diff --git a/.license-overrides.json b/.license-overrides.json
index d7940bc6fd..37385dbaf1 100644
--- a/.license-overrides.json
+++ b/.license-overrides.json
@@ -1,6 +1,6 @@
{
"@fortawesome/free-solid-svg-icons": "License is (CC-BY-4.0 AND MIT) — both are approved open-source licenses, compound AND expression not parsed by checker",
"smalot/pdfparser": "License is LGPL-3.0 — equivalent to LGPL-3.0-only which is on the allowlist, SPDX identifier variation not recognized by checker",
- "apexcharts": "License is MIT — license-checker misreads logo URL as custom license, see https://github.com/apexcharts/apexcharts.js/blob/main/LICENSE",
+ "apexcharts": "NOT MIT. The last MIT release is 5.0.0 -- 5.1.0 onward is the ApexCharts dual-license (Community free only below USD 2M annual revenue; sublicensing under different terms not permitted). This app declares ^7.0.0. Conduction confirmed 2026-08-31 it is below USD 2M, so it qualifies for the Community tier. 🔴 UNRESOLVED: an OEM/Redistribution licence is separately required when embedding ApexCharts in a product used by other people, and is only waived for STATIC charts users cannot interact with -- RegisterDetail.vue and SchemaDetails.vue both set toolbar.show and zoom.enabled, and this app ships to third parties via the Nextcloud App Store. Escalated to the maintainers; do not read this override as a clearance for redistribution.",
"dompdf/dompdf": "License is LGPL-2.1 — equivalent to LGPL-2.1-or-later which is on the allowlist; configured hermetically (isRemoteEnabled=false / isPhpEnabled=false) at the single instantiation site PdfReportWriter:69"
}
diff --git a/appinfo/info.xml b/appinfo/info.xml
index 954c758c8f..3fd175ad83 100644
--- a/appinfo/info.xml
+++ b/appinfo/info.xml
@@ -40,7 +40,7 @@ Open Register drijft apps zoals OpenCatalogi, Procest, Pipelinq en Software Cata
Vrij en open source onder de EUPL-licentie.
]]>
- 2.0.12
+ 2.0.14-unstable.20260901212512
EUPL-1.2
Conduction
OpenRegister
@@ -142,9 +142,11 @@ Vrij en open source onder de EUPL-licentie.
OCA\OpenRegister\BackgroundJob\DsarRetentionSweepJob
OCA\OpenRegister\BackgroundJob\ReportRenderJob
OCA\OpenRegister\BackgroundJob\NotificationQueueFlushJob
+ OCA\OpenRegister\BackgroundJob\TaskScheduledNotificationJob
OCA\OpenRegister\BackgroundJob\ArchivalRetentionTask
OCA\OpenRegister\BackgroundJob\FlowRunWorker
OCA\OpenRegister\BackgroundJob\FlowScheduleWorker
+ OCA\OpenRegister\BackgroundJob\FlowTimerWorker
OCA\OpenRegister\BackgroundJob\HandoffQueueDrainJob
OCA\OpenRegister\BackgroundJob\TemporalCalculationSweepJob
OCA\OpenRegister\BackgroundJob\DsarDpiaDetectionJob
@@ -240,6 +242,42 @@ Vrij en open source onder de EUPL-licentie.
Post-migration, because it needs the flow_* columns the schema
migration adds. -->
OCA\OpenRegister\Repair\RechainAuditTrailForFlowAttribution
+
+ OCA\OpenRegister\Repair\SeedTaskFixtures
+
+ OCA\OpenRegister\Repair\SeedFlowTimerRegister
+ OCA\OpenRegister\Repair\CheckFlowTimerInvariants
+
+ OCA\OpenRegister\Repair\MigrateApprovalChainsToTasks
+ OCA\OpenRegister\Repair\SeedCaseFixtures
+
+ OCA\OpenRegister\Repair\SeedFlowTimerRegister
+ OCA\OpenRegister\Repair\CheckFlowTimerInvariants
OCA\OpenRegister\Repair\ReconcileDeclaredBackgroundJobs
@@ -281,6 +319,7 @@ Vrij en open source onder de EUPL-licentie.
OCA\OpenRegister\Repair\SeedVocabularyRegister
OCA\OpenRegister\Repair\RegisterOpenRegisterWithDoriath
OCA\OpenRegister\Repair\SeedZgwZakenMigrationPack
+ OCA\OpenRegister\Repair\SeedFlowTimerRegister
@@ -295,6 +334,9 @@ Vrij en open source onder de EUPL-licentie.
OCA\OpenRegister\Command\MigrateSchemaApplicationCommand
+
+ OCA\OpenRegister\Command\RollbackApprovalMigrationCommand
OCA\OpenRegister\Command\RechainAuditTrailCommand
OCA\OpenRegister\Command\EncryptFieldCommand
OCA\OpenRegister\Command\DedupeRegistersCommand
+ OCA\OpenRegister\Command\AdoptLeafOrganisationsCommand
+ OCA\OpenRegister\Command\PruneRetiredSchemasCommand
OCA\OpenRegister\Command\RelinkRegisterSchemasCommand
OCA\OpenRegister\Command\ReconcileMagicTablesCommand
OCA\OpenRegister\Command\DedupeConfigurationsCommand
@@ -363,4 +407,14 @@ Vrij en open source onder de EUPL-licentie.
OCA\OpenRegister\Contacts\ContactsMenuProvider
+
+
+
+ OCA\OpenRegister\Dav\TaskVtodoWriteBackPlugin
+
+
diff --git a/appinfo/routes.php b/appinfo/routes.php
index 6f4b5ab5ba..6ecbd7130d 100644
--- a/appinfo/routes.php
+++ b/appinfo/routes.php
@@ -550,6 +550,10 @@
// The VERSION number is `\d+`, not `[^/]+`. Without that,
// `/versions/publish` would match `version` with the literal string
// "publish" and return a 404 for a route that exists.
+ // Adoption: the CALLER becomes the owner of a shipped, ownerless flow.
+ // A deliberate act with its own verb — `owner` is not an editable field
+ // on PUT, so this is the only path from imported to dispatchable.
+ ['name' => 'flow#adopt', 'url' => '/api/flows/{id}/adopt', 'verb' => 'POST', 'requirements' => ['id' => '[^/]+']],
['name' => 'flow#versions', 'url' => '/api/flows/{id}/versions', 'verb' => 'GET', 'requirements' => ['id' => '[^/]+']],
['name' => 'flow#version', 'url' => '/api/flows/{id}/versions/{version}', 'verb' => 'GET', 'requirements' => ['id' => '[^/]+', 'version' => '\d+']],
['name' => 'flow#publish', 'url' => '/api/flows/{id}/publish', 'verb' => 'POST', 'requirements' => ['id' => '[^/]+']],
@@ -1253,16 +1257,6 @@
['name' => 'scheduledWorkflow#update', 'url' => '/api/scheduled-workflows/{id}', 'verb' => 'PUT', 'requirements' => ['id' => '\d+']],
['name' => 'scheduledWorkflow#destroy', 'url' => '/api/scheduled-workflows/{id}', 'verb' => 'DELETE', 'requirements' => ['id' => '\d+']],
- // Approval Chains - multi-step approval definitions and per-object progress.
- ['name' => 'approval#index', 'url' => '/api/approval-chains', 'verb' => 'GET'],
- ['name' => 'approval#show', 'url' => '/api/approval-chains/{id}', 'verb' => 'GET', 'requirements' => ['id' => '\d+']],
- ['name' => 'approval#create', 'url' => '/api/approval-chains', 'verb' => 'POST'],
- ['name' => 'approval#update', 'url' => '/api/approval-chains/{id}', 'verb' => 'PUT', 'requirements' => ['id' => '\d+']],
- ['name' => 'approval#destroy', 'url' => '/api/approval-chains/{id}', 'verb' => 'DELETE', 'requirements' => ['id' => '\d+']],
- ['name' => 'approval#objects', 'url' => '/api/approval-chains/{id}/objects', 'verb' => 'GET', 'requirements' => ['id' => '\d+']],
- ['name' => 'approval#steps', 'url' => '/api/approval-steps', 'verb' => 'GET'],
- ['name' => 'approval#approve', 'url' => '/api/approval-steps/{id}/approve', 'verb' => 'POST', 'requirements' => ['id' => '\d+']],
- ['name' => 'approval#reject', 'url' => '/api/approval-steps/{id}/reject', 'verb' => 'POST', 'requirements' => ['id' => '\d+']],
// MCP Discovery - Tiered API discovery for AI agents.
// CORS preflight (OPTIONS) is handled automatically by the @CORS annotation.
@@ -1338,12 +1332,85 @@
// resolves routes in declaration order, so a later registration would be
// answered by `show('active')` → 404 for every request.
['name' => 'flowRun#active', 'url' => '/api/flow-runs/active', 'verb' => 'GET'],
+ // Finished runs on ONE subject object (flow-runs-subject-scope): the case
+ // page's run history. `subject` is REQUIRED (400 without it) and the read is
+ // organisation-scoped like `active`. Same ordering rule: it MUST stay above
+ // the `{uuid}` route or `show('completed')` answers it with a 404.
+ ['name' => 'flowRun#completedForSubject', 'url' => '/api/flow-runs/completed', 'verb' => 'GET'],
['name' => 'flowRun#show', 'url' => '/api/flow-runs/{uuid}', 'verb' => 'GET', 'requirements' => ['uuid' => '[^/]+']],
['name' => 'flowRun#objects', 'url' => '/api/flow-runs/{uuid}/objects', 'verb' => 'GET', 'requirements' => ['uuid' => '[^/]+']],
['name' => 'flowRun#retry', 'url' => '/api/flow-runs/{uuid}/retry', 'verb' => 'POST', 'requirements' => ['uuid' => '[^/]+']],
['name' => 'flowRun#resume', 'url' => '/api/flow-runs/{uuid}/resume', 'verb' => 'POST', 'requirements' => ['uuid' => '[^/]+']],
+ // Correlation-addressed signal delivery (flow-approval-consolidation):
+ // same authority as resume, addressed by business key instead of run
+ // uuid, fail-closed on zero and on more than one match. Registered on
+ // a literal segment so it can never shadow, or be shadowed by, the
+ // uuid-addressed routes.
+ ['name' => 'flowRun#signalByKey', 'url' => '/api/flow-run-signals/{key}', 'verb' => 'POST', 'requirements' => ['key' => '[^/]+']],
// Interactive test run (or-flow-partial-run): run synchronously with optional startAt + pins + seed.
['name' => 'flowRun#test', 'url' => '/api/flow-runs/test', 'verb' => 'POST'],
+ // The fleet-generic task (flow-task-entity): the inbox and the
+ // lifecycle verbs. Named for the `flow-tasks` CAPABILITY, not for a
+ // flow requirement — a standalone task with run_uuid null is served
+ // here identically. `/api/tasks` itself belongs to the older CalDAV
+ // VTODO leaf (tasks#allUserTasks above), which is a different thing.
+ // Every verb's real authorization is TaskAuthorizationService inside
+ // the service; the route attribute is never the whole check.
+ // The one stable "open this task" address (flow-task-inbox-projections):
+ // the VTODO URL, the notification buttons and the rule actions all
+ // resolve here. It serves the SPA SHELL (history-mode router), and the
+ // SPA's `flow-task-detail` route (src/main.js) renders the task; the bare
+ // `/flow-tasks` inbox list needs no entry of its own because
+ // `dashboard#catchAll` below already shells every non-api sub-path.
+ ['name' => 'task#open', 'url' => '/flow-tasks/{uuid}', 'verb' => 'GET', 'requirements' => ['uuid' => '[^/]+']],
+ ['name' => 'task#index', 'url' => '/api/flow-tasks', 'verb' => 'GET'],
+ ['name' => 'task#create', 'url' => '/api/flow-tasks', 'verb' => 'POST'],
+ ['name' => 'task#show', 'url' => '/api/flow-tasks/{uuid}', 'verb' => 'GET', 'requirements' => ['uuid' => '[^/]+']],
+ ['name' => 'task#audit', 'url' => '/api/flow-tasks/{uuid}/audit', 'verb' => 'GET', 'requirements' => ['uuid' => '[^/]+']],
+ ['name' => 'task#offer', 'url' => '/api/flow-tasks/{uuid}/offer', 'verb' => 'POST', 'requirements' => ['uuid' => '[^/]+']],
+ ['name' => 'task#claim', 'url' => '/api/flow-tasks/{uuid}/claim', 'verb' => 'POST', 'requirements' => ['uuid' => '[^/]+']],
+ ['name' => 'task#unclaim', 'url' => '/api/flow-tasks/{uuid}/unclaim', 'verb' => 'POST', 'requirements' => ['uuid' => '[^/]+']],
+ ['name' => 'task#assign', 'url' => '/api/flow-tasks/{uuid}/assign', 'verb' => 'POST', 'requirements' => ['uuid' => '[^/]+']],
+ ['name' => 'task#reassign', 'url' => '/api/flow-tasks/{uuid}/reassign', 'verb' => 'POST', 'requirements' => ['uuid' => '[^/]+']],
+ ['name' => 'task#delegate', 'url' => '/api/flow-tasks/{uuid}/delegate', 'verb' => 'POST', 'requirements' => ['uuid' => '[^/]+']],
+ ['name' => 'task#resolve', 'url' => '/api/flow-tasks/{uuid}/resolve', 'verb' => 'POST', 'requirements' => ['uuid' => '[^/]+']],
+ ['name' => 'task#complete', 'url' => '/api/flow-tasks/{uuid}/complete', 'verb' => 'POST', 'requirements' => ['uuid' => '[^/]+']],
+ ['name' => 'task#cancel', 'url' => '/api/flow-tasks/{uuid}/cancel', 'verb' => 'POST', 'requirements' => ['uuid' => '[^/]+']],
+ ['name' => 'task#checkItem', 'url' => '/api/flow-tasks/{uuid}/checklist/{itemId}', 'verb' => 'PATCH', 'requirements' => ['uuid' => '[^/]+', 'itemId' => '[^/]+']],
+
+ // The portal seam (flow-portal-task): a party OUTSIDE the instance,
+ // authenticated at portaliq's edge, acts here under a signed
+ // X-Portal-Subject assertion, never a Nextcloud session. The subject
+ // routes are PublicPage by design and authorized inside the service
+ // against the task's STORED party reference. The delivery routes are
+ // the operator's (administrator): portaliq settles what it sent.
+ // `deliveries` is registered before `{uuid}` so the literal wins.
+ ['name' => 'portalTask#index', 'url' => '/api/portal-tasks', 'verb' => 'GET'],
+ ['name' => 'portalTask#deliveries', 'url' => '/api/portal-tasks/deliveries', 'verb' => 'GET'],
+ ['name' => 'portalTask#deliveryDelivered', 'url' => '/api/portal-tasks/deliveries/{uuid}/delivered', 'verb' => 'POST', 'requirements' => ['uuid' => '[^/]+']],
+ ['name' => 'portalTask#deliveryFailed', 'url' => '/api/portal-tasks/deliveries/{uuid}/failed', 'verb' => 'POST', 'requirements' => ['uuid' => '[^/]+']],
+ ['name' => 'portalTask#show', 'url' => '/api/portal-tasks/{uuid}', 'verb' => 'GET', 'requirements' => ['uuid' => '[^/]+']],
+ ['name' => 'portalTask#complete', 'url' => '/api/portal-tasks/{uuid}/complete', 'verb' => 'POST', 'requirements' => ['uuid' => '[^/]+']],
+
+ // The case layer (flow-cmmn-case-semantics): a plan of stages, human
+ // items and milestones anchored to an OpenRegister OBJECT. There is no
+ // case id: every plan route is keyed by the anchoring object's uuid, and
+ // the item verbs by the plan item's uuid. No CMMN XML route exists; the
+ // zaaktype import takes a document that is already in a register.
+ // Every verb's real authorization is CasePlanAuthorizationService
+ // inside the service; the route attribute is never the whole check.
+ // The two literal routes stay ABOVE `{objectUuid}` or they are swallowed.
+ ['name' => 'case#items', 'url' => '/api/cases/items', 'verb' => 'GET'],
+ ['name' => 'case#skeletonFromZaaktype', 'url' => '/api/cases/skeleton-from-zaaktype', 'verb' => 'POST'],
+ ['name' => 'case#transition', 'url' => '/api/cases/items/{uuid}/transition', 'verb' => 'POST', 'requirements' => ['uuid' => '[^/]+']],
+ ['name' => 'case#enable', 'url' => '/api/cases/items/{uuid}/enable', 'verb' => 'POST', 'requirements' => ['uuid' => '[^/]+']],
+ ['name' => 'case#show', 'url' => '/api/cases/{objectUuid}', 'verb' => 'GET', 'requirements' => ['objectUuid' => '[^/]+']],
+ ['name' => 'case#create', 'url' => '/api/cases/{objectUuid}', 'verb' => 'POST', 'requirements' => ['objectUuid' => '[^/]+']],
+ ['name' => 'case#destroy', 'url' => '/api/cases/{objectUuid}', 'verb' => 'DELETE', 'requirements' => ['objectUuid' => '[^/]+']],
+ ['name' => 'case#evaluate', 'url' => '/api/cases/{objectUuid}/evaluate', 'verb' => 'POST', 'requirements' => ['objectUuid' => '[^/]+']],
+ ['name' => 'case#enableable', 'url' => '/api/cases/{objectUuid}/enableable', 'verb' => 'GET', 'requirements' => ['objectUuid' => '[^/]+']],
+ ['name' => 'case#attach', 'url' => '/api/cases/{objectUuid}/items', 'verb' => 'POST', 'requirements' => ['objectUuid' => '[^/]+']],
+ ['name' => 'case#complete', 'url' => '/api/cases/{objectUuid}/complete', 'verb' => 'POST', 'requirements' => ['objectUuid' => '[^/]+']],
// Delegation grants (or-delegation-grants): the consent surface. A grant
// store with no way to answer is a store that only ever says no, so these
// are what make every delegation refusal recoverable.
@@ -1366,5 +1433,24 @@
['name' => 'federatedConfig#publicKey', 'url' => '/api/federated-config/public-key', 'verb' => 'GET'],
['name' => 'federatedConfig#trust', 'url' => '/api/federated-config/trust', 'verb' => 'GET'],
['name' => 'federatedConfig#setTrust', 'url' => '/api/federated-config/trust', 'verb' => 'PUT'],
+
+ // SPA catch-all — MUST stay last so every explicit route above keeps
+ // priority over the /{path} fallback. Without it only `/` served the
+ // shell, so any deep link (/registers, /schemas, a detail route) never
+ // reached the SPA at all — the #133 regression that forced this app back
+ // onto hash routing. Spelled inline rather than via
+ // \OCA\OpenRegister\AppHost\Routes::standard() because this file also
+ // declares a `resources` block the builder does not carry, and because
+ // this IS openregister — guarding a call to its own class would be odd.
+ // ⚠️ `(?!api/)` is load-bearing. Nextcloud's RouteParser processes the
+ // `routes` array BEFORE the `resources` array
+ // (RouteParser::parseDefaultRoutes), and Symfony matches in insertion
+ // order — so even as the LAST entry here this route still registers
+ // ahead of all nine `api/...` resource routes below. Without the
+ // lookahead `.+` (which matches slashes) would swallow
+ // GET /api/registers, /api/schemas and the rest, answering the SPA
+ // shell instead of JSON. The SPA never needs an `api/` path.
+ ['name' => 'dashboard#catchAll', 'url' => '/{path}', 'verb' => 'GET',
+ 'requirements' => ['path' => '(?!api/).+'], 'defaults' => ['path' => '']],
],
];
diff --git a/composer.json b/composer.json
index d1c459351f..fd4058e003 100644
--- a/composer.json
+++ b/composer.json
@@ -159,7 +159,8 @@
"optimize-autoloader": true,
"sort-packages": true,
"platform": {
- "php": "8.3"
+ "php": "8.3",
+ "ext-xsl": "1"
}
},
"extra": {
diff --git a/docs/development/approval-events-migration.md b/docs/development/approval-events-migration.md
new file mode 100644
index 0000000000..49b878ef0f
--- /dev/null
+++ b/docs/development/approval-events-migration.md
@@ -0,0 +1,81 @@
+# Approval events: the replacement mapping
+
+The four `ApprovalStep*Event` classes are removed by
+`flow-approval-consolidation`. No event is re-emitted, aliased or wrapped. A
+consumer that has not migrated stops receiving events at deploy, visibly,
+instead of receiving prompts it can no longer answer.
+
+This page is the normative mapping for consumers. filinq's
+`migrate-signing-to-or-tasks` change migrates against it.
+
+## Per event
+
+### ApprovalStepInitiatedEvent
+
+A step became `pending`. Replacement: a task of the sequence becoming
+`enabled`. Subscribe to the task lifecycle and filter on `sequenceUuid`, or
+read the enabled position through the task inbox.
+
+| Retired field | Replacement |
+|---|---|
+| `chain` | The sequence: `templateId`, `chainKey`, `schemaId` and the frozen `templateSnapshot`. |
+| `step` | The enabled task. Ordinal in `sequencePosition`, role in `candidateGroups[0]`. |
+| `objectUuid` | `task.objectUuid`, also `sequence.anchorObjectUuid`. |
+
+Ordering: the next position is enabled in the same request as the approving
+decision, before that request returns.
+
+### ApprovalStepApprovedEvent
+
+Replacement: a sequence task completing with an approving outcome
+(`TaskTerminalEvent` with `isCommitted() === true`, state `completed`,
+outcome not in the rejecting vocabulary).
+
+| Retired field | Replacement |
+|---|---|
+| `chain` | The sequence, as above. |
+| `step` | The completed task: `completedBy`, `completedAt`, `comment`. |
+| `userId` | `task.completedBy`. The audit entry also carries `onBehalfOf` and `mandate`, which the retired event never had. |
+| `statusOnApprove` | Resolved from the frozen snapshot; carried on `TaskSequenceCompletedEvent` for the final position. Mid-sequence it is readable from the position's `templateSnapshot`. |
+| `nextStep` | The newly enabled task, readable from the sequence after the same request. No replacement carries it inline; named as such. |
+
+### ApprovalStepRejectedEvent
+
+Replacement: a sequence task completing with a rejecting outcome. The
+comment is mandatory and is on `task.comment`.
+
+| Retired field | Replacement |
+|---|---|
+| `chain`, `step`, `userId` | As above. |
+| `statusOnReject` | `sequence.outcome` after the rejection closed the sequence. |
+
+Ordering: the sequence closes and every remaining task is terminated in the
+same request as the rejecting decision.
+
+### ApprovalStepCompletedEvent
+
+Replacement: `TaskSequenceCompletedEvent`, dispatched at exactly the same
+moment: the final position completing with an approving outcome.
+
+| Retired field | Replacement |
+|---|---|
+| `chain` | `event.getSequence()`. |
+| `finalStep` | `event.getFinalTask()`. |
+| `userId` | `event.getDecider()`. |
+| `statusOnApprove` | `event.getStatusOnApprove()`. |
+
+## The reply path
+
+The retired listener contract was a loop: filinq consumed the events and
+called `ApprovalService::approveStep` or `rejectStep` back. The reply path
+is now `TaskService::complete()` with an approving or rejecting outcome, or
+the task routes over HTTP. Deciding an already terminal task is refused with
+a reason naming its terminal state.
+
+## What to do
+
+Register a listener for `TaskTerminalEvent` and `TaskSequenceCompletedEvent`,
+filter on your own sequences, and reply through the task verbs. The
+retirement inventory in
+`tests/fixtures/approval-consolidation/retired-approval-surface.json` lists
+every removed route and class your app must no longer touch.
diff --git a/eslint.config.mjs b/eslint.config.mjs
index 9bad6e2d4b..c7c8ac1e1e 100644
--- a/eslint.config.mjs
+++ b/eslint.config.mjs
@@ -144,11 +144,32 @@ export default [
'no-console': 'off',
'n/no-process-exit': 'off',
'n/hashbang': 'off',
- // `_` / `__` as a deliberate throwaway binding — `catch (_)`, a
- // discarded destructuring slot. Narrow on purpose: the pattern matches
- // UNDERSCORES ONLY, so a real name that happens to start with `_` is
- // still reported. v9 drives plain `.js` through the CORE rule (the
- // `@typescript-eslint` swap is per-file-type), so it is set here.
+ // Tests import devDependencies by definition; this rule is about what
+ // ships in the published package, which tests/ never does.
+ 'n/no-unpublished-import': 'off',
+ },
+ },
+
+ {
+ // `_` / `__` as a deliberate throwaway binding — `catch (_)`, a discarded
+ // destructuring slot. Narrow on purpose: the pattern matches UNDERSCORES
+ // ONLY, so a real name that happens to start with `_` is still reported.
+ //
+ // 🔴 `.js` / `.mjs` ONLY, NOT `.ts`. The CORE rule is not TypeScript-aware:
+ // applied to a `.ts` file it reads the parameter NAMES inside a function
+ // TYPE as bindings and reports them unused. Measured on humaniq —
+ //
+ // t?: (app: string, key: string) => string
+ //
+ // produced four `no-unused-vars` errors for `app` and `key`, which are
+ // documentation, not variables. The same mis-scoping made every unused
+ // `catch (e)` in a `.ts` spec report TWICE, once per rule.
+ //
+ // v9 already turns the core rule off for `.ts` and drives
+ // `@typescript-eslint/no-unused-vars` instead; naming `.ts` here switched
+ // it back on. TypeScript files are handled by the block below.
+ files: ['tests/**/*.js', 'tests/**/*.mjs'],
+ rules: {
'no-unused-vars': [
'error',
{
@@ -165,12 +186,117 @@ export default [
ignoreRestSiblings: true,
},
],
- // Tests import devDependencies by definition; this rule is about what
- // ships in the published package, which tests/ never does.
- 'n/no-unpublished-import': 'off',
},
},
+ {
+ // The TypeScript half of the block above. Same intent, same patterns, on
+ // the rule that actually understands the language: it knows a name inside
+ // a function type is not a binding, so type annotations stay quiet while a
+ // genuinely dead local is still reported.
+ files: ['tests/**/*.ts', 'tests/**/*.tsx'],
+ rules: {
+ '@typescript-eslint/no-unused-vars': [
+ 'error',
+ {
+ varsIgnorePattern: '^_+$',
+ caughtErrors: 'all',
+ caughtErrorsIgnorePattern: '^_+$',
+ argsIgnorePattern: '^_',
+ ignoreRestSiblings: true,
+ },
+ ],
+ },
+ },
+
+ {
+ // 🔴 Node-side CLI tooling under `scripts/`, which is COMMONJS. Flat
+ // config defaults every `.js` to ESM with browser-ish globals, so without
+ // this block eslint reports the CommonJS wrapper itself as undefined
+ // identifiers. Measured on this app: 52 of the 233 errors under
+ // `tests/` + `scripts/` were `no-undef`, ALL of them in `scripts/`, and
+ // all five names were the environment rather than a typo — `process` 23,
+ // `require` 20, `__dirname` 6, `__filename` 2, `module` 1.
+ //
+ // This is describing the environment, not relaxing a rule, and it is the
+ // same argument the test-globals block below makes: declaring them keeps
+ // `no-undef` able to do its real job, which is catching a genuinely
+ // misspelled identifier. Suppressing the rule instead would bury that.
+ //
+ // `no-console` is off because printing its report is what a CLI checker
+ // is FOR.
+ //
+ // 🔴 NO `n/*` ENTRIES HERE, DELIBERATELY. `eslint-plugin-n` is NOT
+ // registered for these files under eslint 10 + @nextcloud/eslint-config
+ // 9, so `'n/no-process-exit': 'off'` would be dead config that reads as
+ // if it were doing something. Measured both ways on this app: 0 `n/`
+ // findings with the entries and 0 without.
+ //
+ // What DID report was the opposite — four `scripts/*.js` carried
+ // `/* eslint-disable n/no-process-exit */` and `/* eslint-disable
+ // n/shebang */` left over from the eslintrc era, and an inline disable
+ // naming an unregistered plugin is itself an error ("Definition for rule
+ // 'n/shebang' was not found"). Those 8 comments are removed; do not add
+ // `n/*` rules back to replace them.
+ //
+ // ⚠️ `.js` and `.cjs` ONLY. A `scripts/*.mjs` is genuinely ESM and must
+ // keep the default `sourceType`, or `import` stops parsing there.
+ files: ['scripts/**/*.js', 'scripts/**/*.cjs'],
+ languageOptions: {
+ sourceType: 'commonjs',
+ globals: {
+ require: 'readonly',
+ module: 'writable',
+ exports: 'writable',
+ process: 'readonly',
+ __dirname: 'readonly',
+ __filename: 'readonly',
+ console: 'readonly',
+ Buffer: 'readonly',
+ global: 'readonly',
+ URL: 'readonly',
+ TextEncoder: 'readonly',
+ TextDecoder: 'readonly',
+ },
+ },
+ rules: {
+ 'no-console': 'off',
+ },
+ },
+
+ {
+ // The ESM half of the block above. A `scripts/*.mjs` is genuinely a module
+ // and must keep the default `sourceType`, so it gets Node's globals but
+ // none of the CommonJS wrapper. Measured: `process` reported undefined 2x
+ // in hermiq's generate-opengemeenten-icons.mjs and 4x in openregister's
+ // l10n/runtime-check.mjs, which the `.js`/`.cjs` block deliberately does
+ // not match.
+ files: ['scripts/**/*.mjs', 'tests/**/*.mjs'],
+ languageOptions: {
+ globals: {
+ process: 'readonly',
+ console: 'readonly',
+ Buffer: 'readonly',
+ global: 'readonly',
+ URL: 'readonly',
+ TextEncoder: 'readonly',
+ TextDecoder: 'readonly',
+ },
+ },
+ rules: {
+ 'no-console': 'off',
+ },
+ },
+
+ {
+ // eslint must not try to PARSE a shell script. `tests/e2e/seed.test.sh`
+ // matches the `**/*.test.*` glob some presets use, and eslint then reads
+ // it as JavaScript and reports "Parsing error: Unexpected character" —
+ // a finding about a file it should never have opened.
+ ignores: ['**/*.sh', '**/*.bash'],
+ },
+
+
{
// Test globals. Several apps keep their spec files INSIDE `src/`, which the
// lint script scans, and neither `@nextcloud/eslint-config` nor the runner
diff --git a/l10n/.schema-l10n-baseline.json b/l10n/.schema-l10n-baseline.json
index 3ed52820fd..4d94ca4b78 100644
--- a/l10n/.schema-l10n-baseline.json
+++ b/l10n/.schema-l10n-baseline.json
@@ -1,3 +1,3 @@
{
- "uncovered": 634
+ "uncovered": 601
}
diff --git a/l10n/be.js b/l10n/be.js
index c6a5ca9768..2932d8cafa 100644
--- a/l10n/be.js
+++ b/l10n/be.js
@@ -3,11 +3,21 @@ OC.L10N.register(
{
"3": "3",
"30": "30",
+ "from amount {amount}": "ад сумы {amount}",
+ "Gated transition: {transition}": "Кантраляваны пераход: {transition}",
+ "Each declared chain provisions an ordered task sequence when its transition is attempted. Approvers decide in their task inbox, not here.": "Кожны абвешчаны ланцужок адкрывае ўпарадкаваную паслядоўнасць задач пры спробе пераходу. Узгадняльнікі вырашаюць у сваёй скрыні задач, а не тут.",
+ "Declare x-openregister-approval-chains on this schema to gate a lifecycle transition on approval.": "Абвясціце x-openregister-approval-chains у гэтай схеме, каб пераход жыццёвага цыкла патрабаваў узгаднення.",
+ "Approval sequences": "Паслядоўнасці ўзгаднення",
"%n entries have no hash yet": "%n запісаў яшчэ не маюць хэша",
"%n entry has no hash yet": "%n запіс яшчэ не мае хэша",
"(Dolphin required)": "(требуется Dolphin)",
+ "No approval chains declared": "Ланцужкі ўзгаднення не абвешчаны",
"(no subject)": "(без темы)",
"(no title)": "(без названия)",
+ "Role {role}": "Роля {role}",
+ "The transition is applied automatically once every step approves.": "Пераход ужываецца аўтаматычна, як толькі кожны крок узгоднены.",
+ "The requester may not decide their own approval.": "Заяўнік не можа вырашаць наконт уласнага ўзгаднення.",
+ "Tier routing on field: {field}": "Ступеньчатая маршрутызацыя па полі: {field}",
"(unnamed)": "(без имени)",
"(untitled card)": "(карточка без названия)",
"({count} selected)": "({count} выбрано)",
@@ -2738,7 +2748,84 @@ OC.L10N.register(
"_Object successfully deleted_::_Objects successfully deleted_": ["Аб'ект паспяхова выдалены","Аб'екты паспяхова выдаленыя","Аб'екты паспяхова выдаленыя","Аб'екты паспяхова выдаленыя"],
"_Purge {count} object from database_::_Purge {count} objects from database_": ["Ачысціць {count} аб'ект з базы даных","Ачысціць {count} аб'екты з базы даных","Ачысціць {count} аб'ектаў з базы даных","Ачысціць {count} аб'екта з базы даных"],
"_Restore {count} object_::_Restore {count} objects_": ["Аднавіць {count} аб'ект","Аднавіць {count} аб'екты","Аднавіць {count} аб'ектаў","Аднавіць {count} аб'екта"],
- "_Successfully restored {count} object_::_Successfully restored {count} objects_": ["Паспяхова адноўлены {count} аб'ект","Паспяхова адноўленыя {count} аб'екты","Паспяхова адноўлена {count} аб'ектаў","Паспяхова адноўлена {count} аб'екта"]
+ "_Successfully restored {count} object_::_Successfully restored {count} objects_": ["Паспяхова адноўлены {count} аб'ект","Паспяхова адноўленыя {count} аб'екты","Паспяхова адноўлена {count} аб'ектаў","Паспяхова адноўлена {count} аб'екта"],
+ "A message identity the notification subsystem resolves.": "Ідэнтычнасць паведамлення, якую вырашае сістэма апавяшчэнняў.",
+ "Computed non-working-date rules. kind fixed: {month, day, name, observedShift?: {whenWeekday, days}}. kind easter: {offset, name}, offset in days from Easter Sunday. kind observedShift: a fixed date with a required shift.": "Вылічаныя правілы непрацоўных дзён. Від fixed: {month, day, name, observedShift?: {whenWeekday, days}}. Від easter: {offset, name}, зрух у днях ад Вялікоднай нядзелі. Від observedShift: нязменная дата з абавязковым пераносам.",
+ "Date": "Дата",
+ "Day": "Дзень",
+ "Day of a fixed or observedShift rule; ignored by an easter rule.": "Дзень правіла fixed або observedShift; правіла easter яго ігнаруе.",
+ "Days": "Дні",
+ "Days from Easter Sunday for an easter rule; ignored by the other kinds.": "Дні ад Вялікоднай нядзелі для правіла easter; іншыя віды іх ігнаруюць.",
+ "Distance from the deadline, in the offset unit.": "Адлегласць да тэрміну ў адзінцы зруху.",
+ "Enumerated one-off closures as {date, name}. Allowed alongside rules; refused as the whole calendar.": "Асобныя закрыцці, пералічаныя як {date, name}. Дазволеныя побач з правіламі; адхіленыя як увесь каляндар.",
+ "Escalate to roles": "Ролі для эскалацыі",
+ "Escalation ladder": "Лесвіца эскалацыі",
+ "Exception dates": "Выключныя даты",
+ "Hours per working day": "Гадзін на працоўны дзень",
+ "How many days the observed date shifts, e.g. -1 for the Saturday before.": "На колькі дзён пераносіцца святочная дата, напр. -1 для папярэдняй суботы.",
+ "Human-readable title.": "Чытэльная назва.",
+ "ISO weekdays (1 = Monday, 7 = Sunday) that are working days.": "ISO дні тыдня (1 = панядзелак, 7 = нядзеля), якія з'яўляюцца працоўнымі.",
+ "Kind": "Від",
+ "Message": "Паведамленне",
+ "Month": "Месяц",
+ "Month of a fixed or observedShift rule; ignored by an easter rule.": "Месяц правіла fixed або observedShift; правіла easter яго ігнаруе.",
+ "Non-working-date rules": "Правілы непрацоўных дзён",
+ "Notify roles": "Ролі для апавяшчэння",
+ "Observed shift": "Перанос свята",
+ "Offset": "Зрух",
+ "Offset unit": "Адзінка зруху",
+ "Open incident": "Адкрыць інцыдэнт",
+ "Optional map from a role name to a concrete recipient descriptor, e.g. {\"teamleader\": \"group:teamleaders\"}. Roles without a binding travel unresolved as role:.": "Неабавязковая мапа з назвы ролі на канкрэтнага атрымальніка, напр. {\"teamleader\": \"group:teamleaders\"}. Ролі без прывязкі рухаюцца нявырашанымі як role:.",
+ "Optional on a fixed rule, required on observedShift: {whenWeekday: weekday name or ISO 1..7, days: integer}.": "Неабавязкова для правіла fixed, абавязкова для observedShift: {whenWeekday: назва дня або ISO 1..7, days: цэлы лік}.",
+ "Ordered rungs: {key, trigger (preBreach|slaBreached), offset, offsetUnit (hours|businessDays|calendarDays), notifyRole[], escalateToRole[], priority, message, openIncident}.": "Упарадкаваныя прыступкі: {key, trigger (preBreach|slaBreached), offset, offsetUnit (hours|businessDays|calendarDays), notifyRole[], escalateToRole[], priority, message, openIncident}.",
+ "Priority": "Прыярытэт",
+ "Role bindings": "Прывязкі роляў",
+ "Roles the matter is escalated to at this rung.": "Ролі, да якіх справа эскалюецца на гэтай прыступцы.",
+ "Roles told at this rung; handler is the subject's own performer.": "Ролі, якія апавяшчаюцца на гэтай прыступцы; handler — асоба, якая вядзе справу.",
+ "Rungs": "Прыступкі",
+ "Stable rung identity, e.g. preBreach:14:calendarDays; derived from trigger, offset and unit when absent.": "Сталая ідэнтычнасць прыступкі, напр. preBreach:14:calendarDays; калі адсутнічае, выводзіцца з трыгера, зруху і адзінкі.",
+ "The calendar's stable name, referenced by a timer's calendar_slug.": "Сталая назва календара, на якую таймер спасылаецца праз calendar_slug.",
+ "The closed date, Y-m-d.": "Дата закрыцця, Y-m-d.",
+ "The holiday's name.": "Назва свята.",
+ "The ladder's stable name, referenced by a timer's ladder_slug.": "Сталая назва лесвіцы, на якую таймер спасылаецца праз ladder_slug.",
+ "The unit of the offset: the same set the SLA accepts.": "Адзінка зруху: той самы набор, які прымае SLA.",
+ "The urgency the raised transition carries.": "Тэрміновасць, якую нясе выкліканы пераход.",
+ "The weekday (name) on which the date shifts, e.g. sunday for Koningsdag.": "Дзень тыдня (назва), пры якім дата пераносіцца, напр. sunday для Koningsdag.",
+ "UUID of the organisation this calendar is configured for. Empty for a shared calendar. The resolution order picks an organisation's calendar when the timer names none.": "UUID арганізацыі, для якой наладжаны гэты каляндар. Пуста для агульнага календара. Калі таймер нічога не называе, парадак вырашэння выбірае каляндар арганізацыі.",
+ "UUID of the organisation this ladder is the default for. Empty for the shared default.": "UUID арганізацыі, для якой гэтая лесвіца прадвызначаная. Пуста для агульнай прадвызначанай.",
+ "When weekday": "Калі прыпадае на",
+ "Whether reaching this rung opens an incident.": "Ці адкрывае дасягненне гэтай прыступкі інцыдэнт.",
+ "Why the day is closed.": "Чаму гэты дзень зачынены.",
+ "Working calendar": "Працоўны каляндар",
+ "Working hours in one working day. Makes hours and businessDays commensurable.": "Працоўныя гадзіны ў адным працоўным дні. Робіць гадзіны і працоўныя дні супастаўнымі.",
+ "Working weekdays": "Працоўныя дні тыдня",
+ "fixed: a month/day; easter: an offset in days from Easter Sunday; observedShift: a month/day with a required observed shift.": "fixed: месяц і дзень; easter: зрух у днях ад Вялікоднай нядзелі; observedShift: месяц і дзень з абавязковым пераносам.",
+ "preBreach fires before the deadline, slaBreached at or after it.": "preBreach спрацоўвае да тэрміну, slaBreached у тэрмін або пасля.",
+ "No such task": "Няма такой задачы",
+ "The task does not exist, or it is not yours to see.": "Задача не існуе, або вы не маеце права яе бачыць.",
+ "Details": "Падрабязнасці",
+ "Due": "Тэрмін",
+ "Assignee": "Выканаўца",
+ "Requested by": "Запытаў",
+ "Outcome": "Вынік",
+ "Ready to claim": "Гатова да ўзяцця",
+ "In progress": "Выконваецца",
+ "Terminated": "Спынена",
+ "Normal": "Звычайны",
+ "Urgent": "Тэрміновы",
+ "Overdue by 1 day": "Пратэрмінавана на 1 дзень",
+ "Overdue by {days} days": "Пратэрмінавана на {days} дз.",
+ "Due today": "Тэрмін сёння",
+ "Due tomorrow": "Тэрмін заўтра",
+ "Due in {days} days": "Тэрмін праз {days} дз.",
+ "Tasks": "Задачы",
+ "Task": "Задача",
+ "Unassigned, open for claiming": "Не прызначана, адкрыта для ўзяцця",
+ "Claim": "Узяць",
+ "Complete": "Завяршыць",
+ "Complete: {outcome}": "Завяршыць: {outcome}",
+ "Could not load the task": "Не ўдалося загрузіць задачу",
+ "The task refused that action": "Задача адхіліла гэта дзеянне"
},
"nplurals=4; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<12 || n%100>14) ? 1 : n%10==0 || (n%10>=5 && n%10<=9) || (n%100>=11 && n%100<=14)? 2 : 3);"
)
diff --git a/l10n/be.json b/l10n/be.json
index e787ba27bf..a66e870a97 100644
--- a/l10n/be.json
+++ b/l10n/be.json
@@ -1,10 +1,20 @@
{
"translations": {
+ "from amount {amount}": "ад сумы {amount}",
+ "Gated transition: {transition}": "Кантраляваны пераход: {transition}",
+ "Each declared chain provisions an ordered task sequence when its transition is attempted. Approvers decide in their task inbox, not here.": "Кожны абвешчаны ланцужок адкрывае ўпарадкаваную паслядоўнасць задач пры спробе пераходу. Узгадняльнікі вырашаюць у сваёй скрыні задач, а не тут.",
+ "Declare x-openregister-approval-chains on this schema to gate a lifecycle transition on approval.": "Абвясціце x-openregister-approval-chains у гэтай схеме, каб пераход жыццёвага цыкла патрабаваў узгаднення.",
+ "Approval sequences": "Паслядоўнасці ўзгаднення",
"%n entries have no hash yet": "%n запісаў яшчэ не маюць хэша",
"%n entry has no hash yet": "%n запіс яшчэ не мае хэша",
"(Dolphin required)": "(требуется Dolphin)",
+ "No approval chains declared": "Ланцужкі ўзгаднення не абвешчаны",
"(no subject)": "(без темы)",
"(no title)": "(без названия)",
+ "Role {role}": "Роля {role}",
+ "The transition is applied automatically once every step approves.": "Пераход ужываецца аўтаматычна, як толькі кожны крок узгоднены.",
+ "The requester may not decide their own approval.": "Заяўнік не можа вырашаць наконт уласнага ўзгаднення.",
+ "Tier routing on field: {field}": "Ступеньчатая маршрутызацыя па полі: {field}",
"(unnamed)": "(без имени)",
"(untitled card)": "(карточка без названия)",
"({count} selected)": "({count} выбрано)",
@@ -2817,7 +2827,84 @@
"Паспяхова адноўленыя {count} аб'екты",
"Паспяхова адноўлена {count} аб'ектаў",
"Паспяхова адноўлена {count} аб'екта"
- ]
+ ],
+ "A message identity the notification subsystem resolves.": "Ідэнтычнасць паведамлення, якую вырашае сістэма апавяшчэнняў.",
+ "Computed non-working-date rules. kind fixed: {month, day, name, observedShift?: {whenWeekday, days}}. kind easter: {offset, name}, offset in days from Easter Sunday. kind observedShift: a fixed date with a required shift.": "Вылічаныя правілы непрацоўных дзён. Від fixed: {month, day, name, observedShift?: {whenWeekday, days}}. Від easter: {offset, name}, зрух у днях ад Вялікоднай нядзелі. Від observedShift: нязменная дата з абавязковым пераносам.",
+ "Date": "Дата",
+ "Day": "Дзень",
+ "Day of a fixed or observedShift rule; ignored by an easter rule.": "Дзень правіла fixed або observedShift; правіла easter яго ігнаруе.",
+ "Days": "Дні",
+ "Days from Easter Sunday for an easter rule; ignored by the other kinds.": "Дні ад Вялікоднай нядзелі для правіла easter; іншыя віды іх ігнаруюць.",
+ "Distance from the deadline, in the offset unit.": "Адлегласць да тэрміну ў адзінцы зруху.",
+ "Enumerated one-off closures as {date, name}. Allowed alongside rules; refused as the whole calendar.": "Асобныя закрыцці, пералічаныя як {date, name}. Дазволеныя побач з правіламі; адхіленыя як увесь каляндар.",
+ "Escalate to roles": "Ролі для эскалацыі",
+ "Escalation ladder": "Лесвіца эскалацыі",
+ "Exception dates": "Выключныя даты",
+ "Hours per working day": "Гадзін на працоўны дзень",
+ "How many days the observed date shifts, e.g. -1 for the Saturday before.": "На колькі дзён пераносіцца святочная дата, напр. -1 для папярэдняй суботы.",
+ "Human-readable title.": "Чытэльная назва.",
+ "ISO weekdays (1 = Monday, 7 = Sunday) that are working days.": "ISO дні тыдня (1 = панядзелак, 7 = нядзеля), якія з'яўляюцца працоўнымі.",
+ "Kind": "Від",
+ "Message": "Паведамленне",
+ "Month": "Месяц",
+ "Month of a fixed or observedShift rule; ignored by an easter rule.": "Месяц правіла fixed або observedShift; правіла easter яго ігнаруе.",
+ "Non-working-date rules": "Правілы непрацоўных дзён",
+ "Notify roles": "Ролі для апавяшчэння",
+ "Observed shift": "Перанос свята",
+ "Offset": "Зрух",
+ "Offset unit": "Адзінка зруху",
+ "Open incident": "Адкрыць інцыдэнт",
+ "Optional map from a role name to a concrete recipient descriptor, e.g. {\"teamleader\": \"group:teamleaders\"}. Roles without a binding travel unresolved as role:.": "Неабавязковая мапа з назвы ролі на канкрэтнага атрымальніка, напр. {\"teamleader\": \"group:teamleaders\"}. Ролі без прывязкі рухаюцца нявырашанымі як role:.",
+ "Optional on a fixed rule, required on observedShift: {whenWeekday: weekday name or ISO 1..7, days: integer}.": "Неабавязкова для правіла fixed, абавязкова для observedShift: {whenWeekday: назва дня або ISO 1..7, days: цэлы лік}.",
+ "Ordered rungs: {key, trigger (preBreach|slaBreached), offset, offsetUnit (hours|businessDays|calendarDays), notifyRole[], escalateToRole[], priority, message, openIncident}.": "Упарадкаваныя прыступкі: {key, trigger (preBreach|slaBreached), offset, offsetUnit (hours|businessDays|calendarDays), notifyRole[], escalateToRole[], priority, message, openIncident}.",
+ "Priority": "Прыярытэт",
+ "Role bindings": "Прывязкі роляў",
+ "Roles the matter is escalated to at this rung.": "Ролі, да якіх справа эскалюецца на гэтай прыступцы.",
+ "Roles told at this rung; handler is the subject's own performer.": "Ролі, якія апавяшчаюцца на гэтай прыступцы; handler — асоба, якая вядзе справу.",
+ "Rungs": "Прыступкі",
+ "Stable rung identity, e.g. preBreach:14:calendarDays; derived from trigger, offset and unit when absent.": "Сталая ідэнтычнасць прыступкі, напр. preBreach:14:calendarDays; калі адсутнічае, выводзіцца з трыгера, зруху і адзінкі.",
+ "The calendar's stable name, referenced by a timer's calendar_slug.": "Сталая назва календара, на якую таймер спасылаецца праз calendar_slug.",
+ "The closed date, Y-m-d.": "Дата закрыцця, Y-m-d.",
+ "The holiday's name.": "Назва свята.",
+ "The ladder's stable name, referenced by a timer's ladder_slug.": "Сталая назва лесвіцы, на якую таймер спасылаецца праз ladder_slug.",
+ "The unit of the offset: the same set the SLA accepts.": "Адзінка зруху: той самы набор, які прымае SLA.",
+ "The urgency the raised transition carries.": "Тэрміновасць, якую нясе выкліканы пераход.",
+ "The weekday (name) on which the date shifts, e.g. sunday for Koningsdag.": "Дзень тыдня (назва), пры якім дата пераносіцца, напр. sunday для Koningsdag.",
+ "UUID of the organisation this calendar is configured for. Empty for a shared calendar. The resolution order picks an organisation's calendar when the timer names none.": "UUID арганізацыі, для якой наладжаны гэты каляндар. Пуста для агульнага календара. Калі таймер нічога не называе, парадак вырашэння выбірае каляндар арганізацыі.",
+ "UUID of the organisation this ladder is the default for. Empty for the shared default.": "UUID арганізацыі, для якой гэтая лесвіца прадвызначаная. Пуста для агульнай прадвызначанай.",
+ "When weekday": "Калі прыпадае на",
+ "Whether reaching this rung opens an incident.": "Ці адкрывае дасягненне гэтай прыступкі інцыдэнт.",
+ "Why the day is closed.": "Чаму гэты дзень зачынены.",
+ "Working calendar": "Працоўны каляндар",
+ "Working hours in one working day. Makes hours and businessDays commensurable.": "Працоўныя гадзіны ў адным працоўным дні. Робіць гадзіны і працоўныя дні супастаўнымі.",
+ "Working weekdays": "Працоўныя дні тыдня",
+ "fixed: a month/day; easter: an offset in days from Easter Sunday; observedShift: a month/day with a required observed shift.": "fixed: месяц і дзень; easter: зрух у днях ад Вялікоднай нядзелі; observedShift: месяц і дзень з абавязковым пераносам.",
+ "preBreach fires before the deadline, slaBreached at or after it.": "preBreach спрацоўвае да тэрміну, slaBreached у тэрмін або пасля.",
+ "No such task": "Няма такой задачы",
+ "The task does not exist, or it is not yours to see.": "Задача не існуе, або вы не маеце права яе бачыць.",
+ "Details": "Падрабязнасці",
+ "Due": "Тэрмін",
+ "Assignee": "Выканаўца",
+ "Requested by": "Запытаў",
+ "Outcome": "Вынік",
+ "Ready to claim": "Гатова да ўзяцця",
+ "In progress": "Выконваецца",
+ "Terminated": "Спынена",
+ "Normal": "Звычайны",
+ "Urgent": "Тэрміновы",
+ "Overdue by 1 day": "Пратэрмінавана на 1 дзень",
+ "Overdue by {days} days": "Пратэрмінавана на {days} дз.",
+ "Due today": "Тэрмін сёння",
+ "Due tomorrow": "Тэрмін заўтра",
+ "Due in {days} days": "Тэрмін праз {days} дз.",
+ "Tasks": "Задачы",
+ "Task": "Задача",
+ "Unassigned, open for claiming": "Не прызначана, адкрыта для ўзяцця",
+ "Claim": "Узяць",
+ "Complete": "Завяршыць",
+ "Complete: {outcome}": "Завяршыць: {outcome}",
+ "Could not load the task": "Не ўдалося загрузіць задачу",
+ "The task refused that action": "Задача адхіліла гэта дзеянне"
},
"pluralForm": "nplurals=4; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<12 || n%100>14) ? 1 : n%10==0 || (n%10>=5 && n%10<=9) || (n%100>=11 && n%100<=14)? 2 : 3);",
"plurals": {
diff --git a/l10n/bg.js b/l10n/bg.js
index de17cf774e..90d2507edf 100644
--- a/l10n/bg.js
+++ b/l10n/bg.js
@@ -3,11 +3,21 @@ OC.L10N.register(
{
"3": "3",
"30": "30",
+ "from amount {amount}": "от сума {amount}",
+ "Gated transition: {transition}": "Контролиран преход: {transition}",
+ "Each declared chain provisions an ordered task sequence when its transition is attempted. Approvers decide in their task inbox, not here.": "Всяка декларирана верига отваря подредена последователност от задачи при опит за прехода. Одобряващите решават в своята кутия със задачи, не тук.",
+ "Declare x-openregister-approval-chains on this schema to gate a lifecycle transition on approval.": "Декларирайте x-openregister-approval-chains в тази схема, за да поставите преход от жизнения цикъл зад одобрение.",
+ "Approval sequences": "Последователности за одобрение",
"%n entries have no hash yet": "%n записа все още нямат хеш",
"%n entry has no hash yet": "%n запис все още няма хеш",
"(Dolphin required)": "(изисква се Dolphin)",
+ "No approval chains declared": "Няма декларирани вериги за одобрение",
"(no subject)": "(без тема)",
"(no title)": "(без заглавие)",
+ "Role {role}": "Роля {role}",
+ "The transition is applied automatically once every step approves.": "Преходът се прилага автоматично, щом всяка стъпка бъде одобрена.",
+ "The requester may not decide their own approval.": "Заявителят не може да решава за собственото си одобрение.",
+ "Tier routing on field: {field}": "Маршрутизиране по нива по полето: {field}",
"(unnamed)": "(без име)",
"(untitled card)": "(карта без заглавие)",
"({count} selected)": "({count} избрани)",
@@ -2738,7 +2748,84 @@ OC.L10N.register(
"_Object successfully deleted_::_Objects successfully deleted_": ["Обектът е изтрит успешно","Обектите са изтрити успешно"],
"_Purge {count} object from database_::_Purge {count} objects from database_": ["Изчистване на {count} обект от базата данни","Изчистване на {count} обекта от базата данни"],
"_Restore {count} object_::_Restore {count} objects_": ["Възстановяване на {count} обект","Възстановяване на {count} обекта"],
- "_Successfully restored {count} object_::_Successfully restored {count} objects_": ["Успешно възстановен {count} обект","Успешно възстановени {count} обекта"]
+ "_Successfully restored {count} object_::_Successfully restored {count} objects_": ["Успешно възстановен {count} обект","Успешно възстановени {count} обекта"],
+ "A message identity the notification subsystem resolves.": "Идентичност на съобщение, която системата за известия разрешава.",
+ "Computed non-working-date rules. kind fixed: {month, day, name, observedShift?: {whenWeekday, days}}. kind easter: {offset, name}, offset in days from Easter Sunday. kind observedShift: a fixed date with a required shift.": "Изчислени правила за неработните дни. Вид fixed: {month, day, name, observedShift?: {whenWeekday, days}}. Вид easter: {offset, name}, отместване в дни от Великденската неделя. Вид observedShift: фиксирана дата със задължително преместване.",
+ "Date": "Дата",
+ "Day": "Ден",
+ "Day of a fixed or observedShift rule; ignored by an easter rule.": "Ден на правило fixed или observedShift; правило easter го пренебрегва.",
+ "Days": "Дни",
+ "Days from Easter Sunday for an easter rule; ignored by the other kinds.": "Дни от Великденската неделя за правило easter; другите видове ги пренебрегват.",
+ "Distance from the deadline, in the offset unit.": "Разстояние до срока в единицата на отместването.",
+ "Enumerated one-off closures as {date, name}. Allowed alongside rules; refused as the whole calendar.": "Единични затваряния, изброени като {date, name}. Позволени редом с правила; отказани като целия календар.",
+ "Escalate to roles": "Роли за ескалация",
+ "Escalation ladder": "Стълба на ескалация",
+ "Exception dates": "Изключителни дати",
+ "Hours per working day": "Часове на работен ден",
+ "How many days the observed date shifts, e.g. -1 for the Saturday before.": "С колко дни се премества честваната дата, напр. -1 за предишната събота.",
+ "Human-readable title.": "Четимо заглавие.",
+ "ISO weekdays (1 = Monday, 7 = Sunday) that are working days.": "ISO дни от седмицата (1 = понеделник, 7 = неделя), които са работни.",
+ "Kind": "Вид",
+ "Message": "Съобщение",
+ "Month": "Месец",
+ "Month of a fixed or observedShift rule; ignored by an easter rule.": "Месец на правило fixed или observedShift; правило easter го пренебрегва.",
+ "Non-working-date rules": "Правила за неработните дни",
+ "Notify roles": "Роли за уведомяване",
+ "Observed shift": "Преместване на празника",
+ "Offset": "Отместване",
+ "Offset unit": "Единица на отместването",
+ "Open incident": "Отваряне на инцидент",
+ "Optional map from a role name to a concrete recipient descriptor, e.g. {\"teamleader\": \"group:teamleaders\"}. Roles without a binding travel unresolved as role:.": "Незадължителна карта от име на роля към конкретен получател, напр. {\"teamleader\": \"group:teamleaders\"}. Роли без обвързване пътуват неразрешени като role:.",
+ "Optional on a fixed rule, required on observedShift: {whenWeekday: weekday name or ISO 1..7, days: integer}.": "Незадължително при правило fixed, задължително при observedShift: {whenWeekday: име на ден или ISO 1..7, days: цяло число}.",
+ "Ordered rungs: {key, trigger (preBreach|slaBreached), offset, offsetUnit (hours|businessDays|calendarDays), notifyRole[], escalateToRole[], priority, message, openIncident}.": "Подредени стъпала: {key, trigger (preBreach|slaBreached), offset, offsetUnit (hours|businessDays|calendarDays), notifyRole[], escalateToRole[], priority, message, openIncident}.",
+ "Priority": "Приоритет",
+ "Role bindings": "Обвързвания на роли",
+ "Roles the matter is escalated to at this rung.": "Роли, към които преписката се ескалира на това стъпало.",
+ "Roles told at this rung; handler is the subject's own performer.": "Роли, уведомявани на това стъпало; handler е лицето, което обработва преписката.",
+ "Rungs": "Стъпала",
+ "Stable rung identity, e.g. preBreach:14:calendarDays; derived from trigger, offset and unit when absent.": "Постоянна идентичност на стъпалото, напр. preBreach:14:calendarDays; при липса се извежда от спусъка, отместването и единицата.",
+ "The calendar's stable name, referenced by a timer's calendar_slug.": "Постоянното име на календара, посочвано от calendar_slug на таймер.",
+ "The closed date, Y-m-d.": "Датата на затваряне, Y-m-d.",
+ "The holiday's name.": "Името на празника.",
+ "The ladder's stable name, referenced by a timer's ladder_slug.": "Постоянното име на стълбата, посочвано от ladder_slug на таймер.",
+ "The unit of the offset: the same set the SLA accepts.": "Единицата на отместването: същият набор, който SLA приема.",
+ "The urgency the raised transition carries.": "Спешността, която носи задействаният преход.",
+ "The weekday (name) on which the date shifts, e.g. sunday for Koningsdag.": "Денят от седмицата (име), при който датата се премества, напр. sunday за Koningsdag.",
+ "UUID of the organisation this calendar is configured for. Empty for a shared calendar. The resolution order picks an organisation's calendar when the timer names none.": "UUID на организацията, за която е настроен този календар. Празно при споделен календар. Ако таймерът не посочи никакъв, редът на разрешаване избира календара на организацията.",
+ "UUID of the organisation this ladder is the default for. Empty for the shared default.": "UUID на организацията, за която тази стълба е подразбираща се. Празно при споделената подразбираща се.",
+ "When weekday": "Ако се пада в",
+ "Whether reaching this rung opens an incident.": "Дали достигането на това стъпало отваря инцидент.",
+ "Why the day is closed.": "Защо денят е затворен.",
+ "Working calendar": "Работен календар",
+ "Working hours in one working day. Makes hours and businessDays commensurable.": "Работни часове в един работен ден. Прави часовете и работните дни съизмерими.",
+ "Working weekdays": "Работни дни от седмицата",
+ "fixed: a month/day; easter: an offset in days from Easter Sunday; observedShift: a month/day with a required observed shift.": "fixed: месец и ден; easter: отместване в дни от Великденската неделя; observedShift: месец и ден със задължително преместване.",
+ "preBreach fires before the deadline, slaBreached at or after it.": "preBreach се задейства преди срока, slaBreached на срока или след него.",
+ "No such task": "Няма такава задача",
+ "The task does not exist, or it is not yours to see.": "Задачата не съществува или нямате право да я видите.",
+ "Details": "Детайли",
+ "Due": "Срок",
+ "Assignee": "Изпълнител",
+ "Requested by": "Заявено от",
+ "Outcome": "Резултат",
+ "Ready to claim": "Готово за поемане",
+ "In progress": "В процес",
+ "Terminated": "Прекратена",
+ "Normal": "Нормален",
+ "Urgent": "Спешен",
+ "Overdue by 1 day": "Просрочена с 1 ден",
+ "Overdue by {days} days": "Просрочена с {days} дни",
+ "Due today": "Срок днес",
+ "Due tomorrow": "Срок утре",
+ "Due in {days} days": "Срок след {days} дни",
+ "Tasks": "Задачи",
+ "Task": "Задача",
+ "Unassigned, open for claiming": "Неразпределена, отворена за поемане",
+ "Claim": "Поемане",
+ "Complete": "Завършване",
+ "Complete: {outcome}": "Завършване: {outcome}",
+ "Could not load the task": "Задачата не можа да се зареди",
+ "The task refused that action": "Задачата отказа това действие"
},
"nplurals=2; plural=(n != 1);"
)
diff --git a/l10n/bg.json b/l10n/bg.json
index b248b7bffd..3acc83ee63 100644
--- a/l10n/bg.json
+++ b/l10n/bg.json
@@ -1,10 +1,20 @@
{
"translations": {
+ "from amount {amount}": "от сума {amount}",
+ "Gated transition: {transition}": "Контролиран преход: {transition}",
+ "Each declared chain provisions an ordered task sequence when its transition is attempted. Approvers decide in their task inbox, not here.": "Всяка декларирана верига отваря подредена последователност от задачи при опит за прехода. Одобряващите решават в своята кутия със задачи, не тук.",
+ "Declare x-openregister-approval-chains on this schema to gate a lifecycle transition on approval.": "Декларирайте x-openregister-approval-chains в тази схема, за да поставите преход от жизнения цикъл зад одобрение.",
+ "Approval sequences": "Последователности за одобрение",
"%n entries have no hash yet": "%n записа все още нямат хеш",
"%n entry has no hash yet": "%n запис все още няма хеш",
"(Dolphin required)": "(изисква се Dolphin)",
+ "No approval chains declared": "Няма декларирани вериги за одобрение",
"(no subject)": "(без тема)",
"(no title)": "(без заглавие)",
+ "Role {role}": "Роля {role}",
+ "The transition is applied automatically once every step approves.": "Преходът се прилага автоматично, щом всяка стъпка бъде одобрена.",
+ "The requester may not decide their own approval.": "Заявителят не може да решава за собственото си одобрение.",
+ "Tier routing on field: {field}": "Маршрутизиране по нива по полето: {field}",
"(unnamed)": "(без име)",
"(untitled card)": "(карта без заглавие)",
"({count} selected)": "({count} избрани)",
@@ -2785,7 +2795,84 @@
"_Successfully restored {count} object_::_Successfully restored {count} objects_": [
"Успешно възстановен {count} обект",
"Успешно възстановени {count} обекта"
- ]
+ ],
+ "A message identity the notification subsystem resolves.": "Идентичност на съобщение, която системата за известия разрешава.",
+ "Computed non-working-date rules. kind fixed: {month, day, name, observedShift?: {whenWeekday, days}}. kind easter: {offset, name}, offset in days from Easter Sunday. kind observedShift: a fixed date with a required shift.": "Изчислени правила за неработните дни. Вид fixed: {month, day, name, observedShift?: {whenWeekday, days}}. Вид easter: {offset, name}, отместване в дни от Великденската неделя. Вид observedShift: фиксирана дата със задължително преместване.",
+ "Date": "Дата",
+ "Day": "Ден",
+ "Day of a fixed or observedShift rule; ignored by an easter rule.": "Ден на правило fixed или observedShift; правило easter го пренебрегва.",
+ "Days": "Дни",
+ "Days from Easter Sunday for an easter rule; ignored by the other kinds.": "Дни от Великденската неделя за правило easter; другите видове ги пренебрегват.",
+ "Distance from the deadline, in the offset unit.": "Разстояние до срока в единицата на отместването.",
+ "Enumerated one-off closures as {date, name}. Allowed alongside rules; refused as the whole calendar.": "Единични затваряния, изброени като {date, name}. Позволени редом с правила; отказани като целия календар.",
+ "Escalate to roles": "Роли за ескалация",
+ "Escalation ladder": "Стълба на ескалация",
+ "Exception dates": "Изключителни дати",
+ "Hours per working day": "Часове на работен ден",
+ "How many days the observed date shifts, e.g. -1 for the Saturday before.": "С колко дни се премества честваната дата, напр. -1 за предишната събота.",
+ "Human-readable title.": "Четимо заглавие.",
+ "ISO weekdays (1 = Monday, 7 = Sunday) that are working days.": "ISO дни от седмицата (1 = понеделник, 7 = неделя), които са работни.",
+ "Kind": "Вид",
+ "Message": "Съобщение",
+ "Month": "Месец",
+ "Month of a fixed or observedShift rule; ignored by an easter rule.": "Месец на правило fixed или observedShift; правило easter го пренебрегва.",
+ "Non-working-date rules": "Правила за неработните дни",
+ "Notify roles": "Роли за уведомяване",
+ "Observed shift": "Преместване на празника",
+ "Offset": "Отместване",
+ "Offset unit": "Единица на отместването",
+ "Open incident": "Отваряне на инцидент",
+ "Optional map from a role name to a concrete recipient descriptor, e.g. {\"teamleader\": \"group:teamleaders\"}. Roles without a binding travel unresolved as role:.": "Незадължителна карта от име на роля към конкретен получател, напр. {\"teamleader\": \"group:teamleaders\"}. Роли без обвързване пътуват неразрешени като role:.",
+ "Optional on a fixed rule, required on observedShift: {whenWeekday: weekday name or ISO 1..7, days: integer}.": "Незадължително при правило fixed, задължително при observedShift: {whenWeekday: име на ден или ISO 1..7, days: цяло число}.",
+ "Ordered rungs: {key, trigger (preBreach|slaBreached), offset, offsetUnit (hours|businessDays|calendarDays), notifyRole[], escalateToRole[], priority, message, openIncident}.": "Подредени стъпала: {key, trigger (preBreach|slaBreached), offset, offsetUnit (hours|businessDays|calendarDays), notifyRole[], escalateToRole[], priority, message, openIncident}.",
+ "Priority": "Приоритет",
+ "Role bindings": "Обвързвания на роли",
+ "Roles the matter is escalated to at this rung.": "Роли, към които преписката се ескалира на това стъпало.",
+ "Roles told at this rung; handler is the subject's own performer.": "Роли, уведомявани на това стъпало; handler е лицето, което обработва преписката.",
+ "Rungs": "Стъпала",
+ "Stable rung identity, e.g. preBreach:14:calendarDays; derived from trigger, offset and unit when absent.": "Постоянна идентичност на стъпалото, напр. preBreach:14:calendarDays; при липса се извежда от спусъка, отместването и единицата.",
+ "The calendar's stable name, referenced by a timer's calendar_slug.": "Постоянното име на календара, посочвано от calendar_slug на таймер.",
+ "The closed date, Y-m-d.": "Датата на затваряне, Y-m-d.",
+ "The holiday's name.": "Името на празника.",
+ "The ladder's stable name, referenced by a timer's ladder_slug.": "Постоянното име на стълбата, посочвано от ladder_slug на таймер.",
+ "The unit of the offset: the same set the SLA accepts.": "Единицата на отместването: същият набор, който SLA приема.",
+ "The urgency the raised transition carries.": "Спешността, която носи задействаният преход.",
+ "The weekday (name) on which the date shifts, e.g. sunday for Koningsdag.": "Денят от седмицата (име), при който датата се премества, напр. sunday за Koningsdag.",
+ "UUID of the organisation this calendar is configured for. Empty for a shared calendar. The resolution order picks an organisation's calendar when the timer names none.": "UUID на организацията, за която е настроен този календар. Празно при споделен календар. Ако таймерът не посочи никакъв, редът на разрешаване избира календара на организацията.",
+ "UUID of the organisation this ladder is the default for. Empty for the shared default.": "UUID на организацията, за която тази стълба е подразбираща се. Празно при споделената подразбираща се.",
+ "When weekday": "Ако се пада в",
+ "Whether reaching this rung opens an incident.": "Дали достигането на това стъпало отваря инцидент.",
+ "Why the day is closed.": "Защо денят е затворен.",
+ "Working calendar": "Работен календар",
+ "Working hours in one working day. Makes hours and businessDays commensurable.": "Работни часове в един работен ден. Прави часовете и работните дни съизмерими.",
+ "Working weekdays": "Работни дни от седмицата",
+ "fixed: a month/day; easter: an offset in days from Easter Sunday; observedShift: a month/day with a required observed shift.": "fixed: месец и ден; easter: отместване в дни от Великденската неделя; observedShift: месец и ден със задължително преместване.",
+ "preBreach fires before the deadline, slaBreached at or after it.": "preBreach се задейства преди срока, slaBreached на срока или след него.",
+ "No such task": "Няма такава задача",
+ "The task does not exist, or it is not yours to see.": "Задачата не съществува или нямате право да я видите.",
+ "Details": "Детайли",
+ "Due": "Срок",
+ "Assignee": "Изпълнител",
+ "Requested by": "Заявено от",
+ "Outcome": "Резултат",
+ "Ready to claim": "Готово за поемане",
+ "In progress": "В процес",
+ "Terminated": "Прекратена",
+ "Normal": "Нормален",
+ "Urgent": "Спешен",
+ "Overdue by 1 day": "Просрочена с 1 ден",
+ "Overdue by {days} days": "Просрочена с {days} дни",
+ "Due today": "Срок днес",
+ "Due tomorrow": "Срок утре",
+ "Due in {days} days": "Срок след {days} дни",
+ "Tasks": "Задачи",
+ "Task": "Задача",
+ "Unassigned, open for claiming": "Неразпределена, отворена за поемане",
+ "Claim": "Поемане",
+ "Complete": "Завършване",
+ "Complete: {outcome}": "Завършване: {outcome}",
+ "Could not load the task": "Задачата не можа да се зареди",
+ "The task refused that action": "Задачата отказа това действие"
},
"pluralForm": "nplurals=2; plural=(n != 1);",
"plurals": {
diff --git a/l10n/bs.js b/l10n/bs.js
index 9fe988bdb6..fd0a9bce15 100644
--- a/l10n/bs.js
+++ b/l10n/bs.js
@@ -3,11 +3,21 @@ OC.L10N.register(
{
"3": "3",
"30": "30",
+ "from amount {amount}": "od iznosa {amount}",
+ "Gated transition: {transition}": "Nadzirani prelaz: {transition}",
+ "Each declared chain provisions an ordered task sequence when its transition is attempted. Approvers decide in their task inbox, not here.": "Svaki deklarisani lanac otvara uređeni niz zadataka kad se prelaz pokuša. Odobravaoci odlučuju u svom sandučetu zadataka, ne ovdje.",
+ "Declare x-openregister-approval-chains on this schema to gate a lifecycle transition on approval.": "Deklarišite x-openregister-approval-chains na ovoj šemi kako bi prelaz životnog ciklusa zahtijevao odobrenje.",
+ "Approval sequences": "Nizovi odobravanja",
"%n entries have no hash yet": "%n unosa još nema heš",
"%n entry has no hash yet": "%n unos još nema heš",
"(Dolphin required)": "(Potreban Dolphin)",
+ "No approval chains declared": "Nema deklarisanih lanaca odobravanja",
"(no subject)": "(bez predmeta)",
"(no title)": "(bez naslova)",
+ "Role {role}": "Uloga {role}",
+ "The transition is applied automatically once every step approves.": "Prelaz se primjenjuje automatski čim je svaki korak odobren.",
+ "The requester may not decide their own approval.": "Podnosilac zahtjeva ne može odlučivati o vlastitom odobrenju.",
+ "Tier routing on field: {field}": "Usmjeravanje po razredima prema polju: {field}",
"(unnamed)": "(bez naziva)",
"(untitled card)": "(kartica bez naslova)",
"({count} selected)": "({count} odabrano)",
@@ -2738,7 +2748,84 @@ OC.L10N.register(
"_Object successfully deleted_::_Objects successfully deleted_": ["Objekt je uspješno izbrisan","Objekti su uspješno izbrisani","Objekti su uspješno izbrisani"],
"_Purge {count} object from database_::_Purge {count} objects from database_": ["Trajno ukloni {count} objekt iz baze podataka","Trajno ukloni {count} objekta iz baze podataka","Trajno ukloni {count} objekata iz baze podataka"],
"_Restore {count} object_::_Restore {count} objects_": ["Vrati {count} objekt","Vrati {count} objekta","Vrati {count} objekata"],
- "_Successfully restored {count} object_::_Successfully restored {count} objects_": ["Uspješno vraćen {count} objekt","Uspješno vraćena {count} objekta","Uspješno vraćeno {count} objekata"]
+ "_Successfully restored {count} object_::_Successfully restored {count} objects_": ["Uspješno vraćen {count} objekt","Uspješno vraćena {count} objekta","Uspješno vraćeno {count} objekata"],
+ "A message identity the notification subsystem resolves.": "Identitet poruke koji razrješava sustav obavijesti.",
+ "Computed non-working-date rules. kind fixed: {month, day, name, observedShift?: {whenWeekday, days}}. kind easter: {offset, name}, offset in days from Easter Sunday. kind observedShift: a fixed date with a required shift.": "Izračunata pravila neradnih dana. Vrsta fixed: {month, day, name, observedShift?: {whenWeekday, days}}. Vrsta easter: {offset, name}, odmak u danima od Uskršnje nedjelje. Vrsta observedShift: nepomičan datum s obaveznim pomjeranjem.",
+ "Date": "Datum",
+ "Day": "Dan",
+ "Day of a fixed or observedShift rule; ignored by an easter rule.": "Dan pravila fixed ili observedShift; pravilo easter ga zanemaruje.",
+ "Days": "Dani",
+ "Days from Easter Sunday for an easter rule; ignored by the other kinds.": "Dani od Uskršnje nedjelje za pravilo easter; druge ih vrste zanemaruju.",
+ "Distance from the deadline, in the offset unit.": "Udaljenost od roka u jedinici odmaka.",
+ "Enumerated one-off closures as {date, name}. Allowed alongside rules; refused as the whole calendar.": "Pojedinačna zatvaranja nabrojena kao {date, name}. Dopuštena uz pravila; odbijena kao cijeli kalendar.",
+ "Escalate to roles": "Uloge za eskalaciju",
+ "Escalation ladder": "Ljestvica eskalacije",
+ "Exception dates": "Iznimni datumi",
+ "Hours per working day": "Sati po radnom danu",
+ "How many days the observed date shifts, e.g. -1 for the Saturday before.": "Za koliko se dana slavljeni datum pomjera, npr. -1 za subotu prije.",
+ "Human-readable title.": "Čitljiv naslov.",
+ "ISO weekdays (1 = Monday, 7 = Sunday) that are working days.": "ISO dani u sedmici (1 = ponedjeljak, 7 = nedjelja) koji su radni.",
+ "Kind": "Vrsta",
+ "Message": "Poruka",
+ "Month": "Mjesec",
+ "Month of a fixed or observedShift rule; ignored by an easter rule.": "Mjesec pravila fixed ili observedShift; pravilo easter ga zanemaruje.",
+ "Non-working-date rules": "Pravila neradnih dana",
+ "Notify roles": "Uloge za obavijest",
+ "Observed shift": "Pomjeranje praznika",
+ "Offset": "Odmak",
+ "Offset unit": "Jedinica odmaka",
+ "Open incident": "Otvori incident",
+ "Optional map from a role name to a concrete recipient descriptor, e.g. {\"teamleader\": \"group:teamleaders\"}. Roles without a binding travel unresolved as role:.": "Neobvezna mapa imena uloge na konkretnog primatelja, npr. {\"teamleader\": \"group:teamleaders\"}. Uloge bez poveznice putuju nerazriješene kao role:.",
+ "Optional on a fixed rule, required on observedShift: {whenWeekday: weekday name or ISO 1..7, days: integer}.": "Neobavezno kod pravila fixed, obavezno kod observedShift: {whenWeekday: ime dana ili ISO 1..7, days: cijeli broj}.",
+ "Ordered rungs: {key, trigger (preBreach|slaBreached), offset, offsetUnit (hours|businessDays|calendarDays), notifyRole[], escalateToRole[], priority, message, openIncident}.": "Poredane prečke: {key, trigger (preBreach|slaBreached), offset, offsetUnit (hours|businessDays|calendarDays), notifyRole[], escalateToRole[], priority, message, openIncident}.",
+ "Priority": "Prioritet",
+ "Role bindings": "Poveznice uloga",
+ "Roles the matter is escalated to at this rung.": "Uloge na koje se predmet na ovoj prečki eskalira.",
+ "Roles told at this rung; handler is the subject's own performer.": "Uloge obaviještene na ovoj prečki; handler je osoba koja obrađuje predmet.",
+ "Rungs": "Prečke",
+ "Stable rung identity, e.g. preBreach:14:calendarDays; derived from trigger, offset and unit when absent.": "Stalni identitet prečke, npr. preBreach:14:calendarDays; ako nedostaje, izvodi se iz okidača, odmaka i jedinice.",
+ "The calendar's stable name, referenced by a timer's calendar_slug.": "Stalno ime kalendara na koje se tajmer poziva putem calendar_slug.",
+ "The closed date, Y-m-d.": "Datum zatvaranja, Y-m-d.",
+ "The holiday's name.": "Ime praznika.",
+ "The ladder's stable name, referenced by a timer's ladder_slug.": "Stalno ime ljestvice na koje se tajmer poziva putem ladder_slug.",
+ "The unit of the offset: the same set the SLA accepts.": "Jedinica odmaka: isti skup koji SLA prihvaća.",
+ "The urgency the raised transition carries.": "Hitnost koju nosi pokrenuti prijelaz.",
+ "The weekday (name) on which the date shifts, e.g. sunday for Koningsdag.": "Dan u sedmici (ime) na koji se datum pomjera, npr. sunday za Koningsdag.",
+ "UUID of the organisation this calendar is configured for. Empty for a shared calendar. The resolution order picks an organisation's calendar when the timer names none.": "UUID organizacije za koju je ovaj kalendar postavljen. Prazno za dijeljeni kalendar. Ne imenuje li tajmer nijedan, redoslijed razrješavanja bira kalendar organizacije.",
+ "UUID of the organisation this ladder is the default for. Empty for the shared default.": "UUID organizacije kojoj je ova ljestvica zadana. Prazno za dijeljenu zadanu.",
+ "When weekday": "Ako padne na",
+ "Whether reaching this rung opens an incident.": "Otvara li dosezanje ove prečke incident.",
+ "Why the day is closed.": "Zašto je dan zatvoren.",
+ "Working calendar": "Radni kalendar",
+ "Working hours in one working day. Makes hours and businessDays commensurable.": "Radni sati u jednom radnom danu. Čini sate i radne dane usporedivima.",
+ "Working weekdays": "Radni dani u sedmici",
+ "fixed: a month/day; easter: an offset in days from Easter Sunday; observedShift: a month/day with a required observed shift.": "fixed: mjesec i dan; easter: odmak u danima od Uskršnje nedjelje; observedShift: mjesec i dan s obaveznim pomjeranjem.",
+ "preBreach fires before the deadline, slaBreached at or after it.": "preBreach se okida prije roka, slaBreached na rok ili poslije njega.",
+ "No such task": "Nema takvog zadatka",
+ "The task does not exist, or it is not yours to see.": "Zadatak ne postoji ili ga ne smijete vidjeti.",
+ "Details": "Detalji",
+ "Due": "Rok",
+ "Assignee": "Dodijeljeno",
+ "Requested by": "Zatražio",
+ "Outcome": "Ishod",
+ "Ready to claim": "Spremno za preuzimanje",
+ "In progress": "U toku",
+ "Terminated": "Prekinuto",
+ "Normal": "Normalno",
+ "Urgent": "Hitno",
+ "Overdue by 1 day": "Kasni 1 dan",
+ "Overdue by {days} days": "Kasni {days} dana",
+ "Due today": "Rok je danas",
+ "Due tomorrow": "Rok je sutra",
+ "Due in {days} days": "Rok za {days} dana",
+ "Tasks": "Zadaci",
+ "Task": "Zadatak",
+ "Unassigned, open for claiming": "Nedodijeljeno, otvoreno za preuzimanje",
+ "Claim": "Preuzmi",
+ "Complete": "Završi",
+ "Complete: {outcome}": "Završi: {outcome}",
+ "Could not load the task": "Zadatak se ne može učitati",
+ "The task refused that action": "Zadatak je odbio tu radnju"
},
"nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;"
)
diff --git a/l10n/bs.json b/l10n/bs.json
index 03af38a5bc..b49c68ab5f 100644
--- a/l10n/bs.json
+++ b/l10n/bs.json
@@ -1,10 +1,20 @@
{
"translations": {
+ "from amount {amount}": "od iznosa {amount}",
+ "Gated transition: {transition}": "Nadzirani prelaz: {transition}",
+ "Each declared chain provisions an ordered task sequence when its transition is attempted. Approvers decide in their task inbox, not here.": "Svaki deklarisani lanac otvara uređeni niz zadataka kad se prelaz pokuša. Odobravaoci odlučuju u svom sandučetu zadataka, ne ovdje.",
+ "Declare x-openregister-approval-chains on this schema to gate a lifecycle transition on approval.": "Deklarišite x-openregister-approval-chains na ovoj šemi kako bi prelaz životnog ciklusa zahtijevao odobrenje.",
+ "Approval sequences": "Nizovi odobravanja",
"%n entries have no hash yet": "%n unosa još nema heš",
"%n entry has no hash yet": "%n unos još nema heš",
"(Dolphin required)": "(Potreban Dolphin)",
+ "No approval chains declared": "Nema deklarisanih lanaca odobravanja",
"(no subject)": "(bez predmeta)",
"(no title)": "(bez naslova)",
+ "Role {role}": "Uloga {role}",
+ "The transition is applied automatically once every step approves.": "Prelaz se primjenjuje automatski čim je svaki korak odobren.",
+ "The requester may not decide their own approval.": "Podnosilac zahtjeva ne može odlučivati o vlastitom odobrenju.",
+ "Tier routing on field: {field}": "Usmjeravanje po razredima prema polju: {field}",
"(unnamed)": "(bez naziva)",
"(untitled card)": "(kartica bez naslova)",
"({count} selected)": "({count} odabrano)",
@@ -2801,7 +2811,84 @@
"Uspješno vraćen {count} objekt",
"Uspješno vraćena {count} objekta",
"Uspješno vraćeno {count} objekata"
- ]
+ ],
+ "A message identity the notification subsystem resolves.": "Identitet poruke koji razrješava sustav obavijesti.",
+ "Computed non-working-date rules. kind fixed: {month, day, name, observedShift?: {whenWeekday, days}}. kind easter: {offset, name}, offset in days from Easter Sunday. kind observedShift: a fixed date with a required shift.": "Izračunata pravila neradnih dana. Vrsta fixed: {month, day, name, observedShift?: {whenWeekday, days}}. Vrsta easter: {offset, name}, odmak u danima od Uskršnje nedjelje. Vrsta observedShift: nepomičan datum s obaveznim pomjeranjem.",
+ "Date": "Datum",
+ "Day": "Dan",
+ "Day of a fixed or observedShift rule; ignored by an easter rule.": "Dan pravila fixed ili observedShift; pravilo easter ga zanemaruje.",
+ "Days": "Dani",
+ "Days from Easter Sunday for an easter rule; ignored by the other kinds.": "Dani od Uskršnje nedjelje za pravilo easter; druge ih vrste zanemaruju.",
+ "Distance from the deadline, in the offset unit.": "Udaljenost od roka u jedinici odmaka.",
+ "Enumerated one-off closures as {date, name}. Allowed alongside rules; refused as the whole calendar.": "Pojedinačna zatvaranja nabrojena kao {date, name}. Dopuštena uz pravila; odbijena kao cijeli kalendar.",
+ "Escalate to roles": "Uloge za eskalaciju",
+ "Escalation ladder": "Ljestvica eskalacije",
+ "Exception dates": "Iznimni datumi",
+ "Hours per working day": "Sati po radnom danu",
+ "How many days the observed date shifts, e.g. -1 for the Saturday before.": "Za koliko se dana slavljeni datum pomjera, npr. -1 za subotu prije.",
+ "Human-readable title.": "Čitljiv naslov.",
+ "ISO weekdays (1 = Monday, 7 = Sunday) that are working days.": "ISO dani u sedmici (1 = ponedjeljak, 7 = nedjelja) koji su radni.",
+ "Kind": "Vrsta",
+ "Message": "Poruka",
+ "Month": "Mjesec",
+ "Month of a fixed or observedShift rule; ignored by an easter rule.": "Mjesec pravila fixed ili observedShift; pravilo easter ga zanemaruje.",
+ "Non-working-date rules": "Pravila neradnih dana",
+ "Notify roles": "Uloge za obavijest",
+ "Observed shift": "Pomjeranje praznika",
+ "Offset": "Odmak",
+ "Offset unit": "Jedinica odmaka",
+ "Open incident": "Otvori incident",
+ "Optional map from a role name to a concrete recipient descriptor, e.g. {\"teamleader\": \"group:teamleaders\"}. Roles without a binding travel unresolved as role:.": "Neobvezna mapa imena uloge na konkretnog primatelja, npr. {\"teamleader\": \"group:teamleaders\"}. Uloge bez poveznice putuju nerazriješene kao role:.",
+ "Optional on a fixed rule, required on observedShift: {whenWeekday: weekday name or ISO 1..7, days: integer}.": "Neobavezno kod pravila fixed, obavezno kod observedShift: {whenWeekday: ime dana ili ISO 1..7, days: cijeli broj}.",
+ "Ordered rungs: {key, trigger (preBreach|slaBreached), offset, offsetUnit (hours|businessDays|calendarDays), notifyRole[], escalateToRole[], priority, message, openIncident}.": "Poredane prečke: {key, trigger (preBreach|slaBreached), offset, offsetUnit (hours|businessDays|calendarDays), notifyRole[], escalateToRole[], priority, message, openIncident}.",
+ "Priority": "Prioritet",
+ "Role bindings": "Poveznice uloga",
+ "Roles the matter is escalated to at this rung.": "Uloge na koje se predmet na ovoj prečki eskalira.",
+ "Roles told at this rung; handler is the subject's own performer.": "Uloge obaviještene na ovoj prečki; handler je osoba koja obrađuje predmet.",
+ "Rungs": "Prečke",
+ "Stable rung identity, e.g. preBreach:14:calendarDays; derived from trigger, offset and unit when absent.": "Stalni identitet prečke, npr. preBreach:14:calendarDays; ako nedostaje, izvodi se iz okidača, odmaka i jedinice.",
+ "The calendar's stable name, referenced by a timer's calendar_slug.": "Stalno ime kalendara na koje se tajmer poziva putem calendar_slug.",
+ "The closed date, Y-m-d.": "Datum zatvaranja, Y-m-d.",
+ "The holiday's name.": "Ime praznika.",
+ "The ladder's stable name, referenced by a timer's ladder_slug.": "Stalno ime ljestvice na koje se tajmer poziva putem ladder_slug.",
+ "The unit of the offset: the same set the SLA accepts.": "Jedinica odmaka: isti skup koji SLA prihvaća.",
+ "The urgency the raised transition carries.": "Hitnost koju nosi pokrenuti prijelaz.",
+ "The weekday (name) on which the date shifts, e.g. sunday for Koningsdag.": "Dan u sedmici (ime) na koji se datum pomjera, npr. sunday za Koningsdag.",
+ "UUID of the organisation this calendar is configured for. Empty for a shared calendar. The resolution order picks an organisation's calendar when the timer names none.": "UUID organizacije za koju je ovaj kalendar postavljen. Prazno za dijeljeni kalendar. Ne imenuje li tajmer nijedan, redoslijed razrješavanja bira kalendar organizacije.",
+ "UUID of the organisation this ladder is the default for. Empty for the shared default.": "UUID organizacije kojoj je ova ljestvica zadana. Prazno za dijeljenu zadanu.",
+ "When weekday": "Ako padne na",
+ "Whether reaching this rung opens an incident.": "Otvara li dosezanje ove prečke incident.",
+ "Why the day is closed.": "Zašto je dan zatvoren.",
+ "Working calendar": "Radni kalendar",
+ "Working hours in one working day. Makes hours and businessDays commensurable.": "Radni sati u jednom radnom danu. Čini sate i radne dane usporedivima.",
+ "Working weekdays": "Radni dani u sedmici",
+ "fixed: a month/day; easter: an offset in days from Easter Sunday; observedShift: a month/day with a required observed shift.": "fixed: mjesec i dan; easter: odmak u danima od Uskršnje nedjelje; observedShift: mjesec i dan s obaveznim pomjeranjem.",
+ "preBreach fires before the deadline, slaBreached at or after it.": "preBreach se okida prije roka, slaBreached na rok ili poslije njega.",
+ "No such task": "Nema takvog zadatka",
+ "The task does not exist, or it is not yours to see.": "Zadatak ne postoji ili ga ne smijete vidjeti.",
+ "Details": "Detalji",
+ "Due": "Rok",
+ "Assignee": "Dodijeljeno",
+ "Requested by": "Zatražio",
+ "Outcome": "Ishod",
+ "Ready to claim": "Spremno za preuzimanje",
+ "In progress": "U toku",
+ "Terminated": "Prekinuto",
+ "Normal": "Normalno",
+ "Urgent": "Hitno",
+ "Overdue by 1 day": "Kasni 1 dan",
+ "Overdue by {days} days": "Kasni {days} dana",
+ "Due today": "Rok je danas",
+ "Due tomorrow": "Rok je sutra",
+ "Due in {days} days": "Rok za {days} dana",
+ "Tasks": "Zadaci",
+ "Task": "Zadatak",
+ "Unassigned, open for claiming": "Nedodijeljeno, otvoreno za preuzimanje",
+ "Claim": "Preuzmi",
+ "Complete": "Završi",
+ "Complete: {outcome}": "Završi: {outcome}",
+ "Could not load the task": "Zadatak se ne može učitati",
+ "The task refused that action": "Zadatak je odbio tu radnju"
},
"pluralForm": "nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;",
"plurals": {
diff --git a/l10n/ca.js b/l10n/ca.js
index 4e22f363df..ad36d2f8fc 100644
--- a/l10n/ca.js
+++ b/l10n/ca.js
@@ -3,11 +3,21 @@ OC.L10N.register(
{
"3": "3",
"30": "30",
+ "from amount {amount}": "a partir de l'import {amount}",
+ "Gated transition: {transition}": "Transició controlada: {transition}",
+ "Each declared chain provisions an ordered task sequence when its transition is attempted. Approvers decide in their task inbox, not here.": "Cada cadena declarada obre una seqüència ordenada de tasques quan s'intenta la transició. Els aprovadors decideixen a la seva safata de tasques, no aquí.",
+ "Declare x-openregister-approval-chains on this schema to gate a lifecycle transition on approval.": "Declareu x-openregister-approval-chains en aquest esquema per condicionar una transició del cicle de vida a una aprovació.",
+ "Approval sequences": "Seqüències d'aprovació",
"%n entries have no hash yet": "%n entrades encara no tenen resum",
"%n entry has no hash yet": "%n entrada encara no té resum",
"(Dolphin required)": "(Es requereix Dolphin)",
+ "No approval chains declared": "No hi ha cadenes d'aprovació declarades",
"(no subject)": "(sense assumpte)",
"(no title)": "(sense títol)",
+ "Role {role}": "Rol {role}",
+ "The transition is applied automatically once every step approves.": "La transició s'aplica automàticament quan tots els passos estan aprovats.",
+ "The requester may not decide their own approval.": "El sol·licitant no pot decidir sobre la seva pròpia aprovació.",
+ "Tier routing on field: {field}": "Encaminament per trams segons el camp: {field}",
"(unnamed)": "(sense nom)",
"(untitled card)": "(targeta sense títol)",
"({count} selected)": "({count} seleccionats)",
@@ -2738,7 +2748,84 @@ OC.L10N.register(
"_Object successfully deleted_::_Objects successfully deleted_": ["Objecte eliminat correctament","Objectes eliminats correctament"],
"_Purge {count} object from database_::_Purge {count} objects from database_": ["Purga {count} objecte de la base de dades","Purga {count} objectes de la base de dades"],
"_Restore {count} object_::_Restore {count} objects_": ["Restaura {count} objecte","Restaura {count} objectes"],
- "_Successfully restored {count} object_::_Successfully restored {count} objects_": ["{count} objecte restaurat correctament","{count} objectes restaurats correctament"]
+ "_Successfully restored {count} object_::_Successfully restored {count} objects_": ["{count} objecte restaurat correctament","{count} objectes restaurats correctament"],
+ "A message identity the notification subsystem resolves.": "Una identitat de missatge que resol el sistema de notificacions.",
+ "Computed non-working-date rules. kind fixed: {month, day, name, observedShift?: {whenWeekday, days}}. kind easter: {offset, name}, offset in days from Easter Sunday. kind observedShift: a fixed date with a required shift.": "Regles calculades de dies no laborables. Tipus fixed: {month, day, name, observedShift?: {whenWeekday, days}}. Tipus easter: {offset, name}, desplaçament en dies des del Diumenge de Pasqua. Tipus observedShift: una data fixa amb trasllat obligatori.",
+ "Date": "Data",
+ "Day": "Dia",
+ "Day of a fixed or observedShift rule; ignored by an easter rule.": "Dia d'una regla fixed o observedShift; una regla easter l'ignora.",
+ "Days": "Dies",
+ "Days from Easter Sunday for an easter rule; ignored by the other kinds.": "Dies des del Diumenge de Pasqua per a una regla easter; els altres tipus els ignoren.",
+ "Distance from the deadline, in the offset unit.": "Distància al termini, en la unitat del desplaçament.",
+ "Enumerated one-off closures as {date, name}. Allowed alongside rules; refused as the whole calendar.": "Tancaments puntuals enumerats com a {date, name}. Permesos al costat de regles; rebutjats com a calendari sencer.",
+ "Escalate to roles": "Rols d'escalada",
+ "Escalation ladder": "Escala d'escalada",
+ "Exception dates": "Dates d'excepció",
+ "Hours per working day": "Hores per dia feiner",
+ "How many days the observed date shifts, e.g. -1 for the Saturday before.": "Quants dies es trasllada la data observada, p. ex. -1 per al dissabte anterior.",
+ "Human-readable title.": "Títol llegible.",
+ "ISO weekdays (1 = Monday, 7 = Sunday) that are working days.": "Dies ISO de la setmana (1 = dilluns, 7 = diumenge) que són feiners.",
+ "Kind": "Tipus",
+ "Message": "Missatge",
+ "Month": "Mes",
+ "Month of a fixed or observedShift rule; ignored by an easter rule.": "Mes d'una regla fixed o observedShift; una regla easter l'ignora.",
+ "Non-working-date rules": "Regles de dies no laborables",
+ "Notify roles": "Rols a notificar",
+ "Observed shift": "Trasllat del festiu",
+ "Offset": "Desplaçament",
+ "Offset unit": "Unitat del desplaçament",
+ "Open incident": "Obrir una incidència",
+ "Optional map from a role name to a concrete recipient descriptor, e.g. {\"teamleader\": \"group:teamleaders\"}. Roles without a binding travel unresolved as role:.": "Mapa opcional d'un nom de rol a un destinatari concret, p. ex. {\"teamleader\": \"group:teamleaders\"}. Els rols sense vinculació viatgen sense resoldre com a role:.",
+ "Optional on a fixed rule, required on observedShift: {whenWeekday: weekday name or ISO 1..7, days: integer}.": "Opcional en una regla fixed, obligatori en observedShift: {whenWeekday: nom del dia o ISO 1..7, days: enter}.",
+ "Ordered rungs: {key, trigger (preBreach|slaBreached), offset, offsetUnit (hours|businessDays|calendarDays), notifyRole[], escalateToRole[], priority, message, openIncident}.": "Esglaons ordenats: {key, trigger (preBreach|slaBreached), offset, offsetUnit (hours|businessDays|calendarDays), notifyRole[], escalateToRole[], priority, message, openIncident}.",
+ "Priority": "Prioritat",
+ "Role bindings": "Vinculacions de rols",
+ "Roles the matter is escalated to at this rung.": "Rols als quals s'escala l'assumpte en aquest esglaó.",
+ "Roles told at this rung; handler is the subject's own performer.": "Rols avisats en aquest esglaó; handler és la persona encarregada de l'assumpte.",
+ "Rungs": "Esglaons",
+ "Stable rung identity, e.g. preBreach:14:calendarDays; derived from trigger, offset and unit when absent.": "Identitat estable de l'esglaó, p. ex. preBreach:14:calendarDays; si falta, es deriva de l'activador, el desplaçament i la unitat.",
+ "The calendar's stable name, referenced by a timer's calendar_slug.": "El nom estable del calendari, referenciat pel calendar_slug d'un temporitzador.",
+ "The closed date, Y-m-d.": "La data de tancament, Y-m-d.",
+ "The holiday's name.": "El nom del festiu.",
+ "The ladder's stable name, referenced by a timer's ladder_slug.": "El nom estable de l'escala, referenciat pel ladder_slug d'un temporitzador.",
+ "The unit of the offset: the same set the SLA accepts.": "La unitat del desplaçament: el mateix conjunt que accepta l'SLA.",
+ "The urgency the raised transition carries.": "La urgència que porta la transició disparada.",
+ "The weekday (name) on which the date shifts, e.g. sunday for Koningsdag.": "El dia de la setmana (nom) en què la data es trasllada, p. ex. sunday per a Koningsdag.",
+ "UUID of the organisation this calendar is configured for. Empty for a shared calendar. The resolution order picks an organisation's calendar when the timer names none.": "UUID de l'organització per a la qual està configurat aquest calendari. Buit per a un calendari compartit. Si el temporitzador no en nomena cap, l'ordre de resolució tria el calendari de l'organització.",
+ "UUID of the organisation this ladder is the default for. Empty for the shared default.": "UUID de l'organització per a la qual aquesta escala és la predeterminada. Buit per al valor compartit.",
+ "When weekday": "Si cau en",
+ "Whether reaching this rung opens an incident.": "Si assolir aquest esglaó obre una incidència.",
+ "Why the day is closed.": "Per què està tancat aquest dia.",
+ "Working calendar": "Calendari laboral",
+ "Working hours in one working day. Makes hours and businessDays commensurable.": "Hores treballades en un dia feiner. Fa comparables les hores i els dies feiners.",
+ "Working weekdays": "Dies feiners de la setmana",
+ "fixed: a month/day; easter: an offset in days from Easter Sunday; observedShift: a month/day with a required observed shift.": "fixed: mes i dia; easter: un desplaçament en dies des del Diumenge de Pasqua; observedShift: mes i dia amb trasllat obligatori.",
+ "preBreach fires before the deadline, slaBreached at or after it.": "preBreach es dispara abans del termini, slaBreached al termini o després.",
+ "No such task": "No existeix aquesta tasca",
+ "The task does not exist, or it is not yours to see.": "La tasca no existeix o no la podeu veure.",
+ "Details": "Detalls",
+ "Due": "Venciment",
+ "Assignee": "Assignat a",
+ "Requested by": "Sol·licitat per",
+ "Outcome": "Resultat",
+ "Ready to claim": "A punt per reclamar",
+ "In progress": "En curs",
+ "Terminated": "Finalitzada",
+ "Normal": "Normal",
+ "Urgent": "Urgent",
+ "Overdue by 1 day": "Endarrerida 1 dia",
+ "Overdue by {days} days": "Endarrerida {days} dies",
+ "Due today": "Venç avui",
+ "Due tomorrow": "Venç demà",
+ "Due in {days} days": "Venç d'aquí a {days} dies",
+ "Tasks": "Tasques",
+ "Task": "Tasca",
+ "Unassigned, open for claiming": "Sense assignar, oberta per reclamar",
+ "Claim": "Reclama",
+ "Complete": "Completa",
+ "Complete: {outcome}": "Completa: {outcome}",
+ "Could not load the task": "No s'ha pogut carregar la tasca",
+ "The task refused that action": "La tasca ha rebutjat aquesta acció"
},
"nplurals=2; plural=(n != 1);"
)
diff --git a/l10n/ca.json b/l10n/ca.json
index 4bd25d354a..2aaf0ee22e 100644
--- a/l10n/ca.json
+++ b/l10n/ca.json
@@ -1,10 +1,20 @@
{
"translations": {
+ "from amount {amount}": "a partir de l'import {amount}",
+ "Gated transition: {transition}": "Transició controlada: {transition}",
+ "Each declared chain provisions an ordered task sequence when its transition is attempted. Approvers decide in their task inbox, not here.": "Cada cadena declarada obre una seqüència ordenada de tasques quan s'intenta la transició. Els aprovadors decideixen a la seva safata de tasques, no aquí.",
+ "Declare x-openregister-approval-chains on this schema to gate a lifecycle transition on approval.": "Declareu x-openregister-approval-chains en aquest esquema per condicionar una transició del cicle de vida a una aprovació.",
+ "Approval sequences": "Seqüències d'aprovació",
"%n entries have no hash yet": "%n entrades encara no tenen resum",
"%n entry has no hash yet": "%n entrada encara no té resum",
"(Dolphin required)": "(Es requereix Dolphin)",
+ "No approval chains declared": "No hi ha cadenes d'aprovació declarades",
"(no subject)": "(sense assumpte)",
"(no title)": "(sense títol)",
+ "Role {role}": "Rol {role}",
+ "The transition is applied automatically once every step approves.": "La transició s'aplica automàticament quan tots els passos estan aprovats.",
+ "The requester may not decide their own approval.": "El sol·licitant no pot decidir sobre la seva pròpia aprovació.",
+ "Tier routing on field: {field}": "Encaminament per trams segons el camp: {field}",
"(unnamed)": "(sense nom)",
"(untitled card)": "(targeta sense títol)",
"({count} selected)": "({count} seleccionats)",
@@ -2785,7 +2795,84 @@
"_Successfully restored {count} object_::_Successfully restored {count} objects_": [
"{count} objecte restaurat correctament",
"{count} objectes restaurats correctament"
- ]
+ ],
+ "A message identity the notification subsystem resolves.": "Una identitat de missatge que resol el sistema de notificacions.",
+ "Computed non-working-date rules. kind fixed: {month, day, name, observedShift?: {whenWeekday, days}}. kind easter: {offset, name}, offset in days from Easter Sunday. kind observedShift: a fixed date with a required shift.": "Regles calculades de dies no laborables. Tipus fixed: {month, day, name, observedShift?: {whenWeekday, days}}. Tipus easter: {offset, name}, desplaçament en dies des del Diumenge de Pasqua. Tipus observedShift: una data fixa amb trasllat obligatori.",
+ "Date": "Data",
+ "Day": "Dia",
+ "Day of a fixed or observedShift rule; ignored by an easter rule.": "Dia d'una regla fixed o observedShift; una regla easter l'ignora.",
+ "Days": "Dies",
+ "Days from Easter Sunday for an easter rule; ignored by the other kinds.": "Dies des del Diumenge de Pasqua per a una regla easter; els altres tipus els ignoren.",
+ "Distance from the deadline, in the offset unit.": "Distància al termini, en la unitat del desplaçament.",
+ "Enumerated one-off closures as {date, name}. Allowed alongside rules; refused as the whole calendar.": "Tancaments puntuals enumerats com a {date, name}. Permesos al costat de regles; rebutjats com a calendari sencer.",
+ "Escalate to roles": "Rols d'escalada",
+ "Escalation ladder": "Escala d'escalada",
+ "Exception dates": "Dates d'excepció",
+ "Hours per working day": "Hores per dia feiner",
+ "How many days the observed date shifts, e.g. -1 for the Saturday before.": "Quants dies es trasllada la data observada, p. ex. -1 per al dissabte anterior.",
+ "Human-readable title.": "Títol llegible.",
+ "ISO weekdays (1 = Monday, 7 = Sunday) that are working days.": "Dies ISO de la setmana (1 = dilluns, 7 = diumenge) que són feiners.",
+ "Kind": "Tipus",
+ "Message": "Missatge",
+ "Month": "Mes",
+ "Month of a fixed or observedShift rule; ignored by an easter rule.": "Mes d'una regla fixed o observedShift; una regla easter l'ignora.",
+ "Non-working-date rules": "Regles de dies no laborables",
+ "Notify roles": "Rols a notificar",
+ "Observed shift": "Trasllat del festiu",
+ "Offset": "Desplaçament",
+ "Offset unit": "Unitat del desplaçament",
+ "Open incident": "Obrir una incidència",
+ "Optional map from a role name to a concrete recipient descriptor, e.g. {\"teamleader\": \"group:teamleaders\"}. Roles without a binding travel unresolved as role:.": "Mapa opcional d'un nom de rol a un destinatari concret, p. ex. {\"teamleader\": \"group:teamleaders\"}. Els rols sense vinculació viatgen sense resoldre com a role:.",
+ "Optional on a fixed rule, required on observedShift: {whenWeekday: weekday name or ISO 1..7, days: integer}.": "Opcional en una regla fixed, obligatori en observedShift: {whenWeekday: nom del dia o ISO 1..7, days: enter}.",
+ "Ordered rungs: {key, trigger (preBreach|slaBreached), offset, offsetUnit (hours|businessDays|calendarDays), notifyRole[], escalateToRole[], priority, message, openIncident}.": "Esglaons ordenats: {key, trigger (preBreach|slaBreached), offset, offsetUnit (hours|businessDays|calendarDays), notifyRole[], escalateToRole[], priority, message, openIncident}.",
+ "Priority": "Prioritat",
+ "Role bindings": "Vinculacions de rols",
+ "Roles the matter is escalated to at this rung.": "Rols als quals s'escala l'assumpte en aquest esglaó.",
+ "Roles told at this rung; handler is the subject's own performer.": "Rols avisats en aquest esglaó; handler és la persona encarregada de l'assumpte.",
+ "Rungs": "Esglaons",
+ "Stable rung identity, e.g. preBreach:14:calendarDays; derived from trigger, offset and unit when absent.": "Identitat estable de l'esglaó, p. ex. preBreach:14:calendarDays; si falta, es deriva de l'activador, el desplaçament i la unitat.",
+ "The calendar's stable name, referenced by a timer's calendar_slug.": "El nom estable del calendari, referenciat pel calendar_slug d'un temporitzador.",
+ "The closed date, Y-m-d.": "La data de tancament, Y-m-d.",
+ "The holiday's name.": "El nom del festiu.",
+ "The ladder's stable name, referenced by a timer's ladder_slug.": "El nom estable de l'escala, referenciat pel ladder_slug d'un temporitzador.",
+ "The unit of the offset: the same set the SLA accepts.": "La unitat del desplaçament: el mateix conjunt que accepta l'SLA.",
+ "The urgency the raised transition carries.": "La urgència que porta la transició disparada.",
+ "The weekday (name) on which the date shifts, e.g. sunday for Koningsdag.": "El dia de la setmana (nom) en què la data es trasllada, p. ex. sunday per a Koningsdag.",
+ "UUID of the organisation this calendar is configured for. Empty for a shared calendar. The resolution order picks an organisation's calendar when the timer names none.": "UUID de l'organització per a la qual està configurat aquest calendari. Buit per a un calendari compartit. Si el temporitzador no en nomena cap, l'ordre de resolució tria el calendari de l'organització.",
+ "UUID of the organisation this ladder is the default for. Empty for the shared default.": "UUID de l'organització per a la qual aquesta escala és la predeterminada. Buit per al valor compartit.",
+ "When weekday": "Si cau en",
+ "Whether reaching this rung opens an incident.": "Si assolir aquest esglaó obre una incidència.",
+ "Why the day is closed.": "Per què està tancat aquest dia.",
+ "Working calendar": "Calendari laboral",
+ "Working hours in one working day. Makes hours and businessDays commensurable.": "Hores treballades en un dia feiner. Fa comparables les hores i els dies feiners.",
+ "Working weekdays": "Dies feiners de la setmana",
+ "fixed: a month/day; easter: an offset in days from Easter Sunday; observedShift: a month/day with a required observed shift.": "fixed: mes i dia; easter: un desplaçament en dies des del Diumenge de Pasqua; observedShift: mes i dia amb trasllat obligatori.",
+ "preBreach fires before the deadline, slaBreached at or after it.": "preBreach es dispara abans del termini, slaBreached al termini o després.",
+ "No such task": "No existeix aquesta tasca",
+ "The task does not exist, or it is not yours to see.": "La tasca no existeix o no la podeu veure.",
+ "Details": "Detalls",
+ "Due": "Venciment",
+ "Assignee": "Assignat a",
+ "Requested by": "Sol·licitat per",
+ "Outcome": "Resultat",
+ "Ready to claim": "A punt per reclamar",
+ "In progress": "En curs",
+ "Terminated": "Finalitzada",
+ "Normal": "Normal",
+ "Urgent": "Urgent",
+ "Overdue by 1 day": "Endarrerida 1 dia",
+ "Overdue by {days} days": "Endarrerida {days} dies",
+ "Due today": "Venç avui",
+ "Due tomorrow": "Venç demà",
+ "Due in {days} days": "Venç d'aquí a {days} dies",
+ "Tasks": "Tasques",
+ "Task": "Tasca",
+ "Unassigned, open for claiming": "Sense assignar, oberta per reclamar",
+ "Claim": "Reclama",
+ "Complete": "Completa",
+ "Complete: {outcome}": "Completa: {outcome}",
+ "Could not load the task": "No s'ha pogut carregar la tasca",
+ "The task refused that action": "La tasca ha rebutjat aquesta acció"
},
"pluralForm": "nplurals=2; plural=(n != 1);",
"plurals": {
diff --git a/l10n/cs.js b/l10n/cs.js
index 94b6dc71b8..58024bf2b3 100644
--- a/l10n/cs.js
+++ b/l10n/cs.js
@@ -3,11 +3,21 @@ OC.L10N.register(
{
"3": "3",
"30": "30",
+ "from amount {amount}": "od částky {amount}",
+ "Gated transition: {transition}": "Hlídaný přechod: {transition}",
+ "Each declared chain provisions an ordered task sequence when its transition is attempted. Approvers decide in their task inbox, not here.": "Každý deklarovaný řetězec otevře uspořádanou sekvenci úkolů při pokusu o přechod. Schvalovatelé rozhodují ve své schránce úkolů, ne zde.",
+ "Declare x-openregister-approval-chains on this schema to gate a lifecycle transition on approval.": "Deklarujte x-openregister-approval-chains na tomto schématu, aby přechod životního cyklu podléhal schválení.",
+ "Approval sequences": "Schvalovací sekvence",
"%n entries have no hash yet": "%n záznamů zatím nemá otisk",
"%n entry has no hash yet": "%n záznam zatím nemá otisk",
"(Dolphin required)": "(vyžaduje Dolphin)",
+ "No approval chains declared": "Nejsou deklarovány žádné schvalovací řetězce",
"(no subject)": "(bez předmětu)",
"(no title)": "(bez názvu)",
+ "Role {role}": "Role {role}",
+ "The transition is applied automatically once every step approves.": "Přechod se použije automaticky, jakmile je každý krok schválen.",
+ "The requester may not decide their own approval.": "Žadatel nesmí rozhodovat o vlastním schválení.",
+ "Tier routing on field: {field}": "Směrování podle pásem přes pole: {field}",
"(unnamed)": "(bez názvu)",
"(untitled card)": "(karta bez názvu)",
"({count} selected)": "({count} vybráno)",
@@ -2738,7 +2748,84 @@ OC.L10N.register(
"_Object successfully deleted_::_Objects successfully deleted_": ["Objekt byl úspěšně smazán","Objekty byly úspěšně smazány","Objekty byly úspěšně smazány","Objekty byly úspěšně smazány"],
"_Purge {count} object from database_::_Purge {count} objects from database_": ["Vyčistit {count} objekt z databáze","Vyčistit {count} objekty z databáze","Vyčistit {count} objektu z databáze","Vyčistit {count} objektů z databáze"],
"_Restore {count} object_::_Restore {count} objects_": ["Obnovit {count} objekt","Obnovit {count} objekty","Obnovit {count} objektu","Obnovit {count} objektů"],
- "_Successfully restored {count} object_::_Successfully restored {count} objects_": ["Úspěšně obnoven {count} objekt","Úspěšně obnoveny {count} objekty","Úspěšně obnoveno {count} objektu","Úspěšně obnoveno {count} objektů"]
+ "_Successfully restored {count} object_::_Successfully restored {count} objects_": ["Úspěšně obnoven {count} objekt","Úspěšně obnoveny {count} objekty","Úspěšně obnoveno {count} objektu","Úspěšně obnoveno {count} objektů"],
+ "A message identity the notification subsystem resolves.": "Identita zprávy, kterou rozliší systém upozornění.",
+ "Computed non-working-date rules. kind fixed: {month, day, name, observedShift?: {whenWeekday, days}}. kind easter: {offset, name}, offset in days from Easter Sunday. kind observedShift: a fixed date with a required shift.": "Vypočítaná pravidla nepracovních dnů. Druh fixed: {month, day, name, observedShift?: {whenWeekday, days}}. Druh easter: {offset, name}, odstup ve dnech od Velikonoční neděle. Druh observedShift: pevné datum s povinným přesunem.",
+ "Date": "Datum",
+ "Day": "Den",
+ "Day of a fixed or observedShift rule; ignored by an easter rule.": "Den pravidla fixed nebo observedShift; pravidlo easter jej ignoruje.",
+ "Days": "Dny",
+ "Days from Easter Sunday for an easter rule; ignored by the other kinds.": "Dny od Velikonoční neděle pro pravidlo easter; ostatní druhy je ignorují.",
+ "Distance from the deadline, in the offset unit.": "Vzdálenost od lhůty v jednotce odstupu.",
+ "Enumerated one-off closures as {date, name}. Allowed alongside rules; refused as the whole calendar.": "Jednorázová uzavření vyjmenovaná jako {date, name}. Povolena vedle pravidel; odmítnuta jako celý kalendář.",
+ "Escalate to roles": "Role pro eskalaci",
+ "Escalation ladder": "Eskalační žebřík",
+ "Exception dates": "Výjimečná data",
+ "Hours per working day": "Hodin na pracovní den",
+ "How many days the observed date shifts, e.g. -1 for the Saturday before.": "O kolik dnů se slavené datum přesune, např. -1 pro předchozí sobotu.",
+ "Human-readable title.": "Čitelný název.",
+ "ISO weekdays (1 = Monday, 7 = Sunday) that are working days.": "ISO dny v týdnu (1 = pondělí, 7 = neděle), které jsou pracovní.",
+ "Kind": "Druh",
+ "Message": "Zpráva",
+ "Month": "Měsíc",
+ "Month of a fixed or observedShift rule; ignored by an easter rule.": "Měsíc pravidla fixed nebo observedShift; pravidlo easter jej ignoruje.",
+ "Non-working-date rules": "Pravidla nepracovních dnů",
+ "Notify roles": "Role k upozornění",
+ "Observed shift": "Přesun svátku",
+ "Offset": "Odstup",
+ "Offset unit": "Jednotka odstupu",
+ "Open incident": "Otevřít incident",
+ "Optional map from a role name to a concrete recipient descriptor, e.g. {\"teamleader\": \"group:teamleaders\"}. Roles without a binding travel unresolved as role:.": "Volitelná mapa z názvu role na konkrétního příjemce, např. {\"teamleader\": \"group:teamleaders\"}. Role bez vazby putují nerozlišené jako role:.",
+ "Optional on a fixed rule, required on observedShift: {whenWeekday: weekday name or ISO 1..7, days: integer}.": "Volitelné u pravidla fixed, povinné u observedShift: {whenWeekday: název dne nebo ISO 1..7, days: celé číslo}.",
+ "Ordered rungs: {key, trigger (preBreach|slaBreached), offset, offsetUnit (hours|businessDays|calendarDays), notifyRole[], escalateToRole[], priority, message, openIncident}.": "Seřazené příčky: {key, trigger (preBreach|slaBreached), offset, offsetUnit (hours|businessDays|calendarDays), notifyRole[], escalateToRole[], priority, message, openIncident}.",
+ "Priority": "Priorita",
+ "Role bindings": "Vazby rolí",
+ "Roles the matter is escalated to at this rung.": "Role, na které se věc na této příčce eskaluje.",
+ "Roles told at this rung; handler is the subject's own performer.": "Role upozorněné na této příčce; handler je osoba, která věc vyřizuje.",
+ "Rungs": "Příčky",
+ "Stable rung identity, e.g. preBreach:14:calendarDays; derived from trigger, offset and unit when absent.": "Stálá identita příčky, např. preBreach:14:calendarDays; chybí-li, odvodí se ze spouštěče, odstupu a jednotky.",
+ "The calendar's stable name, referenced by a timer's calendar_slug.": "Stálý název kalendáře, na který časovač odkazuje přes calendar_slug.",
+ "The closed date, Y-m-d.": "Datum uzavření, Y-m-d.",
+ "The holiday's name.": "Název svátku.",
+ "The ladder's stable name, referenced by a timer's ladder_slug.": "Stálý název žebříku, na který časovač odkazuje přes ladder_slug.",
+ "The unit of the offset: the same set the SLA accepts.": "Jednotka odstupu: stejná množina, jakou přijímá SLA.",
+ "The urgency the raised transition carries.": "Naléhavost, kterou nese vyvolaný přechod.",
+ "The weekday (name) on which the date shifts, e.g. sunday for Koningsdag.": "Den v týdnu (název), při kterém se datum přesune, např. sunday pro Koningsdag.",
+ "UUID of the organisation this calendar is configured for. Empty for a shared calendar. The resolution order picks an organisation's calendar when the timer names none.": "UUID organizace, pro kterou je tento kalendář nastaven. Prázdné u sdíleného kalendáře. Nejmenuje-li časovač žádný, pořadí rozlišení vybere kalendář organizace.",
+ "UUID of the organisation this ladder is the default for. Empty for the shared default.": "UUID organizace, pro kterou je tento žebřík výchozí. Prázdné u sdíleného výchozího.",
+ "When weekday": "Připadne-li na",
+ "Whether reaching this rung opens an incident.": "Zda dosažení této příčky otevře incident.",
+ "Why the day is closed.": "Proč je den uzavřen.",
+ "Working calendar": "Pracovní kalendář",
+ "Working hours in one working day. Makes hours and businessDays commensurable.": "Odpracované hodiny v jednom pracovním dni. Činí hodiny a pracovní dny srovnatelnými.",
+ "Working weekdays": "Pracovní dny v týdnu",
+ "fixed: a month/day; easter: an offset in days from Easter Sunday; observedShift: a month/day with a required observed shift.": "fixed: měsíc a den; easter: odstup ve dnech od Velikonoční neděle; observedShift: měsíc a den s povinným přesunem.",
+ "preBreach fires before the deadline, slaBreached at or after it.": "preBreach se spouští před lhůtou, slaBreached ve lhůtě nebo po ní.",
+ "No such task": "Žádný takový úkol",
+ "The task does not exist, or it is not yours to see.": "Úkol neexistuje, nebo ho nesmíte vidět.",
+ "Details": "Podrobnosti",
+ "Due": "Termín",
+ "Assignee": "Přiřazeno",
+ "Requested by": "Vyžádal",
+ "Outcome": "Výsledek",
+ "Ready to claim": "Připraveno k převzetí",
+ "In progress": "Probíhá",
+ "Terminated": "Ukončeno",
+ "Normal": "Normální",
+ "Urgent": "Naléhavé",
+ "Overdue by 1 day": "1 den po termínu",
+ "Overdue by {days} days": "{days} dní po termínu",
+ "Due today": "Termín dnes",
+ "Due tomorrow": "Termín zítra",
+ "Due in {days} days": "Termín za {days} dní",
+ "Tasks": "Úkoly",
+ "Task": "Úkol",
+ "Unassigned, open for claiming": "Nepřiřazeno, lze převzít",
+ "Claim": "Převzít",
+ "Complete": "Dokončit",
+ "Complete: {outcome}": "Dokončit: {outcome}",
+ "Could not load the task": "Úkol se nepodařilo načíst",
+ "The task refused that action": "Úkol tuto akci odmítl"
},
"nplurals=4; plural=(n == 1 && n % 1 == 0) ? 0 : (n >= 2 && n <= 4 && n % 1 == 0) ? 1: (n % 1 != 0 ) ? 2 : 3;"
)
diff --git a/l10n/cs.json b/l10n/cs.json
index e17ef21bad..636fd9a1e7 100644
--- a/l10n/cs.json
+++ b/l10n/cs.json
@@ -1,10 +1,20 @@
{
"translations": {
+ "from amount {amount}": "od částky {amount}",
+ "Gated transition: {transition}": "Hlídaný přechod: {transition}",
+ "Each declared chain provisions an ordered task sequence when its transition is attempted. Approvers decide in their task inbox, not here.": "Každý deklarovaný řetězec otevře uspořádanou sekvenci úkolů při pokusu o přechod. Schvalovatelé rozhodují ve své schránce úkolů, ne zde.",
+ "Declare x-openregister-approval-chains on this schema to gate a lifecycle transition on approval.": "Deklarujte x-openregister-approval-chains na tomto schématu, aby přechod životního cyklu podléhal schválení.",
+ "Approval sequences": "Schvalovací sekvence",
"%n entries have no hash yet": "%n záznamů zatím nemá otisk",
"%n entry has no hash yet": "%n záznam zatím nemá otisk",
"(Dolphin required)": "(vyžaduje Dolphin)",
+ "No approval chains declared": "Nejsou deklarovány žádné schvalovací řetězce",
"(no subject)": "(bez předmětu)",
"(no title)": "(bez názvu)",
+ "Role {role}": "Role {role}",
+ "The transition is applied automatically once every step approves.": "Přechod se použije automaticky, jakmile je každý krok schválen.",
+ "The requester may not decide their own approval.": "Žadatel nesmí rozhodovat o vlastním schválení.",
+ "Tier routing on field: {field}": "Směrování podle pásem přes pole: {field}",
"(unnamed)": "(bez názvu)",
"(untitled card)": "(karta bez názvu)",
"({count} selected)": "({count} vybráno)",
@@ -2817,7 +2827,84 @@
"Úspěšně obnoveny {count} objekty",
"Úspěšně obnoveno {count} objektu",
"Úspěšně obnoveno {count} objektů"
- ]
+ ],
+ "A message identity the notification subsystem resolves.": "Identita zprávy, kterou rozliší systém upozornění.",
+ "Computed non-working-date rules. kind fixed: {month, day, name, observedShift?: {whenWeekday, days}}. kind easter: {offset, name}, offset in days from Easter Sunday. kind observedShift: a fixed date with a required shift.": "Vypočítaná pravidla nepracovních dnů. Druh fixed: {month, day, name, observedShift?: {whenWeekday, days}}. Druh easter: {offset, name}, odstup ve dnech od Velikonoční neděle. Druh observedShift: pevné datum s povinným přesunem.",
+ "Date": "Datum",
+ "Day": "Den",
+ "Day of a fixed or observedShift rule; ignored by an easter rule.": "Den pravidla fixed nebo observedShift; pravidlo easter jej ignoruje.",
+ "Days": "Dny",
+ "Days from Easter Sunday for an easter rule; ignored by the other kinds.": "Dny od Velikonoční neděle pro pravidlo easter; ostatní druhy je ignorují.",
+ "Distance from the deadline, in the offset unit.": "Vzdálenost od lhůty v jednotce odstupu.",
+ "Enumerated one-off closures as {date, name}. Allowed alongside rules; refused as the whole calendar.": "Jednorázová uzavření vyjmenovaná jako {date, name}. Povolena vedle pravidel; odmítnuta jako celý kalendář.",
+ "Escalate to roles": "Role pro eskalaci",
+ "Escalation ladder": "Eskalační žebřík",
+ "Exception dates": "Výjimečná data",
+ "Hours per working day": "Hodin na pracovní den",
+ "How many days the observed date shifts, e.g. -1 for the Saturday before.": "O kolik dnů se slavené datum přesune, např. -1 pro předchozí sobotu.",
+ "Human-readable title.": "Čitelný název.",
+ "ISO weekdays (1 = Monday, 7 = Sunday) that are working days.": "ISO dny v týdnu (1 = pondělí, 7 = neděle), které jsou pracovní.",
+ "Kind": "Druh",
+ "Message": "Zpráva",
+ "Month": "Měsíc",
+ "Month of a fixed or observedShift rule; ignored by an easter rule.": "Měsíc pravidla fixed nebo observedShift; pravidlo easter jej ignoruje.",
+ "Non-working-date rules": "Pravidla nepracovních dnů",
+ "Notify roles": "Role k upozornění",
+ "Observed shift": "Přesun svátku",
+ "Offset": "Odstup",
+ "Offset unit": "Jednotka odstupu",
+ "Open incident": "Otevřít incident",
+ "Optional map from a role name to a concrete recipient descriptor, e.g. {\"teamleader\": \"group:teamleaders\"}. Roles without a binding travel unresolved as role:.": "Volitelná mapa z názvu role na konkrétního příjemce, např. {\"teamleader\": \"group:teamleaders\"}. Role bez vazby putují nerozlišené jako role:.",
+ "Optional on a fixed rule, required on observedShift: {whenWeekday: weekday name or ISO 1..7, days: integer}.": "Volitelné u pravidla fixed, povinné u observedShift: {whenWeekday: název dne nebo ISO 1..7, days: celé číslo}.",
+ "Ordered rungs: {key, trigger (preBreach|slaBreached), offset, offsetUnit (hours|businessDays|calendarDays), notifyRole[], escalateToRole[], priority, message, openIncident}.": "Seřazené příčky: {key, trigger (preBreach|slaBreached), offset, offsetUnit (hours|businessDays|calendarDays), notifyRole[], escalateToRole[], priority, message, openIncident}.",
+ "Priority": "Priorita",
+ "Role bindings": "Vazby rolí",
+ "Roles the matter is escalated to at this rung.": "Role, na které se věc na této příčce eskaluje.",
+ "Roles told at this rung; handler is the subject's own performer.": "Role upozorněné na této příčce; handler je osoba, která věc vyřizuje.",
+ "Rungs": "Příčky",
+ "Stable rung identity, e.g. preBreach:14:calendarDays; derived from trigger, offset and unit when absent.": "Stálá identita příčky, např. preBreach:14:calendarDays; chybí-li, odvodí se ze spouštěče, odstupu a jednotky.",
+ "The calendar's stable name, referenced by a timer's calendar_slug.": "Stálý název kalendáře, na který časovač odkazuje přes calendar_slug.",
+ "The closed date, Y-m-d.": "Datum uzavření, Y-m-d.",
+ "The holiday's name.": "Název svátku.",
+ "The ladder's stable name, referenced by a timer's ladder_slug.": "Stálý název žebříku, na který časovač odkazuje přes ladder_slug.",
+ "The unit of the offset: the same set the SLA accepts.": "Jednotka odstupu: stejná množina, jakou přijímá SLA.",
+ "The urgency the raised transition carries.": "Naléhavost, kterou nese vyvolaný přechod.",
+ "The weekday (name) on which the date shifts, e.g. sunday for Koningsdag.": "Den v týdnu (název), při kterém se datum přesune, např. sunday pro Koningsdag.",
+ "UUID of the organisation this calendar is configured for. Empty for a shared calendar. The resolution order picks an organisation's calendar when the timer names none.": "UUID organizace, pro kterou je tento kalendář nastaven. Prázdné u sdíleného kalendáře. Nejmenuje-li časovač žádný, pořadí rozlišení vybere kalendář organizace.",
+ "UUID of the organisation this ladder is the default for. Empty for the shared default.": "UUID organizace, pro kterou je tento žebřík výchozí. Prázdné u sdíleného výchozího.",
+ "When weekday": "Připadne-li na",
+ "Whether reaching this rung opens an incident.": "Zda dosažení této příčky otevře incident.",
+ "Why the day is closed.": "Proč je den uzavřen.",
+ "Working calendar": "Pracovní kalendář",
+ "Working hours in one working day. Makes hours and businessDays commensurable.": "Odpracované hodiny v jednom pracovním dni. Činí hodiny a pracovní dny srovnatelnými.",
+ "Working weekdays": "Pracovní dny v týdnu",
+ "fixed: a month/day; easter: an offset in days from Easter Sunday; observedShift: a month/day with a required observed shift.": "fixed: měsíc a den; easter: odstup ve dnech od Velikonoční neděle; observedShift: měsíc a den s povinným přesunem.",
+ "preBreach fires before the deadline, slaBreached at or after it.": "preBreach se spouští před lhůtou, slaBreached ve lhůtě nebo po ní.",
+ "No such task": "Žádný takový úkol",
+ "The task does not exist, or it is not yours to see.": "Úkol neexistuje, nebo ho nesmíte vidět.",
+ "Details": "Podrobnosti",
+ "Due": "Termín",
+ "Assignee": "Přiřazeno",
+ "Requested by": "Vyžádal",
+ "Outcome": "Výsledek",
+ "Ready to claim": "Připraveno k převzetí",
+ "In progress": "Probíhá",
+ "Terminated": "Ukončeno",
+ "Normal": "Normální",
+ "Urgent": "Naléhavé",
+ "Overdue by 1 day": "1 den po termínu",
+ "Overdue by {days} days": "{days} dní po termínu",
+ "Due today": "Termín dnes",
+ "Due tomorrow": "Termín zítra",
+ "Due in {days} days": "Termín za {days} dní",
+ "Tasks": "Úkoly",
+ "Task": "Úkol",
+ "Unassigned, open for claiming": "Nepřiřazeno, lze převzít",
+ "Claim": "Převzít",
+ "Complete": "Dokončit",
+ "Complete: {outcome}": "Dokončit: {outcome}",
+ "Could not load the task": "Úkol se nepodařilo načíst",
+ "The task refused that action": "Úkol tuto akci odmítl"
},
"pluralForm": "nplurals=4; plural=(n == 1 && n % 1 == 0) ? 0 : (n >= 2 && n <= 4 && n % 1 == 0) ? 1: (n % 1 != 0 ) ? 2 : 3;",
"plurals": {
diff --git a/l10n/da.js b/l10n/da.js
index be8ae25bd3..7e693a84bf 100644
--- a/l10n/da.js
+++ b/l10n/da.js
@@ -3,11 +3,21 @@ OC.L10N.register(
{
"3": "3",
"30": "30",
+ "from amount {amount}": "fra beløb {amount}",
+ "Gated transition: {transition}": "Overvåget overgang: {transition}",
+ "Each declared chain provisions an ordered task sequence when its transition is attempted. Approvers decide in their task inbox, not here.": "Hver deklareret kæde åbner en ordnet opgavesekvens, når overgangen forsøges. Godkendere beslutter i deres opgaveindbakke, ikke her.",
+ "Declare x-openregister-approval-chains on this schema to gate a lifecycle transition on approval.": "Deklarér x-openregister-approval-chains på dette skema for at kræve godkendelse før en livscyklusovergang.",
+ "Approval sequences": "Godkendelsessekvenser",
"%n entries have no hash yet": "%n poster har endnu ingen hash",
"%n entry has no hash yet": "%n post har endnu ingen hash",
"(Dolphin required)": "(Dolphin påkrævet)",
+ "No approval chains declared": "Ingen godkendelseskæder deklareret",
"(no subject)": "(intet emne)",
"(no title)": "(ingen titel)",
+ "Role {role}": "Rolle {role}",
+ "The transition is applied automatically once every step approves.": "Overgangen anvendes automatisk, når hvert trin er godkendt.",
+ "The requester may not decide their own approval.": "Anmoderen må ikke afgøre sin egen godkendelse.",
+ "Tier routing on field: {field}": "Trinvis routing på feltet: {field}",
"(unnamed)": "(uden navn)",
"(untitled card)": "(kort uden titel)",
"({count} selected)": "({count} valgt)",
@@ -2738,7 +2748,84 @@ OC.L10N.register(
"_Object successfully deleted_::_Objects successfully deleted_": ["Objekt slettet","Objekter slettet"],
"_Purge {count} object from database_::_Purge {count} objects from database_": ["Ryd {count} objekt fra databasen","Ryd {count} objekter fra databasen"],
"_Restore {count} object_::_Restore {count} objects_": ["Gendan {count} objekt","Gendan {count} objekter"],
- "_Successfully restored {count} object_::_Successfully restored {count} objects_": ["{count} objekt gendannet","{count} objekter gendannet"]
+ "_Successfully restored {count} object_::_Successfully restored {count} objects_": ["{count} objekt gendannet","{count} objekter gendannet"],
+ "A message identity the notification subsystem resolves.": "A message identity the notification subsystem resolves.",
+ "Computed non-working-date rules. kind fixed: {month, day, name, observedShift?: {whenWeekday, days}}. kind easter: {offset, name}, offset in days from Easter Sunday. kind observedShift: a fixed date with a required shift.": "Computed non-working-date rules. kind fixed: {month, day, name, observedShift?: {whenWeekday, days}}. kind easter: {offset, name}, offset in days from Easter Sunday. kind observedShift: a fixed date with a required shift.",
+ "Date": "Date",
+ "Day": "Day",
+ "Day of a fixed or observedShift rule; ignored by an easter rule.": "Day of a fixed or observedShift rule; ignored by an easter rule.",
+ "Days": "Days",
+ "Days from Easter Sunday for an easter rule; ignored by the other kinds.": "Days from Easter Sunday for an easter rule; ignored by the other kinds.",
+ "Distance from the deadline, in the offset unit.": "Distance from the deadline, in the offset unit.",
+ "Enumerated one-off closures as {date, name}. Allowed alongside rules; refused as the whole calendar.": "Enumerated one-off closures as {date, name}. Allowed alongside rules; refused as the whole calendar.",
+ "Escalate to roles": "Escalate to roles",
+ "Escalation ladder": "Escalation ladder",
+ "Exception dates": "Exception dates",
+ "Hours per working day": "Hours per working day",
+ "How many days the observed date shifts, e.g. -1 for the Saturday before.": "How many days the observed date shifts, e.g. -1 for the Saturday before.",
+ "Human-readable title.": "Human-readable title.",
+ "ISO weekdays (1 = Monday, 7 = Sunday) that are working days.": "ISO weekdays (1 = Monday, 7 = Sunday) that are working days.",
+ "Kind": "Kind",
+ "Message": "Message",
+ "Month": "Month",
+ "Month of a fixed or observedShift rule; ignored by an easter rule.": "Month of a fixed or observedShift rule; ignored by an easter rule.",
+ "Non-working-date rules": "Non-working-date rules",
+ "Notify roles": "Notify roles",
+ "Observed shift": "Observed shift",
+ "Offset": "Offset",
+ "Offset unit": "Offset unit",
+ "Open incident": "Open incident",
+ "Optional map from a role name to a concrete recipient descriptor, e.g. {\"teamleader\": \"group:teamleaders\"}. Roles without a binding travel unresolved as role:.": "Optional map from a role name to a concrete recipient descriptor, e.g. {\"teamleader\": \"group:teamleaders\"}. Roles without a binding travel unresolved as role:.",
+ "Optional on a fixed rule, required on observedShift: {whenWeekday: weekday name or ISO 1..7, days: integer}.": "Optional on a fixed rule, required on observedShift: {whenWeekday: weekday name or ISO 1..7, days: integer}.",
+ "Ordered rungs: {key, trigger (preBreach|slaBreached), offset, offsetUnit (hours|businessDays|calendarDays), notifyRole[], escalateToRole[], priority, message, openIncident}.": "Ordered rungs: {key, trigger (preBreach|slaBreached), offset, offsetUnit (hours|businessDays|calendarDays), notifyRole[], escalateToRole[], priority, message, openIncident}.",
+ "Priority": "Priority",
+ "Role bindings": "Role bindings",
+ "Roles the matter is escalated to at this rung.": "Roles the matter is escalated to at this rung.",
+ "Roles told at this rung; handler is the subject's own performer.": "Roles told at this rung; handler is the subject's own performer.",
+ "Rungs": "Rungs",
+ "Stable rung identity, e.g. preBreach:14:calendarDays; derived from trigger, offset and unit when absent.": "Stable rung identity, e.g. preBreach:14:calendarDays; derived from trigger, offset and unit when absent.",
+ "The calendar's stable name, referenced by a timer's calendar_slug.": "The calendar's stable name, referenced by a timer's calendar_slug.",
+ "The closed date, Y-m-d.": "The closed date, Y-m-d.",
+ "The holiday's name.": "The holiday's name.",
+ "The ladder's stable name, referenced by a timer's ladder_slug.": "The ladder's stable name, referenced by a timer's ladder_slug.",
+ "The unit of the offset: the same set the SLA accepts.": "The unit of the offset: the same set the SLA accepts.",
+ "The urgency the raised transition carries.": "The urgency the raised transition carries.",
+ "The weekday (name) on which the date shifts, e.g. sunday for Koningsdag.": "The weekday (name) on which the date shifts, e.g. sunday for Koningsdag.",
+ "UUID of the organisation this calendar is configured for. Empty for a shared calendar. The resolution order picks an organisation's calendar when the timer names none.": "UUID of the organisation this calendar is configured for. Empty for a shared calendar. The resolution order picks an organisation's calendar when the timer names none.",
+ "UUID of the organisation this ladder is the default for. Empty for the shared default.": "UUID of the organisation this ladder is the default for. Empty for the shared default.",
+ "When weekday": "When weekday",
+ "Whether reaching this rung opens an incident.": "Whether reaching this rung opens an incident.",
+ "Why the day is closed.": "Why the day is closed.",
+ "Working calendar": "Working calendar",
+ "Working hours in one working day. Makes hours and businessDays commensurable.": "Working hours in one working day. Makes hours and businessDays commensurable.",
+ "Working weekdays": "Working weekdays",
+ "fixed: a month/day; easter: an offset in days from Easter Sunday; observedShift: a month/day with a required observed shift.": "fixed: a month/day; easter: an offset in days from Easter Sunday; observedShift: a month/day with a required observed shift.",
+ "preBreach fires before the deadline, slaBreached at or after it.": "preBreach fires before the deadline, slaBreached at or after it.",
+ "No such task": "Ingen sådan opgave",
+ "The task does not exist, or it is not yours to see.": "Opgaven findes ikke, eller du må ikke se den.",
+ "Details": "Detaljer",
+ "Due": "Frist",
+ "Assignee": "Tildelt",
+ "Requested by": "Anmodet af",
+ "Outcome": "Resultat",
+ "Ready to claim": "Klar til at overtage",
+ "In progress": "I gang",
+ "Terminated": "Afbrudt",
+ "Normal": "Normal",
+ "Urgent": "Haster",
+ "Overdue by 1 day": "1 dag over fristen",
+ "Overdue by {days} days": "{days} dage over fristen",
+ "Due today": "Frist i dag",
+ "Due tomorrow": "Frist i morgen",
+ "Due in {days} days": "Frist om {days} dage",
+ "Tasks": "Opgaver",
+ "Task": "Opgave",
+ "Unassigned, open for claiming": "Ikke tildelt, åben for overtagelse",
+ "Claim": "Overtag",
+ "Complete": "Fuldfør",
+ "Complete: {outcome}": "Fuldfør: {outcome}",
+ "Could not load the task": "Kunne ikke indlæse opgaven",
+ "The task refused that action": "Opgaven afviste den handling"
},
"nplurals=2; plural=(n != 1);"
)
diff --git a/l10n/da.json b/l10n/da.json
index e0292c88a9..205de37c27 100644
--- a/l10n/da.json
+++ b/l10n/da.json
@@ -1,10 +1,20 @@
{
"translations": {
+ "from amount {amount}": "fra beløb {amount}",
+ "Gated transition: {transition}": "Overvåget overgang: {transition}",
+ "Each declared chain provisions an ordered task sequence when its transition is attempted. Approvers decide in their task inbox, not here.": "Hver deklareret kæde åbner en ordnet opgavesekvens, når overgangen forsøges. Godkendere beslutter i deres opgaveindbakke, ikke her.",
+ "Declare x-openregister-approval-chains on this schema to gate a lifecycle transition on approval.": "Deklarér x-openregister-approval-chains på dette skema for at kræve godkendelse før en livscyklusovergang.",
+ "Approval sequences": "Godkendelsessekvenser",
"%n entries have no hash yet": "%n poster har endnu ingen hash",
"%n entry has no hash yet": "%n post har endnu ingen hash",
"(Dolphin required)": "(Dolphin påkrævet)",
+ "No approval chains declared": "Ingen godkendelseskæder deklareret",
"(no subject)": "(intet emne)",
"(no title)": "(ingen titel)",
+ "Role {role}": "Rolle {role}",
+ "The transition is applied automatically once every step approves.": "Overgangen anvendes automatisk, når hvert trin er godkendt.",
+ "The requester may not decide their own approval.": "Anmoderen må ikke afgøre sin egen godkendelse.",
+ "Tier routing on field: {field}": "Trinvis routing på feltet: {field}",
"(unnamed)": "(uden navn)",
"(untitled card)": "(kort uden titel)",
"({count} selected)": "({count} valgt)",
@@ -2785,7 +2795,84 @@
"_Successfully restored {count} object_::_Successfully restored {count} objects_": [
"{count} objekt gendannet",
"{count} objekter gendannet"
- ]
+ ],
+ "A message identity the notification subsystem resolves.": "A message identity the notification subsystem resolves.",
+ "Computed non-working-date rules. kind fixed: {month, day, name, observedShift?: {whenWeekday, days}}. kind easter: {offset, name}, offset in days from Easter Sunday. kind observedShift: a fixed date with a required shift.": "Computed non-working-date rules. kind fixed: {month, day, name, observedShift?: {whenWeekday, days}}. kind easter: {offset, name}, offset in days from Easter Sunday. kind observedShift: a fixed date with a required shift.",
+ "Date": "Date",
+ "Day": "Day",
+ "Day of a fixed or observedShift rule; ignored by an easter rule.": "Day of a fixed or observedShift rule; ignored by an easter rule.",
+ "Days": "Days",
+ "Days from Easter Sunday for an easter rule; ignored by the other kinds.": "Days from Easter Sunday for an easter rule; ignored by the other kinds.",
+ "Distance from the deadline, in the offset unit.": "Distance from the deadline, in the offset unit.",
+ "Enumerated one-off closures as {date, name}. Allowed alongside rules; refused as the whole calendar.": "Enumerated one-off closures as {date, name}. Allowed alongside rules; refused as the whole calendar.",
+ "Escalate to roles": "Escalate to roles",
+ "Escalation ladder": "Escalation ladder",
+ "Exception dates": "Exception dates",
+ "Hours per working day": "Hours per working day",
+ "How many days the observed date shifts, e.g. -1 for the Saturday before.": "How many days the observed date shifts, e.g. -1 for the Saturday before.",
+ "Human-readable title.": "Human-readable title.",
+ "ISO weekdays (1 = Monday, 7 = Sunday) that are working days.": "ISO weekdays (1 = Monday, 7 = Sunday) that are working days.",
+ "Kind": "Kind",
+ "Message": "Message",
+ "Month": "Month",
+ "Month of a fixed or observedShift rule; ignored by an easter rule.": "Month of a fixed or observedShift rule; ignored by an easter rule.",
+ "Non-working-date rules": "Non-working-date rules",
+ "Notify roles": "Notify roles",
+ "Observed shift": "Observed shift",
+ "Offset": "Offset",
+ "Offset unit": "Offset unit",
+ "Open incident": "Open incident",
+ "Optional map from a role name to a concrete recipient descriptor, e.g. {\"teamleader\": \"group:teamleaders\"}. Roles without a binding travel unresolved as role:.": "Optional map from a role name to a concrete recipient descriptor, e.g. {\"teamleader\": \"group:teamleaders\"}. Roles without a binding travel unresolved as role:.",
+ "Optional on a fixed rule, required on observedShift: {whenWeekday: weekday name or ISO 1..7, days: integer}.": "Optional on a fixed rule, required on observedShift: {whenWeekday: weekday name or ISO 1..7, days: integer}.",
+ "Ordered rungs: {key, trigger (preBreach|slaBreached), offset, offsetUnit (hours|businessDays|calendarDays), notifyRole[], escalateToRole[], priority, message, openIncident}.": "Ordered rungs: {key, trigger (preBreach|slaBreached), offset, offsetUnit (hours|businessDays|calendarDays), notifyRole[], escalateToRole[], priority, message, openIncident}.",
+ "Priority": "Priority",
+ "Role bindings": "Role bindings",
+ "Roles the matter is escalated to at this rung.": "Roles the matter is escalated to at this rung.",
+ "Roles told at this rung; handler is the subject's own performer.": "Roles told at this rung; handler is the subject's own performer.",
+ "Rungs": "Rungs",
+ "Stable rung identity, e.g. preBreach:14:calendarDays; derived from trigger, offset and unit when absent.": "Stable rung identity, e.g. preBreach:14:calendarDays; derived from trigger, offset and unit when absent.",
+ "The calendar's stable name, referenced by a timer's calendar_slug.": "The calendar's stable name, referenced by a timer's calendar_slug.",
+ "The closed date, Y-m-d.": "The closed date, Y-m-d.",
+ "The holiday's name.": "The holiday's name.",
+ "The ladder's stable name, referenced by a timer's ladder_slug.": "The ladder's stable name, referenced by a timer's ladder_slug.",
+ "The unit of the offset: the same set the SLA accepts.": "The unit of the offset: the same set the SLA accepts.",
+ "The urgency the raised transition carries.": "The urgency the raised transition carries.",
+ "The weekday (name) on which the date shifts, e.g. sunday for Koningsdag.": "The weekday (name) on which the date shifts, e.g. sunday for Koningsdag.",
+ "UUID of the organisation this calendar is configured for. Empty for a shared calendar. The resolution order picks an organisation's calendar when the timer names none.": "UUID of the organisation this calendar is configured for. Empty for a shared calendar. The resolution order picks an organisation's calendar when the timer names none.",
+ "UUID of the organisation this ladder is the default for. Empty for the shared default.": "UUID of the organisation this ladder is the default for. Empty for the shared default.",
+ "When weekday": "When weekday",
+ "Whether reaching this rung opens an incident.": "Whether reaching this rung opens an incident.",
+ "Why the day is closed.": "Why the day is closed.",
+ "Working calendar": "Working calendar",
+ "Working hours in one working day. Makes hours and businessDays commensurable.": "Working hours in one working day. Makes hours and businessDays commensurable.",
+ "Working weekdays": "Working weekdays",
+ "fixed: a month/day; easter: an offset in days from Easter Sunday; observedShift: a month/day with a required observed shift.": "fixed: a month/day; easter: an offset in days from Easter Sunday; observedShift: a month/day with a required observed shift.",
+ "preBreach fires before the deadline, slaBreached at or after it.": "preBreach fires before the deadline, slaBreached at or after it.",
+ "No such task": "Ingen sådan opgave",
+ "The task does not exist, or it is not yours to see.": "Opgaven findes ikke, eller du må ikke se den.",
+ "Details": "Detaljer",
+ "Due": "Frist",
+ "Assignee": "Tildelt",
+ "Requested by": "Anmodet af",
+ "Outcome": "Resultat",
+ "Ready to claim": "Klar til at overtage",
+ "In progress": "I gang",
+ "Terminated": "Afbrudt",
+ "Normal": "Normal",
+ "Urgent": "Haster",
+ "Overdue by 1 day": "1 dag over fristen",
+ "Overdue by {days} days": "{days} dage over fristen",
+ "Due today": "Frist i dag",
+ "Due tomorrow": "Frist i morgen",
+ "Due in {days} days": "Frist om {days} dage",
+ "Tasks": "Opgaver",
+ "Task": "Opgave",
+ "Unassigned, open for claiming": "Ikke tildelt, åben for overtagelse",
+ "Claim": "Overtag",
+ "Complete": "Fuldfør",
+ "Complete: {outcome}": "Fuldfør: {outcome}",
+ "Could not load the task": "Kunne ikke indlæse opgaven",
+ "The task refused that action": "Opgaven afviste den handling"
},
"pluralForm": "nplurals=2; plural=(n != 1);",
"plurals": {
diff --git a/l10n/de.js b/l10n/de.js
index d862152ac3..a027d06df5 100644
--- a/l10n/de.js
+++ b/l10n/de.js
@@ -3,11 +3,21 @@ OC.L10N.register(
{
"3": "3",
"30": "30",
+ "from amount {amount}": "ab Betrag {amount}",
+ "Gated transition: {transition}": "Bewachter Übergang: {transition}",
+ "Each declared chain provisions an ordered task sequence when its transition is attempted. Approvers decide in their task inbox, not here.": "Jede deklarierte Kette eröffnet beim Versuch des Übergangs eine geordnete Aufgabensequenz. Freigebende entscheiden in ihrem Aufgabeneingang, nicht hier.",
+ "Declare x-openregister-approval-chains on this schema to gate a lifecycle transition on approval.": "Deklarieren Sie x-openregister-approval-chains auf diesem Schema, um einen Lebenszyklusübergang hinter eine Freigabe zu stellen.",
+ "Approval sequences": "Freigabesequenzen",
"%n entries have no hash yet": "%n Einträge haben noch keinen Hash",
"%n entry has no hash yet": "%n Eintrag hat noch keinen Hash",
"(Dolphin required)": "(Dolphin erforderlich)",
+ "No approval chains declared": "Keine Freigabeketten deklariert",
"(no subject)": "(kein Betreff)",
"(no title)": "(kein Titel)",
+ "Role {role}": "Rolle {role}",
+ "The transition is applied automatically once every step approves.": "Der Übergang wird automatisch angewendet, sobald jeder Schritt freigegeben ist.",
+ "The requester may not decide their own approval.": "Wer den Antrag stellt, darf nicht über die eigene Freigabe entscheiden.",
+ "Tier routing on field: {field}": "Stufen-Routing über Feld: {field}",
"(unnamed)": "(unbenannt)",
"(untitled card)": "(unbenannte Karte)",
"({count} selected)": "({count} ausgewählt)",
@@ -2738,7 +2748,84 @@ OC.L10N.register(
"_Object successfully deleted_::_Objects successfully deleted_": ["Objekt erfolgreich gelöscht","Objekte erfolgreich gelöscht"],
"_Purge {count} object from database_::_Purge {count} objects from database_": ["{count} Objekt aus der Datenbank bereinigen","{count} Objekte aus der Datenbank bereinigen"],
"_Restore {count} object_::_Restore {count} objects_": ["{count} Objekt wiederherstellen","{count} Objekte wiederherstellen"],
- "_Successfully restored {count} object_::_Successfully restored {count} objects_": ["{count} Objekt erfolgreich wiederhergestellt","{count} Objekte erfolgreich wiederhergestellt"]
+ "_Successfully restored {count} object_::_Successfully restored {count} objects_": ["{count} Objekt erfolgreich wiederhergestellt","{count} Objekte erfolgreich wiederhergestellt"],
+ "A message identity the notification subsystem resolves.": "Eine Nachrichtenkennung, die das Benachrichtigungssystem auflöst.",
+ "Computed non-working-date rules. kind fixed: {month, day, name, observedShift?: {whenWeekday, days}}. kind easter: {offset, name}, offset in days from Easter Sunday. kind observedShift: a fixed date with a required shift.": "Berechnete Regeln für arbeitsfreie Tage. Art fixed: {month, day, name, observedShift?: {whenWeekday, days}}. Art easter: {offset, name}, Abstand in Tagen ab Ostersonntag. Art observedShift: ein festes Datum mit vorgeschriebener Verschiebung.",
+ "Date": "Datum",
+ "Day": "Tag",
+ "Day of a fixed or observedShift rule; ignored by an easter rule.": "Tag einer fixed- oder observedShift-Regel; eine easter-Regel ignoriert ihn.",
+ "Days": "Tage",
+ "Days from Easter Sunday for an easter rule; ignored by the other kinds.": "Tage ab Ostersonntag für eine easter-Regel; die anderen Arten ignorieren sie.",
+ "Distance from the deadline, in the offset unit.": "Abstand zur Frist, in der gewählten Einheit.",
+ "Enumerated one-off closures as {date, name}. Allowed alongside rules; refused as the whole calendar.": "Einzelne Schließtage als {date, name}. Neben Regeln zulässig; als ganzer Kalender abgelehnt.",
+ "Escalate to roles": "Eskalation an Rollen",
+ "Escalation ladder": "Eskalationsleiter",
+ "Exception dates": "Ausnahmetage",
+ "Hours per working day": "Stunden pro Arbeitstag",
+ "How many days the observed date shifts, e.g. -1 for the Saturday before.": "Um wie viele Tage der begangene Tag verschoben wird, z. B. -1 für den Samstag davor.",
+ "Human-readable title.": "Lesbarer Titel.",
+ "ISO weekdays (1 = Monday, 7 = Sunday) that are working days.": "ISO-Wochentage (1 = Montag, 7 = Sonntag), die Arbeitstage sind.",
+ "Kind": "Art",
+ "Message": "Nachricht",
+ "Month": "Monat",
+ "Month of a fixed or observedShift rule; ignored by an easter rule.": "Monat einer fixed- oder observedShift-Regel; eine easter-Regel ignoriert ihn.",
+ "Non-working-date rules": "Regeln für arbeitsfreie Tage",
+ "Notify roles": "Zu benachrichtigende Rollen",
+ "Observed shift": "Verschobener Feiertag",
+ "Offset": "Abstand",
+ "Offset unit": "Einheit des Abstands",
+ "Open incident": "Vorfall eröffnen",
+ "Optional map from a role name to a concrete recipient descriptor, e.g. {\"teamleader\": \"group:teamleaders\"}. Roles without a binding travel unresolved as role:.": "Optionale Zuordnung eines Rollennamens zu einem konkreten Empfänger, z. B. {\"teamleader\": \"group:teamleaders\"}. Rollen ohne Zuordnung reisen unaufgelöst als role: weiter.",
+ "Optional on a fixed rule, required on observedShift: {whenWeekday: weekday name or ISO 1..7, days: integer}.": "Optional bei einer fixed-Regel, verpflichtend bei observedShift: {whenWeekday: Name des Wochentags oder ISO 1..7, days: ganze Zahl}.",
+ "Ordered rungs: {key, trigger (preBreach|slaBreached), offset, offsetUnit (hours|businessDays|calendarDays), notifyRole[], escalateToRole[], priority, message, openIncident}.": "Geordnete Stufen: {key, trigger (preBreach|slaBreached), offset, offsetUnit (hours|businessDays|calendarDays), notifyRole[], escalateToRole[], priority, message, openIncident}.",
+ "Priority": "Priorität",
+ "Role bindings": "Rollenzuordnungen",
+ "Roles the matter is escalated to at this rung.": "Rollen, an die auf dieser Stufe eskaliert wird.",
+ "Roles told at this rung; handler is the subject's own performer.": "Rollen, die auf dieser Stufe benachrichtigt werden; handler ist die Bearbeiterin oder der Bearbeiter des Vorgangs.",
+ "Rungs": "Stufen",
+ "Stable rung identity, e.g. preBreach:14:calendarDays; derived from trigger, offset and unit when absent.": "Feste Kennung der Stufe, z. B. preBreach:14:calendarDays; fehlt sie, wird sie aus Auslöser, Abstand und Einheit abgeleitet.",
+ "The calendar's stable name, referenced by a timer's calendar_slug.": "Der feste Name des Kalenders, auf den ein Timer über calendar_slug verweist.",
+ "The closed date, Y-m-d.": "Der geschlossene Tag, Y-m-d.",
+ "The holiday's name.": "Der Name des Feiertags.",
+ "The ladder's stable name, referenced by a timer's ladder_slug.": "Der feste Name der Leiter, auf die ein Timer über ladder_slug verweist.",
+ "The unit of the offset: the same set the SLA accepts.": "Die Einheit des Abstands: dieselben Werte, die das SLA akzeptiert.",
+ "The urgency the raised transition carries.": "Die Dringlichkeit, die der ausgelöste Übergang trägt.",
+ "The weekday (name) on which the date shifts, e.g. sunday for Koningsdag.": "Der Wochentag (Name), an dem das Datum verschoben wird, z. B. sunday für Koningsdag.",
+ "UUID of the organisation this calendar is configured for. Empty for a shared calendar. The resolution order picks an organisation's calendar when the timer names none.": "UUID der Organisation, für die dieser Kalender eingerichtet ist. Leer bei einem gemeinsamen Kalender. Nennt der Timer keinen Kalender, wählt die Auflösungsreihenfolge den Kalender der Organisation.",
+ "UUID of the organisation this ladder is the default for. Empty for the shared default.": "UUID der Organisation, für die diese Leiter der Standard ist. Leer beim gemeinsamen Standard.",
+ "When weekday": "Bei Wochentag",
+ "Whether reaching this rung opens an incident.": "Ob das Erreichen dieser Stufe einen Vorfall eröffnet.",
+ "Why the day is closed.": "Warum dieser Tag geschlossen ist.",
+ "Working calendar": "Werkkalender",
+ "Working hours in one working day. Makes hours and businessDays commensurable.": "Arbeitsstunden eines Arbeitstags. Macht Stunden und Werktage vergleichbar.",
+ "Working weekdays": "Arbeitswochentage",
+ "fixed: a month/day; easter: an offset in days from Easter Sunday; observedShift: a month/day with a required observed shift.": "fixed: Monat und Tag; easter: ein Abstand in Tagen ab Ostersonntag; observedShift: Monat und Tag mit vorgeschriebener Verschiebung.",
+ "preBreach fires before the deadline, slaBreached at or after it.": "preBreach löst vor Ablauf der Frist aus, slaBreached bei oder nach Ablauf.",
+ "No such task": "Keine solche Aufgabe",
+ "The task does not exist, or it is not yours to see.": "Die Aufgabe existiert nicht oder Sie dürfen sie nicht sehen.",
+ "Details": "Details",
+ "Due": "Fällig",
+ "Assignee": "Zugewiesen an",
+ "Requested by": "Angefordert von",
+ "Outcome": "Ergebnis",
+ "Ready to claim": "Bereit zur Übernahme",
+ "In progress": "In Bearbeitung",
+ "Terminated": "Beendet",
+ "Normal": "Normal",
+ "Urgent": "Dringend",
+ "Overdue by 1 day": "1 Tag überfällig",
+ "Overdue by {days} days": "{days} Tage überfällig",
+ "Due today": "Heute fällig",
+ "Due tomorrow": "Morgen fällig",
+ "Due in {days} days": "Fällig in {days} Tagen",
+ "Tasks": "Aufgaben",
+ "Task": "Aufgabe",
+ "Unassigned, open for claiming": "Nicht zugewiesen, zur Übernahme offen",
+ "Claim": "Übernehmen",
+ "Complete": "Abschließen",
+ "Complete: {outcome}": "Abschließen: {outcome}",
+ "Could not load the task": "Aufgabe konnte nicht geladen werden",
+ "The task refused that action": "Die Aufgabe hat diese Aktion abgelehnt"
},
"nplurals=2; plural=(n != 1);"
)
diff --git a/l10n/de.json b/l10n/de.json
index cf8036950c..b9c596ab83 100644
--- a/l10n/de.json
+++ b/l10n/de.json
@@ -1,10 +1,20 @@
{
"translations": {
+ "from amount {amount}": "ab Betrag {amount}",
+ "Gated transition: {transition}": "Bewachter Übergang: {transition}",
+ "Each declared chain provisions an ordered task sequence when its transition is attempted. Approvers decide in their task inbox, not here.": "Jede deklarierte Kette eröffnet beim Versuch des Übergangs eine geordnete Aufgabensequenz. Freigebende entscheiden in ihrem Aufgabeneingang, nicht hier.",
+ "Declare x-openregister-approval-chains on this schema to gate a lifecycle transition on approval.": "Deklarieren Sie x-openregister-approval-chains auf diesem Schema, um einen Lebenszyklusübergang hinter eine Freigabe zu stellen.",
+ "Approval sequences": "Freigabesequenzen",
"%n entries have no hash yet": "%n Einträge haben noch keinen Hash",
"%n entry has no hash yet": "%n Eintrag hat noch keinen Hash",
"(Dolphin required)": "(Dolphin erforderlich)",
+ "No approval chains declared": "Keine Freigabeketten deklariert",
"(no subject)": "(kein Betreff)",
"(no title)": "(kein Titel)",
+ "Role {role}": "Rolle {role}",
+ "The transition is applied automatically once every step approves.": "Der Übergang wird automatisch angewendet, sobald jeder Schritt freigegeben ist.",
+ "The requester may not decide their own approval.": "Wer den Antrag stellt, darf nicht über die eigene Freigabe entscheiden.",
+ "Tier routing on field: {field}": "Stufen-Routing über Feld: {field}",
"(unnamed)": "(unbenannt)",
"(untitled card)": "(unbenannte Karte)",
"({count} selected)": "({count} ausgewählt)",
@@ -2785,7 +2795,84 @@
"_Successfully restored {count} object_::_Successfully restored {count} objects_": [
"{count} Objekt erfolgreich wiederhergestellt",
"{count} Objekte erfolgreich wiederhergestellt"
- ]
+ ],
+ "A message identity the notification subsystem resolves.": "Eine Nachrichtenkennung, die das Benachrichtigungssystem auflöst.",
+ "Computed non-working-date rules. kind fixed: {month, day, name, observedShift?: {whenWeekday, days}}. kind easter: {offset, name}, offset in days from Easter Sunday. kind observedShift: a fixed date with a required shift.": "Berechnete Regeln für arbeitsfreie Tage. Art fixed: {month, day, name, observedShift?: {whenWeekday, days}}. Art easter: {offset, name}, Abstand in Tagen ab Ostersonntag. Art observedShift: ein festes Datum mit vorgeschriebener Verschiebung.",
+ "Date": "Datum",
+ "Day": "Tag",
+ "Day of a fixed or observedShift rule; ignored by an easter rule.": "Tag einer fixed- oder observedShift-Regel; eine easter-Regel ignoriert ihn.",
+ "Days": "Tage",
+ "Days from Easter Sunday for an easter rule; ignored by the other kinds.": "Tage ab Ostersonntag für eine easter-Regel; die anderen Arten ignorieren sie.",
+ "Distance from the deadline, in the offset unit.": "Abstand zur Frist, in der gewählten Einheit.",
+ "Enumerated one-off closures as {date, name}. Allowed alongside rules; refused as the whole calendar.": "Einzelne Schließtage als {date, name}. Neben Regeln zulässig; als ganzer Kalender abgelehnt.",
+ "Escalate to roles": "Eskalation an Rollen",
+ "Escalation ladder": "Eskalationsleiter",
+ "Exception dates": "Ausnahmetage",
+ "Hours per working day": "Stunden pro Arbeitstag",
+ "How many days the observed date shifts, e.g. -1 for the Saturday before.": "Um wie viele Tage der begangene Tag verschoben wird, z. B. -1 für den Samstag davor.",
+ "Human-readable title.": "Lesbarer Titel.",
+ "ISO weekdays (1 = Monday, 7 = Sunday) that are working days.": "ISO-Wochentage (1 = Montag, 7 = Sonntag), die Arbeitstage sind.",
+ "Kind": "Art",
+ "Message": "Nachricht",
+ "Month": "Monat",
+ "Month of a fixed or observedShift rule; ignored by an easter rule.": "Monat einer fixed- oder observedShift-Regel; eine easter-Regel ignoriert ihn.",
+ "Non-working-date rules": "Regeln für arbeitsfreie Tage",
+ "Notify roles": "Zu benachrichtigende Rollen",
+ "Observed shift": "Verschobener Feiertag",
+ "Offset": "Abstand",
+ "Offset unit": "Einheit des Abstands",
+ "Open incident": "Vorfall eröffnen",
+ "Optional map from a role name to a concrete recipient descriptor, e.g. {\"teamleader\": \"group:teamleaders\"}. Roles without a binding travel unresolved as role:.": "Optionale Zuordnung eines Rollennamens zu einem konkreten Empfänger, z. B. {\"teamleader\": \"group:teamleaders\"}. Rollen ohne Zuordnung reisen unaufgelöst als role: weiter.",
+ "Optional on a fixed rule, required on observedShift: {whenWeekday: weekday name or ISO 1..7, days: integer}.": "Optional bei einer fixed-Regel, verpflichtend bei observedShift: {whenWeekday: Name des Wochentags oder ISO 1..7, days: ganze Zahl}.",
+ "Ordered rungs: {key, trigger (preBreach|slaBreached), offset, offsetUnit (hours|businessDays|calendarDays), notifyRole[], escalateToRole[], priority, message, openIncident}.": "Geordnete Stufen: {key, trigger (preBreach|slaBreached), offset, offsetUnit (hours|businessDays|calendarDays), notifyRole[], escalateToRole[], priority, message, openIncident}.",
+ "Priority": "Priorität",
+ "Role bindings": "Rollenzuordnungen",
+ "Roles the matter is escalated to at this rung.": "Rollen, an die auf dieser Stufe eskaliert wird.",
+ "Roles told at this rung; handler is the subject's own performer.": "Rollen, die auf dieser Stufe benachrichtigt werden; handler ist die Bearbeiterin oder der Bearbeiter des Vorgangs.",
+ "Rungs": "Stufen",
+ "Stable rung identity, e.g. preBreach:14:calendarDays; derived from trigger, offset and unit when absent.": "Feste Kennung der Stufe, z. B. preBreach:14:calendarDays; fehlt sie, wird sie aus Auslöser, Abstand und Einheit abgeleitet.",
+ "The calendar's stable name, referenced by a timer's calendar_slug.": "Der feste Name des Kalenders, auf den ein Timer über calendar_slug verweist.",
+ "The closed date, Y-m-d.": "Der geschlossene Tag, Y-m-d.",
+ "The holiday's name.": "Der Name des Feiertags.",
+ "The ladder's stable name, referenced by a timer's ladder_slug.": "Der feste Name der Leiter, auf die ein Timer über ladder_slug verweist.",
+ "The unit of the offset: the same set the SLA accepts.": "Die Einheit des Abstands: dieselben Werte, die das SLA akzeptiert.",
+ "The urgency the raised transition carries.": "Die Dringlichkeit, die der ausgelöste Übergang trägt.",
+ "The weekday (name) on which the date shifts, e.g. sunday for Koningsdag.": "Der Wochentag (Name), an dem das Datum verschoben wird, z. B. sunday für Koningsdag.",
+ "UUID of the organisation this calendar is configured for. Empty for a shared calendar. The resolution order picks an organisation's calendar when the timer names none.": "UUID der Organisation, für die dieser Kalender eingerichtet ist. Leer bei einem gemeinsamen Kalender. Nennt der Timer keinen Kalender, wählt die Auflösungsreihenfolge den Kalender der Organisation.",
+ "UUID of the organisation this ladder is the default for. Empty for the shared default.": "UUID der Organisation, für die diese Leiter der Standard ist. Leer beim gemeinsamen Standard.",
+ "When weekday": "Bei Wochentag",
+ "Whether reaching this rung opens an incident.": "Ob das Erreichen dieser Stufe einen Vorfall eröffnet.",
+ "Why the day is closed.": "Warum dieser Tag geschlossen ist.",
+ "Working calendar": "Werkkalender",
+ "Working hours in one working day. Makes hours and businessDays commensurable.": "Arbeitsstunden eines Arbeitstags. Macht Stunden und Werktage vergleichbar.",
+ "Working weekdays": "Arbeitswochentage",
+ "fixed: a month/day; easter: an offset in days from Easter Sunday; observedShift: a month/day with a required observed shift.": "fixed: Monat und Tag; easter: ein Abstand in Tagen ab Ostersonntag; observedShift: Monat und Tag mit vorgeschriebener Verschiebung.",
+ "preBreach fires before the deadline, slaBreached at or after it.": "preBreach löst vor Ablauf der Frist aus, slaBreached bei oder nach Ablauf.",
+ "No such task": "Keine solche Aufgabe",
+ "The task does not exist, or it is not yours to see.": "Die Aufgabe existiert nicht oder Sie dürfen sie nicht sehen.",
+ "Details": "Details",
+ "Due": "Fällig",
+ "Assignee": "Zugewiesen an",
+ "Requested by": "Angefordert von",
+ "Outcome": "Ergebnis",
+ "Ready to claim": "Bereit zur Übernahme",
+ "In progress": "In Bearbeitung",
+ "Terminated": "Beendet",
+ "Normal": "Normal",
+ "Urgent": "Dringend",
+ "Overdue by 1 day": "1 Tag überfällig",
+ "Overdue by {days} days": "{days} Tage überfällig",
+ "Due today": "Heute fällig",
+ "Due tomorrow": "Morgen fällig",
+ "Due in {days} days": "Fällig in {days} Tagen",
+ "Tasks": "Aufgaben",
+ "Task": "Aufgabe",
+ "Unassigned, open for claiming": "Nicht zugewiesen, zur Übernahme offen",
+ "Claim": "Übernehmen",
+ "Complete": "Abschließen",
+ "Complete: {outcome}": "Abschließen: {outcome}",
+ "Could not load the task": "Aufgabe konnte nicht geladen werden",
+ "The task refused that action": "Die Aufgabe hat diese Aktion abgelehnt"
},
"pluralForm": "nplurals=2; plural=(n != 1);",
"plurals": {
diff --git a/l10n/el.js b/l10n/el.js
index 4acdfbbd63..b79ce5a01b 100644
--- a/l10n/el.js
+++ b/l10n/el.js
@@ -3,11 +3,21 @@ OC.L10N.register(
{
"3": "3",
"30": "30",
+ "from amount {amount}": "από ποσό {amount}",
+ "Gated transition: {transition}": "Ελεγχόμενη μετάβαση: {transition}",
+ "Each declared chain provisions an ordered task sequence when its transition is attempted. Approvers decide in their task inbox, not here.": "Κάθε δηλωμένη αλυσίδα ανοίγει μια διατεταγμένη ακολουθία εργασιών όταν επιχειρείται η μετάβαση. Οι εγκρίνοντες αποφασίζουν στα εισερχόμενα εργασιών τους, όχι εδώ.",
+ "Declare x-openregister-approval-chains on this schema to gate a lifecycle transition on approval.": "Δηλώστε x-openregister-approval-chains σε αυτό το σχήμα ώστε μια μετάβαση κύκλου ζωής να απαιτεί έγκριση.",
+ "Approval sequences": "Ακολουθίες έγκρισης",
"%n entries have no hash yet": "%n καταχωρίσεις δεν έχουν ακόμη κατακερματισμό",
"%n entry has no hash yet": "%n καταχώριση δεν έχει ακόμη κατακερματισμό",
"(Dolphin required)": "(απαιτείται Dolphin)",
+ "No approval chains declared": "Δεν έχουν δηλωθεί αλυσίδες έγκρισης",
"(no subject)": "(χωρίς θέμα)",
"(no title)": "(χωρίς τίτλο)",
+ "Role {role}": "Ρόλος {role}",
+ "The transition is applied automatically once every step approves.": "Η μετάβαση εφαρμόζεται αυτόματα μόλις εγκριθεί κάθε βήμα.",
+ "The requester may not decide their own approval.": "Ο αιτών δεν μπορεί να αποφασίσει για τη δική του έγκριση.",
+ "Tier routing on field: {field}": "Κλιμακωτή δρομολόγηση στο πεδίο: {field}",
"(unnamed)": "(χωρίς όνομα)",
"(untitled card)": "(κάρτα χωρίς τίτλο)",
"({count} selected)": "({count} επιλεγμένα)",
@@ -2738,7 +2748,84 @@ OC.L10N.register(
"_Object successfully deleted_::_Objects successfully deleted_": ["Το Αντικείμενο διαγράφηκε με επιτυχία","Τα Αντικείμενα διαγράφηκαν με επιτυχία"],
"_Purge {count} object from database_::_Purge {count} objects from database_": ["Εκκαθάριση {count} Αντικειμένου από τη βάση δεδομένων","Εκκαθάριση {count} Αντικειμένων από τη βάση δεδομένων"],
"_Restore {count} object_::_Restore {count} objects_": ["Επαναφορά {count} Αντικειμένου","Επαναφορά {count} Αντικειμένων"],
- "_Successfully restored {count} object_::_Successfully restored {count} objects_": ["Αποκαταστάθηκε με επιτυχία {count} Αντικείμενο","Αποκαταστάθηκαν με επιτυχία {count} Αντικείμενα"]
+ "_Successfully restored {count} object_::_Successfully restored {count} objects_": ["Αποκαταστάθηκε με επιτυχία {count} Αντικείμενο","Αποκαταστάθηκαν με επιτυχία {count} Αντικείμενα"],
+ "A message identity the notification subsystem resolves.": "A message identity the notification subsystem resolves.",
+ "Computed non-working-date rules. kind fixed: {month, day, name, observedShift?: {whenWeekday, days}}. kind easter: {offset, name}, offset in days from Easter Sunday. kind observedShift: a fixed date with a required shift.": "Computed non-working-date rules. kind fixed: {month, day, name, observedShift?: {whenWeekday, days}}. kind easter: {offset, name}, offset in days from Easter Sunday. kind observedShift: a fixed date with a required shift.",
+ "Date": "Date",
+ "Day": "Day",
+ "Day of a fixed or observedShift rule; ignored by an easter rule.": "Day of a fixed or observedShift rule; ignored by an easter rule.",
+ "Days": "Days",
+ "Days from Easter Sunday for an easter rule; ignored by the other kinds.": "Days from Easter Sunday for an easter rule; ignored by the other kinds.",
+ "Distance from the deadline, in the offset unit.": "Distance from the deadline, in the offset unit.",
+ "Enumerated one-off closures as {date, name}. Allowed alongside rules; refused as the whole calendar.": "Enumerated one-off closures as {date, name}. Allowed alongside rules; refused as the whole calendar.",
+ "Escalate to roles": "Escalate to roles",
+ "Escalation ladder": "Escalation ladder",
+ "Exception dates": "Exception dates",
+ "Hours per working day": "Hours per working day",
+ "How many days the observed date shifts, e.g. -1 for the Saturday before.": "How many days the observed date shifts, e.g. -1 for the Saturday before.",
+ "Human-readable title.": "Human-readable title.",
+ "ISO weekdays (1 = Monday, 7 = Sunday) that are working days.": "ISO weekdays (1 = Monday, 7 = Sunday) that are working days.",
+ "Kind": "Kind",
+ "Message": "Message",
+ "Month": "Month",
+ "Month of a fixed or observedShift rule; ignored by an easter rule.": "Month of a fixed or observedShift rule; ignored by an easter rule.",
+ "Non-working-date rules": "Non-working-date rules",
+ "Notify roles": "Notify roles",
+ "Observed shift": "Observed shift",
+ "Offset": "Offset",
+ "Offset unit": "Offset unit",
+ "Open incident": "Open incident",
+ "Optional map from a role name to a concrete recipient descriptor, e.g. {\"teamleader\": \"group:teamleaders\"}. Roles without a binding travel unresolved as role:.": "Optional map from a role name to a concrete recipient descriptor, e.g. {\"teamleader\": \"group:teamleaders\"}. Roles without a binding travel unresolved as role:.",
+ "Optional on a fixed rule, required on observedShift: {whenWeekday: weekday name or ISO 1..7, days: integer}.": "Optional on a fixed rule, required on observedShift: {whenWeekday: weekday name or ISO 1..7, days: integer}.",
+ "Ordered rungs: {key, trigger (preBreach|slaBreached), offset, offsetUnit (hours|businessDays|calendarDays), notifyRole[], escalateToRole[], priority, message, openIncident}.": "Ordered rungs: {key, trigger (preBreach|slaBreached), offset, offsetUnit (hours|businessDays|calendarDays), notifyRole[], escalateToRole[], priority, message, openIncident}.",
+ "Priority": "Priority",
+ "Role bindings": "Role bindings",
+ "Roles the matter is escalated to at this rung.": "Roles the matter is escalated to at this rung.",
+ "Roles told at this rung; handler is the subject's own performer.": "Roles told at this rung; handler is the subject's own performer.",
+ "Rungs": "Rungs",
+ "Stable rung identity, e.g. preBreach:14:calendarDays; derived from trigger, offset and unit when absent.": "Stable rung identity, e.g. preBreach:14:calendarDays; derived from trigger, offset and unit when absent.",
+ "The calendar's stable name, referenced by a timer's calendar_slug.": "The calendar's stable name, referenced by a timer's calendar_slug.",
+ "The closed date, Y-m-d.": "The closed date, Y-m-d.",
+ "The holiday's name.": "The holiday's name.",
+ "The ladder's stable name, referenced by a timer's ladder_slug.": "The ladder's stable name, referenced by a timer's ladder_slug.",
+ "The unit of the offset: the same set the SLA accepts.": "The unit of the offset: the same set the SLA accepts.",
+ "The urgency the raised transition carries.": "The urgency the raised transition carries.",
+ "The weekday (name) on which the date shifts, e.g. sunday for Koningsdag.": "The weekday (name) on which the date shifts, e.g. sunday for Koningsdag.",
+ "UUID of the organisation this calendar is configured for. Empty for a shared calendar. The resolution order picks an organisation's calendar when the timer names none.": "UUID of the organisation this calendar is configured for. Empty for a shared calendar. The resolution order picks an organisation's calendar when the timer names none.",
+ "UUID of the organisation this ladder is the default for. Empty for the shared default.": "UUID of the organisation this ladder is the default for. Empty for the shared default.",
+ "When weekday": "When weekday",
+ "Whether reaching this rung opens an incident.": "Whether reaching this rung opens an incident.",
+ "Why the day is closed.": "Why the day is closed.",
+ "Working calendar": "Working calendar",
+ "Working hours in one working day. Makes hours and businessDays commensurable.": "Working hours in one working day. Makes hours and businessDays commensurable.",
+ "Working weekdays": "Working weekdays",
+ "fixed: a month/day; easter: an offset in days from Easter Sunday; observedShift: a month/day with a required observed shift.": "fixed: a month/day; easter: an offset in days from Easter Sunday; observedShift: a month/day with a required observed shift.",
+ "preBreach fires before the deadline, slaBreached at or after it.": "preBreach fires before the deadline, slaBreached at or after it.",
+ "No such task": "Δεν υπάρχει τέτοια εργασία",
+ "The task does not exist, or it is not yours to see.": "Η εργασία δεν υπάρχει ή δεν επιτρέπεται να τη δείτε.",
+ "Details": "Λεπτομέρειες",
+ "Due": "Προθεσμία",
+ "Assignee": "Ανάθεση σε",
+ "Requested by": "Αιτήθηκε από",
+ "Outcome": "Αποτέλεσμα",
+ "Ready to claim": "Έτοιμο για ανάληψη",
+ "In progress": "Σε εξέλιξη",
+ "Terminated": "Τερματίστηκε",
+ "Normal": "Κανονική",
+ "Urgent": "Επείγουσα",
+ "Overdue by 1 day": "Εκπρόθεσμη κατά 1 ημέρα",
+ "Overdue by {days} days": "Εκπρόθεσμη κατά {days} ημέρες",
+ "Due today": "Λήγει σήμερα",
+ "Due tomorrow": "Λήγει αύριο",
+ "Due in {days} days": "Λήγει σε {days} ημέρες",
+ "Tasks": "Εργασίες",
+ "Task": "Εργασία",
+ "Unassigned, open for claiming": "Χωρίς ανάθεση, ανοιχτή για ανάληψη",
+ "Claim": "Ανάληψη",
+ "Complete": "Ολοκλήρωση",
+ "Complete: {outcome}": "Ολοκλήρωση: {outcome}",
+ "Could not load the task": "Δεν ήταν δυνατή η φόρτωση της εργασίας",
+ "The task refused that action": "Η εργασία απέρριψε αυτήν την ενέργεια"
},
"nplurals=2; plural=(n != 1);"
)
diff --git a/l10n/el.json b/l10n/el.json
index 5a21bf9a7f..b4a7886d1d 100644
--- a/l10n/el.json
+++ b/l10n/el.json
@@ -1,10 +1,20 @@
{
"translations": {
+ "from amount {amount}": "από ποσό {amount}",
+ "Gated transition: {transition}": "Ελεγχόμενη μετάβαση: {transition}",
+ "Each declared chain provisions an ordered task sequence when its transition is attempted. Approvers decide in their task inbox, not here.": "Κάθε δηλωμένη αλυσίδα ανοίγει μια διατεταγμένη ακολουθία εργασιών όταν επιχειρείται η μετάβαση. Οι εγκρίνοντες αποφασίζουν στα εισερχόμενα εργασιών τους, όχι εδώ.",
+ "Declare x-openregister-approval-chains on this schema to gate a lifecycle transition on approval.": "Δηλώστε x-openregister-approval-chains σε αυτό το σχήμα ώστε μια μετάβαση κύκλου ζωής να απαιτεί έγκριση.",
+ "Approval sequences": "Ακολουθίες έγκρισης",
"%n entries have no hash yet": "%n καταχωρίσεις δεν έχουν ακόμη κατακερματισμό",
"%n entry has no hash yet": "%n καταχώριση δεν έχει ακόμη κατακερματισμό",
"(Dolphin required)": "(απαιτείται Dolphin)",
+ "No approval chains declared": "Δεν έχουν δηλωθεί αλυσίδες έγκρισης",
"(no subject)": "(χωρίς θέμα)",
"(no title)": "(χωρίς τίτλο)",
+ "Role {role}": "Ρόλος {role}",
+ "The transition is applied automatically once every step approves.": "Η μετάβαση εφαρμόζεται αυτόματα μόλις εγκριθεί κάθε βήμα.",
+ "The requester may not decide their own approval.": "Ο αιτών δεν μπορεί να αποφασίσει για τη δική του έγκριση.",
+ "Tier routing on field: {field}": "Κλιμακωτή δρομολόγηση στο πεδίο: {field}",
"(unnamed)": "(χωρίς όνομα)",
"(untitled card)": "(κάρτα χωρίς τίτλο)",
"({count} selected)": "({count} επιλεγμένα)",
@@ -2785,7 +2795,84 @@
"_Successfully restored {count} object_::_Successfully restored {count} objects_": [
"Αποκαταστάθηκε με επιτυχία {count} Αντικείμενο",
"Αποκαταστάθηκαν με επιτυχία {count} Αντικείμενα"
- ]
+ ],
+ "A message identity the notification subsystem resolves.": "A message identity the notification subsystem resolves.",
+ "Computed non-working-date rules. kind fixed: {month, day, name, observedShift?: {whenWeekday, days}}. kind easter: {offset, name}, offset in days from Easter Sunday. kind observedShift: a fixed date with a required shift.": "Computed non-working-date rules. kind fixed: {month, day, name, observedShift?: {whenWeekday, days}}. kind easter: {offset, name}, offset in days from Easter Sunday. kind observedShift: a fixed date with a required shift.",
+ "Date": "Date",
+ "Day": "Day",
+ "Day of a fixed or observedShift rule; ignored by an easter rule.": "Day of a fixed or observedShift rule; ignored by an easter rule.",
+ "Days": "Days",
+ "Days from Easter Sunday for an easter rule; ignored by the other kinds.": "Days from Easter Sunday for an easter rule; ignored by the other kinds.",
+ "Distance from the deadline, in the offset unit.": "Distance from the deadline, in the offset unit.",
+ "Enumerated one-off closures as {date, name}. Allowed alongside rules; refused as the whole calendar.": "Enumerated one-off closures as {date, name}. Allowed alongside rules; refused as the whole calendar.",
+ "Escalate to roles": "Escalate to roles",
+ "Escalation ladder": "Escalation ladder",
+ "Exception dates": "Exception dates",
+ "Hours per working day": "Hours per working day",
+ "How many days the observed date shifts, e.g. -1 for the Saturday before.": "How many days the observed date shifts, e.g. -1 for the Saturday before.",
+ "Human-readable title.": "Human-readable title.",
+ "ISO weekdays (1 = Monday, 7 = Sunday) that are working days.": "ISO weekdays (1 = Monday, 7 = Sunday) that are working days.",
+ "Kind": "Kind",
+ "Message": "Message",
+ "Month": "Month",
+ "Month of a fixed or observedShift rule; ignored by an easter rule.": "Month of a fixed or observedShift rule; ignored by an easter rule.",
+ "Non-working-date rules": "Non-working-date rules",
+ "Notify roles": "Notify roles",
+ "Observed shift": "Observed shift",
+ "Offset": "Offset",
+ "Offset unit": "Offset unit",
+ "Open incident": "Open incident",
+ "Optional map from a role name to a concrete recipient descriptor, e.g. {\"teamleader\": \"group:teamleaders\"}. Roles without a binding travel unresolved as role:.": "Optional map from a role name to a concrete recipient descriptor, e.g. {\"teamleader\": \"group:teamleaders\"}. Roles without a binding travel unresolved as role:.",
+ "Optional on a fixed rule, required on observedShift: {whenWeekday: weekday name or ISO 1..7, days: integer}.": "Optional on a fixed rule, required on observedShift: {whenWeekday: weekday name or ISO 1..7, days: integer}.",
+ "Ordered rungs: {key, trigger (preBreach|slaBreached), offset, offsetUnit (hours|businessDays|calendarDays), notifyRole[], escalateToRole[], priority, message, openIncident}.": "Ordered rungs: {key, trigger (preBreach|slaBreached), offset, offsetUnit (hours|businessDays|calendarDays), notifyRole[], escalateToRole[], priority, message, openIncident}.",
+ "Priority": "Priority",
+ "Role bindings": "Role bindings",
+ "Roles the matter is escalated to at this rung.": "Roles the matter is escalated to at this rung.",
+ "Roles told at this rung; handler is the subject's own performer.": "Roles told at this rung; handler is the subject's own performer.",
+ "Rungs": "Rungs",
+ "Stable rung identity, e.g. preBreach:14:calendarDays; derived from trigger, offset and unit when absent.": "Stable rung identity, e.g. preBreach:14:calendarDays; derived from trigger, offset and unit when absent.",
+ "The calendar's stable name, referenced by a timer's calendar_slug.": "The calendar's stable name, referenced by a timer's calendar_slug.",
+ "The closed date, Y-m-d.": "The closed date, Y-m-d.",
+ "The holiday's name.": "The holiday's name.",
+ "The ladder's stable name, referenced by a timer's ladder_slug.": "The ladder's stable name, referenced by a timer's ladder_slug.",
+ "The unit of the offset: the same set the SLA accepts.": "The unit of the offset: the same set the SLA accepts.",
+ "The urgency the raised transition carries.": "The urgency the raised transition carries.",
+ "The weekday (name) on which the date shifts, e.g. sunday for Koningsdag.": "The weekday (name) on which the date shifts, e.g. sunday for Koningsdag.",
+ "UUID of the organisation this calendar is configured for. Empty for a shared calendar. The resolution order picks an organisation's calendar when the timer names none.": "UUID of the organisation this calendar is configured for. Empty for a shared calendar. The resolution order picks an organisation's calendar when the timer names none.",
+ "UUID of the organisation this ladder is the default for. Empty for the shared default.": "UUID of the organisation this ladder is the default for. Empty for the shared default.",
+ "When weekday": "When weekday",
+ "Whether reaching this rung opens an incident.": "Whether reaching this rung opens an incident.",
+ "Why the day is closed.": "Why the day is closed.",
+ "Working calendar": "Working calendar",
+ "Working hours in one working day. Makes hours and businessDays commensurable.": "Working hours in one working day. Makes hours and businessDays commensurable.",
+ "Working weekdays": "Working weekdays",
+ "fixed: a month/day; easter: an offset in days from Easter Sunday; observedShift: a month/day with a required observed shift.": "fixed: a month/day; easter: an offset in days from Easter Sunday; observedShift: a month/day with a required observed shift.",
+ "preBreach fires before the deadline, slaBreached at or after it.": "preBreach fires before the deadline, slaBreached at or after it.",
+ "No such task": "Δεν υπάρχει τέτοια εργασία",
+ "The task does not exist, or it is not yours to see.": "Η εργασία δεν υπάρχει ή δεν επιτρέπεται να τη δείτε.",
+ "Details": "Λεπτομέρειες",
+ "Due": "Προθεσμία",
+ "Assignee": "Ανάθεση σε",
+ "Requested by": "Αιτήθηκε από",
+ "Outcome": "Αποτέλεσμα",
+ "Ready to claim": "Έτοιμο για ανάληψη",
+ "In progress": "Σε εξέλιξη",
+ "Terminated": "Τερματίστηκε",
+ "Normal": "Κανονική",
+ "Urgent": "Επείγουσα",
+ "Overdue by 1 day": "Εκπρόθεσμη κατά 1 ημέρα",
+ "Overdue by {days} days": "Εκπρόθεσμη κατά {days} ημέρες",
+ "Due today": "Λήγει σήμερα",
+ "Due tomorrow": "Λήγει αύριο",
+ "Due in {days} days": "Λήγει σε {days} ημέρες",
+ "Tasks": "Εργασίες",
+ "Task": "Εργασία",
+ "Unassigned, open for claiming": "Χωρίς ανάθεση, ανοιχτή για ανάληψη",
+ "Claim": "Ανάληψη",
+ "Complete": "Ολοκλήρωση",
+ "Complete: {outcome}": "Ολοκλήρωση: {outcome}",
+ "Could not load the task": "Δεν ήταν δυνατή η φόρτωση της εργασίας",
+ "The task refused that action": "Η εργασία απέρριψε αυτήν την ενέργεια"
},
"pluralForm": "nplurals=2; plural=(n != 1);",
"plurals": {
diff --git a/l10n/en.js b/l10n/en.js
index 042d84ba92..77f202ba3e 100644
--- a/l10n/en.js
+++ b/l10n/en.js
@@ -3,9 +3,19 @@ OC.L10N.register(
{
"3": "3",
"30": "30",
+ "Declare x-openregister-approval-chains on this schema to gate a lifecycle transition on approval.": "Declare x-openregister-approval-chains on this schema to gate a lifecycle transition on approval.",
+ "Approval sequences": "Approval sequences",
"(Dolphin required)": "(Dolphin required)",
+ "from amount {amount}": "from amount {amount}",
+ "Gated transition: {transition}": "Gated transition: {transition}",
+ "Each declared chain provisions an ordered task sequence when its transition is attempted. Approvers decide in their task inbox, not here.": "Each declared chain provisions an ordered task sequence when its transition is attempted. Approvers decide in their task inbox, not here.",
+ "No approval chains declared": "No approval chains declared",
"(no subject)": "(no subject)",
"(no title)": "(no title)",
+ "Role {role}": "Role {role}",
+ "The transition is applied automatically once every step approves.": "The transition is applied automatically once every step approves.",
+ "The requester may not decide their own approval.": "The requester may not decide their own approval.",
+ "Tier routing on field: {field}": "Tier routing on field: {field}",
"(unnamed)": "(unnamed)",
"(untitled card)": "(untitled card)",
"({count} selected)": "({count} selected)",
@@ -2738,7 +2748,84 @@ OC.L10N.register(
"_Object successfully deleted_::_Objects successfully deleted_": ["Object successfully deleted","Objects successfully deleted"],
"_Purge {count} object from database_::_Purge {count} objects from database_": ["Purge {count} object from database","Purge {count} objects from database"],
"_Restore {count} object_::_Restore {count} objects_": ["Restore {count} object","Restore {count} objects"],
- "_Successfully restored {count} object_::_Successfully restored {count} objects_": ["Successfully restored {count} object","Successfully restored {count} objects"]
+ "_Successfully restored {count} object_::_Successfully restored {count} objects_": ["Successfully restored {count} object","Successfully restored {count} objects"],
+ "Working calendar": "Working calendar",
+ "Escalation ladder": "Escalation ladder",
+ "Working weekdays": "Working weekdays",
+ "Hours per working day": "Hours per working day",
+ "Non-working-date rules": "Non-working-date rules",
+ "Exception dates": "Exception dates",
+ "Rungs": "Rungs",
+ "Role bindings": "Role bindings",
+ "Kind": "Kind",
+ "Month": "Month",
+ "Day": "Day",
+ "Offset": "Offset",
+ "Observed shift": "Observed shift",
+ "When weekday": "When weekday",
+ "Days": "Days",
+ "Date": "Date",
+ "Offset unit": "Offset unit",
+ "Notify roles": "Notify roles",
+ "Escalate to roles": "Escalate to roles",
+ "Priority": "Priority",
+ "Message": "Message",
+ "Open incident": "Open incident",
+ "The calendar's stable name, referenced by a timer's calendar_slug.": "The calendar's stable name, referenced by a timer's calendar_slug.",
+ "Human-readable title.": "Human-readable title.",
+ "UUID of the organisation this calendar is configured for. Empty for a shared calendar. The resolution order picks an organisation's calendar when the timer names none.": "UUID of the organisation this calendar is configured for. Empty for a shared calendar. The resolution order picks an organisation's calendar when the timer names none.",
+ "ISO weekdays (1 = Monday, 7 = Sunday) that are working days.": "ISO weekdays (1 = Monday, 7 = Sunday) that are working days.",
+ "Working hours in one working day. Makes hours and businessDays commensurable.": "Working hours in one working day. Makes hours and businessDays commensurable.",
+ "Computed non-working-date rules. kind fixed: {month, day, name, observedShift?: {whenWeekday, days}}. kind easter: {offset, name}, offset in days from Easter Sunday. kind observedShift: a fixed date with a required shift.": "Computed non-working-date rules. kind fixed: {month, day, name, observedShift?: {whenWeekday, days}}. kind easter: {offset, name}, offset in days from Easter Sunday. kind observedShift: a fixed date with a required shift.",
+ "fixed: a month/day; easter: an offset in days from Easter Sunday; observedShift: a month/day with a required observed shift.": "fixed: a month/day; easter: an offset in days from Easter Sunday; observedShift: a month/day with a required observed shift.",
+ "The holiday's name.": "The holiday's name.",
+ "Month of a fixed or observedShift rule; ignored by an easter rule.": "Month of a fixed or observedShift rule; ignored by an easter rule.",
+ "Day of a fixed or observedShift rule; ignored by an easter rule.": "Day of a fixed or observedShift rule; ignored by an easter rule.",
+ "Days from Easter Sunday for an easter rule; ignored by the other kinds.": "Days from Easter Sunday for an easter rule; ignored by the other kinds.",
+ "Optional on a fixed rule, required on observedShift: {whenWeekday: weekday name or ISO 1..7, days: integer}.": "Optional on a fixed rule, required on observedShift: {whenWeekday: weekday name or ISO 1..7, days: integer}.",
+ "The weekday (name) on which the date shifts, e.g. sunday for Koningsdag.": "The weekday (name) on which the date shifts, e.g. sunday for Koningsdag.",
+ "How many days the observed date shifts, e.g. -1 for the Saturday before.": "How many days the observed date shifts, e.g. -1 for the Saturday before.",
+ "Enumerated one-off closures as {date, name}. Allowed alongside rules; refused as the whole calendar.": "Enumerated one-off closures as {date, name}. Allowed alongside rules; refused as the whole calendar.",
+ "The closed date, Y-m-d.": "The closed date, Y-m-d.",
+ "Why the day is closed.": "Why the day is closed.",
+ "The ladder's stable name, referenced by a timer's ladder_slug.": "The ladder's stable name, referenced by a timer's ladder_slug.",
+ "UUID of the organisation this ladder is the default for. Empty for the shared default.": "UUID of the organisation this ladder is the default for. Empty for the shared default.",
+ "Ordered rungs: {key, trigger (preBreach|slaBreached), offset, offsetUnit (hours|businessDays|calendarDays), notifyRole[], escalateToRole[], priority, message, openIncident}.": "Ordered rungs: {key, trigger (preBreach|slaBreached), offset, offsetUnit (hours|businessDays|calendarDays), notifyRole[], escalateToRole[], priority, message, openIncident}.",
+ "Stable rung identity, e.g. preBreach:14:calendarDays; derived from trigger, offset and unit when absent.": "Stable rung identity, e.g. preBreach:14:calendarDays; derived from trigger, offset and unit when absent.",
+ "preBreach fires before the deadline, slaBreached at or after it.": "preBreach fires before the deadline, slaBreached at or after it.",
+ "Distance from the deadline, in the offset unit.": "Distance from the deadline, in the offset unit.",
+ "The unit of the offset: the same set the SLA accepts.": "The unit of the offset: the same set the SLA accepts.",
+ "Roles told at this rung; handler is the subject's own performer.": "Roles told at this rung; handler is the subject's own performer.",
+ "Roles the matter is escalated to at this rung.": "Roles the matter is escalated to at this rung.",
+ "The urgency the raised transition carries.": "The urgency the raised transition carries.",
+ "A message identity the notification subsystem resolves.": "A message identity the notification subsystem resolves.",
+ "Whether reaching this rung opens an incident.": "Whether reaching this rung opens an incident.",
+ "Optional map from a role name to a concrete recipient descriptor, e.g. {\"teamleader\": \"group:teamleaders\"}. Roles without a binding travel unresolved as role:.": "Optional map from a role name to a concrete recipient descriptor, e.g. {\"teamleader\": \"group:teamleaders\"}. Roles without a binding travel unresolved as role:.",
+ "No such task": "No such task",
+ "The task does not exist, or it is not yours to see.": "The task does not exist, or it is not yours to see.",
+ "Details": "Details",
+ "Due": "Due",
+ "Assignee": "Assignee",
+ "Requested by": "Requested by",
+ "Outcome": "Outcome",
+ "Ready to claim": "Ready to claim",
+ "In progress": "In progress",
+ "Terminated": "Terminated",
+ "Normal": "Normal",
+ "Urgent": "Urgent",
+ "Overdue by 1 day": "Overdue by 1 day",
+ "Overdue by {days} days": "Overdue by {days} days",
+ "Due today": "Due today",
+ "Due tomorrow": "Due tomorrow",
+ "Due in {days} days": "Due in {days} days",
+ "Tasks": "Tasks",
+ "Task": "Task",
+ "Unassigned, open for claiming": "Unassigned, open for claiming",
+ "Claim": "Claim",
+ "Complete": "Complete",
+ "Complete: {outcome}": "Complete: {outcome}",
+ "Could not load the task": "Could not load the task",
+ "The task refused that action": "The task refused that action"
},
"nplurals=2; plural=(n != 1);"
)
diff --git a/l10n/en.json b/l10n/en.json
index ea7366b7ef..7e7b145085 100644
--- a/l10n/en.json
+++ b/l10n/en.json
@@ -2,9 +2,19 @@
"translations": {
"3": "3",
"30": "30",
+ "Declare x-openregister-approval-chains on this schema to gate a lifecycle transition on approval.": "Declare x-openregister-approval-chains on this schema to gate a lifecycle transition on approval.",
+ "Approval sequences": "Approval sequences",
"(Dolphin required)": "(Dolphin required)",
+ "from amount {amount}": "from amount {amount}",
+ "Gated transition: {transition}": "Gated transition: {transition}",
+ "Each declared chain provisions an ordered task sequence when its transition is attempted. Approvers decide in their task inbox, not here.": "Each declared chain provisions an ordered task sequence when its transition is attempted. Approvers decide in their task inbox, not here.",
+ "No approval chains declared": "No approval chains declared",
"(no subject)": "(no subject)",
"(no title)": "(no title)",
+ "Role {role}": "Role {role}",
+ "The transition is applied automatically once every step approves.": "The transition is applied automatically once every step approves.",
+ "The requester may not decide their own approval.": "The requester may not decide their own approval.",
+ "Tier routing on field: {field}": "Tier routing on field: {field}",
"(unnamed)": "(unnamed)",
"(untitled card)": "(untitled card)",
"({count} selected)": "({count} selected)",
@@ -2785,7 +2795,84 @@
"_Successfully restored {count} object_::_Successfully restored {count} objects_": [
"Successfully restored {count} object",
"Successfully restored {count} objects"
- ]
+ ],
+ "Working calendar": "Working calendar",
+ "Escalation ladder": "Escalation ladder",
+ "Working weekdays": "Working weekdays",
+ "Hours per working day": "Hours per working day",
+ "Non-working-date rules": "Non-working-date rules",
+ "Exception dates": "Exception dates",
+ "Rungs": "Rungs",
+ "Role bindings": "Role bindings",
+ "Kind": "Kind",
+ "Month": "Month",
+ "Day": "Day",
+ "Offset": "Offset",
+ "Observed shift": "Observed shift",
+ "When weekday": "When weekday",
+ "Days": "Days",
+ "Date": "Date",
+ "Offset unit": "Offset unit",
+ "Notify roles": "Notify roles",
+ "Escalate to roles": "Escalate to roles",
+ "Priority": "Priority",
+ "Message": "Message",
+ "Open incident": "Open incident",
+ "The calendar's stable name, referenced by a timer's calendar_slug.": "The calendar's stable name, referenced by a timer's calendar_slug.",
+ "Human-readable title.": "Human-readable title.",
+ "UUID of the organisation this calendar is configured for. Empty for a shared calendar. The resolution order picks an organisation's calendar when the timer names none.": "UUID of the organisation this calendar is configured for. Empty for a shared calendar. The resolution order picks an organisation's calendar when the timer names none.",
+ "ISO weekdays (1 = Monday, 7 = Sunday) that are working days.": "ISO weekdays (1 = Monday, 7 = Sunday) that are working days.",
+ "Working hours in one working day. Makes hours and businessDays commensurable.": "Working hours in one working day. Makes hours and businessDays commensurable.",
+ "Computed non-working-date rules. kind fixed: {month, day, name, observedShift?: {whenWeekday, days}}. kind easter: {offset, name}, offset in days from Easter Sunday. kind observedShift: a fixed date with a required shift.": "Computed non-working-date rules. kind fixed: {month, day, name, observedShift?: {whenWeekday, days}}. kind easter: {offset, name}, offset in days from Easter Sunday. kind observedShift: a fixed date with a required shift.",
+ "fixed: a month/day; easter: an offset in days from Easter Sunday; observedShift: a month/day with a required observed shift.": "fixed: a month/day; easter: an offset in days from Easter Sunday; observedShift: a month/day with a required observed shift.",
+ "The holiday's name.": "The holiday's name.",
+ "Month of a fixed or observedShift rule; ignored by an easter rule.": "Month of a fixed or observedShift rule; ignored by an easter rule.",
+ "Day of a fixed or observedShift rule; ignored by an easter rule.": "Day of a fixed or observedShift rule; ignored by an easter rule.",
+ "Days from Easter Sunday for an easter rule; ignored by the other kinds.": "Days from Easter Sunday for an easter rule; ignored by the other kinds.",
+ "Optional on a fixed rule, required on observedShift: {whenWeekday: weekday name or ISO 1..7, days: integer}.": "Optional on a fixed rule, required on observedShift: {whenWeekday: weekday name or ISO 1..7, days: integer}.",
+ "The weekday (name) on which the date shifts, e.g. sunday for Koningsdag.": "The weekday (name) on which the date shifts, e.g. sunday for Koningsdag.",
+ "How many days the observed date shifts, e.g. -1 for the Saturday before.": "How many days the observed date shifts, e.g. -1 for the Saturday before.",
+ "Enumerated one-off closures as {date, name}. Allowed alongside rules; refused as the whole calendar.": "Enumerated one-off closures as {date, name}. Allowed alongside rules; refused as the whole calendar.",
+ "The closed date, Y-m-d.": "The closed date, Y-m-d.",
+ "Why the day is closed.": "Why the day is closed.",
+ "The ladder's stable name, referenced by a timer's ladder_slug.": "The ladder's stable name, referenced by a timer's ladder_slug.",
+ "UUID of the organisation this ladder is the default for. Empty for the shared default.": "UUID of the organisation this ladder is the default for. Empty for the shared default.",
+ "Ordered rungs: {key, trigger (preBreach|slaBreached), offset, offsetUnit (hours|businessDays|calendarDays), notifyRole[], escalateToRole[], priority, message, openIncident}.": "Ordered rungs: {key, trigger (preBreach|slaBreached), offset, offsetUnit (hours|businessDays|calendarDays), notifyRole[], escalateToRole[], priority, message, openIncident}.",
+ "Stable rung identity, e.g. preBreach:14:calendarDays; derived from trigger, offset and unit when absent.": "Stable rung identity, e.g. preBreach:14:calendarDays; derived from trigger, offset and unit when absent.",
+ "preBreach fires before the deadline, slaBreached at or after it.": "preBreach fires before the deadline, slaBreached at or after it.",
+ "Distance from the deadline, in the offset unit.": "Distance from the deadline, in the offset unit.",
+ "The unit of the offset: the same set the SLA accepts.": "The unit of the offset: the same set the SLA accepts.",
+ "Roles told at this rung; handler is the subject's own performer.": "Roles told at this rung; handler is the subject's own performer.",
+ "Roles the matter is escalated to at this rung.": "Roles the matter is escalated to at this rung.",
+ "The urgency the raised transition carries.": "The urgency the raised transition carries.",
+ "A message identity the notification subsystem resolves.": "A message identity the notification subsystem resolves.",
+ "Whether reaching this rung opens an incident.": "Whether reaching this rung opens an incident.",
+ "Optional map from a role name to a concrete recipient descriptor, e.g. {\"teamleader\": \"group:teamleaders\"}. Roles without a binding travel unresolved as role:.": "Optional map from a role name to a concrete recipient descriptor, e.g. {\"teamleader\": \"group:teamleaders\"}. Roles without a binding travel unresolved as role:.",
+ "No such task": "No such task",
+ "The task does not exist, or it is not yours to see.": "The task does not exist, or it is not yours to see.",
+ "Details": "Details",
+ "Due": "Due",
+ "Assignee": "Assignee",
+ "Requested by": "Requested by",
+ "Outcome": "Outcome",
+ "Ready to claim": "Ready to claim",
+ "In progress": "In progress",
+ "Terminated": "Terminated",
+ "Normal": "Normal",
+ "Urgent": "Urgent",
+ "Overdue by 1 day": "Overdue by 1 day",
+ "Overdue by {days} days": "Overdue by {days} days",
+ "Due today": "Due today",
+ "Due tomorrow": "Due tomorrow",
+ "Due in {days} days": "Due in {days} days",
+ "Tasks": "Tasks",
+ "Task": "Task",
+ "Unassigned, open for claiming": "Unassigned, open for claiming",
+ "Claim": "Claim",
+ "Complete": "Complete",
+ "Complete: {outcome}": "Complete: {outcome}",
+ "Could not load the task": "Could not load the task",
+ "The task refused that action": "The task refused that action"
},
"pluralForm": "nplurals=2; plural=(n != 1);",
"plurals": {
diff --git a/l10n/es.js b/l10n/es.js
index 7c3dbfdd38..c9d546438a 100644
--- a/l10n/es.js
+++ b/l10n/es.js
@@ -3,11 +3,21 @@ OC.L10N.register(
{
"3": "3",
"30": "30",
+ "from amount {amount}": "a partir del importe {amount}",
+ "Gated transition: {transition}": "Transición controlada: {transition}",
+ "Each declared chain provisions an ordered task sequence when its transition is attempted. Approvers decide in their task inbox, not here.": "Cada cadena declarada abre una secuencia ordenada de tareas cuando se intenta la transición. Quienes aprueban deciden en su bandeja de tareas, no aquí.",
+ "Declare x-openregister-approval-chains on this schema to gate a lifecycle transition on approval.": "Declare x-openregister-approval-chains en este esquema para condicionar una transición del ciclo de vida a una aprobación.",
+ "Approval sequences": "Secuencias de aprobación",
"%n entries have no hash yet": "%n entradas aún no tienen hash",
"%n entry has no hash yet": "%n entrada aún no tiene hash",
"(Dolphin required)": "(Se requiere Dolphin)",
+ "No approval chains declared": "No hay cadenas de aprobación declaradas",
"(no subject)": "(sin asunto)",
"(no title)": "(sin título)",
+ "Role {role}": "Rol {role}",
+ "The transition is applied automatically once every step approves.": "La transición se aplica automáticamente cuando todos los pasos están aprobados.",
+ "The requester may not decide their own approval.": "El solicitante no puede decidir sobre su propia aprobación.",
+ "Tier routing on field: {field}": "Enrutamiento por tramos según el campo: {field}",
"(unnamed)": "(sin nombre)",
"(untitled card)": "(tarjeta sin título)",
"({count} selected)": "({count} seleccionados)",
@@ -2738,7 +2748,84 @@ OC.L10N.register(
"_Object successfully deleted_::_Objects successfully deleted_": ["Objeto eliminado correctamente","Objetos eliminados correctamente","Objetos eliminados correctamente"],
"_Purge {count} object from database_::_Purge {count} objects from database_": ["Purgar {count} objeto de la base de datos","Purgar {count} objetos de la base de datos","Purgar {count} objetos de la base de datos"],
"_Restore {count} object_::_Restore {count} objects_": ["Restaurar {count} objeto","Restaurar {count} objetos","Restaurar {count} objetos"],
- "_Successfully restored {count} object_::_Successfully restored {count} objects_": ["Se restauró {count} objeto correctamente","Se restauraron {count} objetos correctamente","Se restauraron {count} objetos correctamente"]
+ "_Successfully restored {count} object_::_Successfully restored {count} objects_": ["Se restauró {count} objeto correctamente","Se restauraron {count} objetos correctamente","Se restauraron {count} objetos correctamente"],
+ "A message identity the notification subsystem resolves.": "Una identidad de mensaje que resuelve el sistema de notificaciones.",
+ "Computed non-working-date rules. kind fixed: {month, day, name, observedShift?: {whenWeekday, days}}. kind easter: {offset, name}, offset in days from Easter Sunday. kind observedShift: a fixed date with a required shift.": "Reglas calculadas de días no laborables. Tipo fixed: {month, day, name, observedShift?: {whenWeekday, days}}. Tipo easter: {offset, name}, desplazamiento en días desde el Domingo de Pascua. Tipo observedShift: una fecha fija con traslado obligatorio.",
+ "Date": "Fecha",
+ "Day": "Día",
+ "Day of a fixed or observedShift rule; ignored by an easter rule.": "Día de una regla fixed u observedShift; una regla easter lo ignora.",
+ "Days": "Días",
+ "Days from Easter Sunday for an easter rule; ignored by the other kinds.": "Días desde el Domingo de Pascua para una regla easter; los demás tipos los ignoran.",
+ "Distance from the deadline, in the offset unit.": "Distancia al plazo, en la unidad del desplazamiento.",
+ "Enumerated one-off closures as {date, name}. Allowed alongside rules; refused as the whole calendar.": "Cierres puntuales enumerados como {date, name}. Permitidos junto a reglas; rechazados como calendario completo.",
+ "Escalate to roles": "Roles de escalado",
+ "Escalation ladder": "Escalera de escalado",
+ "Exception dates": "Fechas de excepción",
+ "Hours per working day": "Horas por día laborable",
+ "How many days the observed date shifts, e.g. -1 for the Saturday before.": "Cuántos días se traslada la fecha observada, p. ej. -1 para el sábado anterior.",
+ "Human-readable title.": "Título legible.",
+ "ISO weekdays (1 = Monday, 7 = Sunday) that are working days.": "Días ISO de la semana (1 = lunes, 7 = domingo) que son laborables.",
+ "Kind": "Tipo",
+ "Message": "Mensaje",
+ "Month": "Mes",
+ "Month of a fixed or observedShift rule; ignored by an easter rule.": "Mes de una regla fixed u observedShift; una regla easter lo ignora.",
+ "Non-working-date rules": "Reglas de días no laborables",
+ "Notify roles": "Roles a notificar",
+ "Observed shift": "Traslado del festivo",
+ "Offset": "Desplazamiento",
+ "Offset unit": "Unidad del desplazamiento",
+ "Open incident": "Abrir incidencia",
+ "Optional map from a role name to a concrete recipient descriptor, e.g. {\"teamleader\": \"group:teamleaders\"}. Roles without a binding travel unresolved as role:.": "Mapa opcional de un nombre de rol a un destinatario concreto, p. ej. {\"teamleader\": \"group:teamleaders\"}. Los roles sin asignación viajan sin resolver como role:.",
+ "Optional on a fixed rule, required on observedShift: {whenWeekday: weekday name or ISO 1..7, days: integer}.": "Opcional en una regla fixed, obligatorio en observedShift: {whenWeekday: nombre del día o ISO 1..7, days: entero}.",
+ "Ordered rungs: {key, trigger (preBreach|slaBreached), offset, offsetUnit (hours|businessDays|calendarDays), notifyRole[], escalateToRole[], priority, message, openIncident}.": "Peldaños ordenados: {key, trigger (preBreach|slaBreached), offset, offsetUnit (hours|businessDays|calendarDays), notifyRole[], escalateToRole[], priority, message, openIncident}.",
+ "Priority": "Prioridad",
+ "Role bindings": "Asignaciones de roles",
+ "Roles the matter is escalated to at this rung.": "Roles a los que se escala el asunto en este peldaño.",
+ "Roles told at this rung; handler is the subject's own performer.": "Roles avisados en este peldaño; handler es la persona encargada del asunto.",
+ "Rungs": "Peldaños",
+ "Stable rung identity, e.g. preBreach:14:calendarDays; derived from trigger, offset and unit when absent.": "Identidad estable del peldaño, p. ej. preBreach:14:calendarDays; si falta, se deriva del disparador, el desplazamiento y la unidad.",
+ "The calendar's stable name, referenced by a timer's calendar_slug.": "El nombre estable del calendario, referenciado por el calendar_slug de un temporizador.",
+ "The closed date, Y-m-d.": "La fecha de cierre, Y-m-d.",
+ "The holiday's name.": "El nombre del festivo.",
+ "The ladder's stable name, referenced by a timer's ladder_slug.": "El nombre estable de la escalera, referenciado por el ladder_slug de un temporizador.",
+ "The unit of the offset: the same set the SLA accepts.": "La unidad del desplazamiento: el mismo conjunto que acepta el SLA.",
+ "The urgency the raised transition carries.": "La urgencia que lleva la transición disparada.",
+ "The weekday (name) on which the date shifts, e.g. sunday for Koningsdag.": "El día de la semana (nombre) en que la fecha se traslada, p. ej. sunday para Koningsdag.",
+ "UUID of the organisation this calendar is configured for. Empty for a shared calendar. The resolution order picks an organisation's calendar when the timer names none.": "UUID de la organización para la que está configurado este calendario. Vacío para un calendario compartido. Si el temporizador no nombra ninguno, el orden de resolución elige el calendario de la organización.",
+ "UUID of the organisation this ladder is the default for. Empty for the shared default.": "UUID de la organización para la que esta escalera es la predeterminada. Vacío para el valor compartido.",
+ "When weekday": "Si cae en",
+ "Whether reaching this rung opens an incident.": "Si alcanzar este peldaño abre una incidencia.",
+ "Why the day is closed.": "Por qué está cerrado ese día.",
+ "Working calendar": "Calendario laboral",
+ "Working hours in one working day. Makes hours and businessDays commensurable.": "Horas trabajadas en un día laborable. Hace comparables las horas y los días laborables.",
+ "Working weekdays": "Días laborables de la semana",
+ "fixed: a month/day; easter: an offset in days from Easter Sunday; observedShift: a month/day with a required observed shift.": "fixed: mes y día; easter: un desplazamiento en días desde el Domingo de Pascua; observedShift: mes y día con traslado obligatorio.",
+ "preBreach fires before the deadline, slaBreached at or after it.": "preBreach se dispara antes del plazo, slaBreached en el plazo o después.",
+ "No such task": "No existe esa tarea",
+ "The task does not exist, or it is not yours to see.": "La tarea no existe o no puede verla.",
+ "Details": "Detalles",
+ "Due": "Vencimiento",
+ "Assignee": "Asignado a",
+ "Requested by": "Solicitado por",
+ "Outcome": "Resultado",
+ "Ready to claim": "Listo para reclamar",
+ "In progress": "En curso",
+ "Terminated": "Terminada",
+ "Normal": "Normal",
+ "Urgent": "Urgente",
+ "Overdue by 1 day": "Atrasada 1 día",
+ "Overdue by {days} days": "Atrasada {days} días",
+ "Due today": "Vence hoy",
+ "Due tomorrow": "Vence mañana",
+ "Due in {days} days": "Vence en {days} días",
+ "Tasks": "Tareas",
+ "Task": "Tarea",
+ "Unassigned, open for claiming": "Sin asignar, abierta para reclamar",
+ "Claim": "Reclamar",
+ "Complete": "Completar",
+ "Complete: {outcome}": "Completar: {outcome}",
+ "Could not load the task": "No se pudo cargar la tarea",
+ "The task refused that action": "La tarea rechazó esa acción"
},
"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"
)
diff --git a/l10n/es.json b/l10n/es.json
index c054d39548..67264bf118 100644
--- a/l10n/es.json
+++ b/l10n/es.json
@@ -1,10 +1,20 @@
{
"translations": {
+ "from amount {amount}": "a partir del importe {amount}",
+ "Gated transition: {transition}": "Transición controlada: {transition}",
+ "Each declared chain provisions an ordered task sequence when its transition is attempted. Approvers decide in their task inbox, not here.": "Cada cadena declarada abre una secuencia ordenada de tareas cuando se intenta la transición. Quienes aprueban deciden en su bandeja de tareas, no aquí.",
+ "Declare x-openregister-approval-chains on this schema to gate a lifecycle transition on approval.": "Declare x-openregister-approval-chains en este esquema para condicionar una transición del ciclo de vida a una aprobación.",
+ "Approval sequences": "Secuencias de aprobación",
"%n entries have no hash yet": "%n entradas aún no tienen hash",
"%n entry has no hash yet": "%n entrada aún no tiene hash",
"(Dolphin required)": "(Se requiere Dolphin)",
+ "No approval chains declared": "No hay cadenas de aprobación declaradas",
"(no subject)": "(sin asunto)",
"(no title)": "(sin título)",
+ "Role {role}": "Rol {role}",
+ "The transition is applied automatically once every step approves.": "La transición se aplica automáticamente cuando todos los pasos están aprobados.",
+ "The requester may not decide their own approval.": "El solicitante no puede decidir sobre su propia aprobación.",
+ "Tier routing on field: {field}": "Enrutamiento por tramos según el campo: {field}",
"(unnamed)": "(sin nombre)",
"(untitled card)": "(tarjeta sin título)",
"({count} selected)": "({count} seleccionados)",
@@ -2801,7 +2811,84 @@
"Se restauró {count} objeto correctamente",
"Se restauraron {count} objetos correctamente",
"Se restauraron {count} objetos correctamente"
- ]
+ ],
+ "A message identity the notification subsystem resolves.": "Una identidad de mensaje que resuelve el sistema de notificaciones.",
+ "Computed non-working-date rules. kind fixed: {month, day, name, observedShift?: {whenWeekday, days}}. kind easter: {offset, name}, offset in days from Easter Sunday. kind observedShift: a fixed date with a required shift.": "Reglas calculadas de días no laborables. Tipo fixed: {month, day, name, observedShift?: {whenWeekday, days}}. Tipo easter: {offset, name}, desplazamiento en días desde el Domingo de Pascua. Tipo observedShift: una fecha fija con traslado obligatorio.",
+ "Date": "Fecha",
+ "Day": "Día",
+ "Day of a fixed or observedShift rule; ignored by an easter rule.": "Día de una regla fixed u observedShift; una regla easter lo ignora.",
+ "Days": "Días",
+ "Days from Easter Sunday for an easter rule; ignored by the other kinds.": "Días desde el Domingo de Pascua para una regla easter; los demás tipos los ignoran.",
+ "Distance from the deadline, in the offset unit.": "Distancia al plazo, en la unidad del desplazamiento.",
+ "Enumerated one-off closures as {date, name}. Allowed alongside rules; refused as the whole calendar.": "Cierres puntuales enumerados como {date, name}. Permitidos junto a reglas; rechazados como calendario completo.",
+ "Escalate to roles": "Roles de escalado",
+ "Escalation ladder": "Escalera de escalado",
+ "Exception dates": "Fechas de excepción",
+ "Hours per working day": "Horas por día laborable",
+ "How many days the observed date shifts, e.g. -1 for the Saturday before.": "Cuántos días se traslada la fecha observada, p. ej. -1 para el sábado anterior.",
+ "Human-readable title.": "Título legible.",
+ "ISO weekdays (1 = Monday, 7 = Sunday) that are working days.": "Días ISO de la semana (1 = lunes, 7 = domingo) que son laborables.",
+ "Kind": "Tipo",
+ "Message": "Mensaje",
+ "Month": "Mes",
+ "Month of a fixed or observedShift rule; ignored by an easter rule.": "Mes de una regla fixed u observedShift; una regla easter lo ignora.",
+ "Non-working-date rules": "Reglas de días no laborables",
+ "Notify roles": "Roles a notificar",
+ "Observed shift": "Traslado del festivo",
+ "Offset": "Desplazamiento",
+ "Offset unit": "Unidad del desplazamiento",
+ "Open incident": "Abrir incidencia",
+ "Optional map from a role name to a concrete recipient descriptor, e.g. {\"teamleader\": \"group:teamleaders\"}. Roles without a binding travel unresolved as role:.": "Mapa opcional de un nombre de rol a un destinatario concreto, p. ej. {\"teamleader\": \"group:teamleaders\"}. Los roles sin asignación viajan sin resolver como role:.",
+ "Optional on a fixed rule, required on observedShift: {whenWeekday: weekday name or ISO 1..7, days: integer}.": "Opcional en una regla fixed, obligatorio en observedShift: {whenWeekday: nombre del día o ISO 1..7, days: entero}.",
+ "Ordered rungs: {key, trigger (preBreach|slaBreached), offset, offsetUnit (hours|businessDays|calendarDays), notifyRole[], escalateToRole[], priority, message, openIncident}.": "Peldaños ordenados: {key, trigger (preBreach|slaBreached), offset, offsetUnit (hours|businessDays|calendarDays), notifyRole[], escalateToRole[], priority, message, openIncident}.",
+ "Priority": "Prioridad",
+ "Role bindings": "Asignaciones de roles",
+ "Roles the matter is escalated to at this rung.": "Roles a los que se escala el asunto en este peldaño.",
+ "Roles told at this rung; handler is the subject's own performer.": "Roles avisados en este peldaño; handler es la persona encargada del asunto.",
+ "Rungs": "Peldaños",
+ "Stable rung identity, e.g. preBreach:14:calendarDays; derived from trigger, offset and unit when absent.": "Identidad estable del peldaño, p. ej. preBreach:14:calendarDays; si falta, se deriva del disparador, el desplazamiento y la unidad.",
+ "The calendar's stable name, referenced by a timer's calendar_slug.": "El nombre estable del calendario, referenciado por el calendar_slug de un temporizador.",
+ "The closed date, Y-m-d.": "La fecha de cierre, Y-m-d.",
+ "The holiday's name.": "El nombre del festivo.",
+ "The ladder's stable name, referenced by a timer's ladder_slug.": "El nombre estable de la escalera, referenciado por el ladder_slug de un temporizador.",
+ "The unit of the offset: the same set the SLA accepts.": "La unidad del desplazamiento: el mismo conjunto que acepta el SLA.",
+ "The urgency the raised transition carries.": "La urgencia que lleva la transición disparada.",
+ "The weekday (name) on which the date shifts, e.g. sunday for Koningsdag.": "El día de la semana (nombre) en que la fecha se traslada, p. ej. sunday para Koningsdag.",
+ "UUID of the organisation this calendar is configured for. Empty for a shared calendar. The resolution order picks an organisation's calendar when the timer names none.": "UUID de la organización para la que está configurado este calendario. Vacío para un calendario compartido. Si el temporizador no nombra ninguno, el orden de resolución elige el calendario de la organización.",
+ "UUID of the organisation this ladder is the default for. Empty for the shared default.": "UUID de la organización para la que esta escalera es la predeterminada. Vacío para el valor compartido.",
+ "When weekday": "Si cae en",
+ "Whether reaching this rung opens an incident.": "Si alcanzar este peldaño abre una incidencia.",
+ "Why the day is closed.": "Por qué está cerrado ese día.",
+ "Working calendar": "Calendario laboral",
+ "Working hours in one working day. Makes hours and businessDays commensurable.": "Horas trabajadas en un día laborable. Hace comparables las horas y los días laborables.",
+ "Working weekdays": "Días laborables de la semana",
+ "fixed: a month/day; easter: an offset in days from Easter Sunday; observedShift: a month/day with a required observed shift.": "fixed: mes y día; easter: un desplazamiento en días desde el Domingo de Pascua; observedShift: mes y día con traslado obligatorio.",
+ "preBreach fires before the deadline, slaBreached at or after it.": "preBreach se dispara antes del plazo, slaBreached en el plazo o después.",
+ "No such task": "No existe esa tarea",
+ "The task does not exist, or it is not yours to see.": "La tarea no existe o no puede verla.",
+ "Details": "Detalles",
+ "Due": "Vencimiento",
+ "Assignee": "Asignado a",
+ "Requested by": "Solicitado por",
+ "Outcome": "Resultado",
+ "Ready to claim": "Listo para reclamar",
+ "In progress": "En curso",
+ "Terminated": "Terminada",
+ "Normal": "Normal",
+ "Urgent": "Urgente",
+ "Overdue by 1 day": "Atrasada 1 día",
+ "Overdue by {days} days": "Atrasada {days} días",
+ "Due today": "Vence hoy",
+ "Due tomorrow": "Vence mañana",
+ "Due in {days} days": "Vence en {days} días",
+ "Tasks": "Tareas",
+ "Task": "Tarea",
+ "Unassigned, open for claiming": "Sin asignar, abierta para reclamar",
+ "Claim": "Reclamar",
+ "Complete": "Completar",
+ "Complete: {outcome}": "Completar: {outcome}",
+ "Could not load the task": "No se pudo cargar la tarea",
+ "The task refused that action": "La tarea rechazó esa acción"
},
"pluralForm": "nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;",
"plurals": {
diff --git a/l10n/et.js b/l10n/et.js
index 5e115f49eb..ecddc4a7a4 100644
--- a/l10n/et.js
+++ b/l10n/et.js
@@ -3,11 +3,21 @@ OC.L10N.register(
{
"3": "3",
"30": "30",
+ "from amount {amount}": "alates summast {amount}",
+ "Gated transition: {transition}": "Valvatud üleminek: {transition}",
+ "Each declared chain provisions an ordered task sequence when its transition is attempted. Approvers decide in their task inbox, not here.": "Iga deklareeritud ahel avab ülemineku proovimisel järjestatud ülesannete jada. Kinnitajad otsustavad oma ülesannete postkastis, mitte siin.",
+ "Declare x-openregister-approval-chains on this schema to gate a lifecycle transition on approval.": "Deklareeri sellel skeemil x-openregister-approval-chains, et seada elutsükli üleminek kinnituse taha.",
+ "Approval sequences": "Kinnitusjadad",
"%n entries have no hash yet": "%n kirjel pole veel räsi",
"%n entry has no hash yet": "%n kirjel pole veel räsi",
"(Dolphin required)": "(Dolphin nõutav)",
+ "No approval chains declared": "Ühtegi kinnitusahelat pole deklareeritud",
"(no subject)": "(teema puudub)",
"(no title)": "(pealkiri puudub)",
+ "Role {role}": "Roll {role}",
+ "The transition is applied automatically once every step approves.": "Üleminek rakendatakse automaatselt, kui iga samm on kinnitatud.",
+ "The requester may not decide their own approval.": "Taotleja ei tohi otsustada omaenda kinnituse üle.",
+ "Tier routing on field: {field}": "Astmeline suunamine välja järgi: {field}",
"(unnamed)": "(nimetu)",
"(untitled card)": "(pealkirjata kaart)",
"({count} selected)": "({count} valitud)",
@@ -2738,7 +2748,84 @@ OC.L10N.register(
"_Object successfully deleted_::_Objects successfully deleted_": ["Objekt edukalt kustutatud","Objektid edukalt kustutatud"],
"_Purge {count} object from database_::_Purge {count} objects from database_": ["Kustuta {count} objekt andmebaasist jäädavalt","Kustuta {count} objekti andmebaasist jäädavalt"],
"_Restore {count} object_::_Restore {count} objects_": ["Taasta {count} objekt","Taasta {count} objekti"],
- "_Successfully restored {count} object_::_Successfully restored {count} objects_": ["{count} objekt edukalt taastatud","{count} objekti edukalt taastatud"]
+ "_Successfully restored {count} object_::_Successfully restored {count} objects_": ["{count} objekt edukalt taastatud","{count} objekti edukalt taastatud"],
+ "A message identity the notification subsystem resolves.": "Sõnumi identiteet, mille teavitussüsteem lahendab.",
+ "Computed non-working-date rules. kind fixed: {month, day, name, observedShift?: {whenWeekday, days}}. kind easter: {offset, name}, offset in days from Easter Sunday. kind observedShift: a fixed date with a required shift.": "Arvutatud puhkepäevade reeglid. Liik fixed: {month, day, name, observedShift?: {whenWeekday, days}}. Liik easter: {offset, name}, nihe päevades ülestõusmispühade pühapäevast. Liik observedShift: kindel kuupäev kohustusliku ülekandega.",
+ "Date": "Kuupäev",
+ "Day": "Päev",
+ "Day of a fixed or observedShift rule; ignored by an easter rule.": "Reegli fixed või observedShift päev; reegel easter eirab seda.",
+ "Days": "Päevad",
+ "Days from Easter Sunday for an easter rule; ignored by the other kinds.": "Päevad ülestõusmispühade pühapäevast reegli easter jaoks; teised liigid eiravad neid.",
+ "Distance from the deadline, in the offset unit.": "Kaugus tähtajast nihke ühikus.",
+ "Enumerated one-off closures as {date, name}. Allowed alongside rules; refused as the whole calendar.": "Ühekordsed sulgemised loeteluna {date, name}. Lubatud reeglite kõrval; keelatud terve kalendrina.",
+ "Escalate to roles": "Eskaleerimise rollid",
+ "Escalation ladder": "Eskaleerimisredel",
+ "Exception dates": "Erandkuupäevad",
+ "Hours per working day": "Tunde tööpäeva kohta",
+ "How many days the observed date shifts, e.g. -1 for the Saturday before.": "Mitu päeva tähistatav kuupäev üle kandub, nt -1 eelmise laupäeva jaoks.",
+ "Human-readable title.": "Loetav pealkiri.",
+ "ISO weekdays (1 = Monday, 7 = Sunday) that are working days.": "ISO nädalapäevad (1 = esmaspäev, 7 = pühapäev), mis on tööpäevad.",
+ "Kind": "Liik",
+ "Message": "Sõnum",
+ "Month": "Kuu",
+ "Month of a fixed or observedShift rule; ignored by an easter rule.": "Reegli fixed või observedShift kuu; reegel easter eirab seda.",
+ "Non-working-date rules": "Puhkepäevade reeglid",
+ "Notify roles": "Teavitatavad rollid",
+ "Observed shift": "Püha ülekandmine",
+ "Offset": "Nihe",
+ "Offset unit": "Nihke ühik",
+ "Open incident": "Ava intsident",
+ "Optional map from a role name to a concrete recipient descriptor, e.g. {\"teamleader\": \"group:teamleaders\"}. Roles without a binding travel unresolved as role:.": "Valikuline kaardistus rollinimest konkreetse saajani, nt {\"teamleader\": \"group:teamleaders\"}. Seoseta rollid liiguvad lahendamata kujul role:.",
+ "Optional on a fixed rule, required on observedShift: {whenWeekday: weekday name or ISO 1..7, days: integer}.": "Valikuline reegli fixed puhul, kohustuslik observedShift puhul: {whenWeekday: päeva nimi või ISO 1..7, days: täisarv}.",
+ "Ordered rungs: {key, trigger (preBreach|slaBreached), offset, offsetUnit (hours|businessDays|calendarDays), notifyRole[], escalateToRole[], priority, message, openIncident}.": "Järjestatud pulgad: {key, trigger (preBreach|slaBreached), offset, offsetUnit (hours|businessDays|calendarDays), notifyRole[], escalateToRole[], priority, message, openIncident}.",
+ "Priority": "Prioriteet",
+ "Role bindings": "Rolliseosed",
+ "Roles the matter is escalated to at this rung.": "Rollid, kellele asi sellel pulgal eskaleeritakse.",
+ "Roles told at this rung; handler is the subject's own performer.": "Sellel pulgal teavitatavad rollid; handler on asja menetleja.",
+ "Rungs": "Pulgad",
+ "Stable rung identity, e.g. preBreach:14:calendarDays; derived from trigger, offset and unit when absent.": "Pulga püsiv identiteet, nt preBreach:14:calendarDays; puudumisel tuletatakse päästikust, nihkest ja ühikust.",
+ "The calendar's stable name, referenced by a timer's calendar_slug.": "Kalendri püsinimi, millele taimer viitab calendar_slug kaudu.",
+ "The closed date, Y-m-d.": "Suletud kuupäev, Y-m-d.",
+ "The holiday's name.": "Püha nimi.",
+ "The ladder's stable name, referenced by a timer's ladder_slug.": "Redeli püsinimi, millele taimer viitab ladder_slug kaudu.",
+ "The unit of the offset: the same set the SLA accepts.": "Nihke ühik: sama hulk, mida SLA aktsepteerib.",
+ "The urgency the raised transition carries.": "Käivitatud ülemineku kiireloomulisus.",
+ "The weekday (name) on which the date shifts, e.g. sunday for Koningsdag.": "Nädalapäev (nimi), mille korral kuupäev kandub üle, nt sunday Koningsdagi puhul.",
+ "UUID of the organisation this calendar is configured for. Empty for a shared calendar. The resolution order picks an organisation's calendar when the timer names none.": "Organisatsiooni UUID, mille jaoks see kalender on seadistatud. Tühi jagatud kalendri puhul. Kui taimer ühtegi ei nimeta, valib lahendusjärjekord organisatsiooni kalendri.",
+ "UUID of the organisation this ladder is the default for. Empty for the shared default.": "Organisatsiooni UUID, mille jaoks see redel on vaikimisi. Tühi jagatud vaikeväärtuse puhul.",
+ "When weekday": "Kui langeb päevale",
+ "Whether reaching this rung opens an incident.": "Kas selle pulga saavutamine avab intsidendi.",
+ "Why the day is closed.": "Miks see päev on suletud.",
+ "Working calendar": "Töökalender",
+ "Working hours in one working day. Makes hours and businessDays commensurable.": "Töötunnid ühes tööpäevas. Muudab tunnid ja tööpäevad võrreldavaks.",
+ "Working weekdays": "Nädala tööpäevad",
+ "fixed: a month/day; easter: an offset in days from Easter Sunday; observedShift: a month/day with a required observed shift.": "fixed: kuu ja päev; easter: nihe päevades ülestõusmispühade pühapäevast; observedShift: kuu ja päev kohustusliku ülekandega.",
+ "preBreach fires before the deadline, slaBreached at or after it.": "preBreach käivitub enne tähtaega, slaBreached tähtajal või pärast seda.",
+ "No such task": "Sellist ülesannet pole",
+ "The task does not exist, or it is not yours to see.": "Ülesannet pole olemas või teil pole õigust seda näha.",
+ "Details": "Üksikasjad",
+ "Due": "Tähtaeg",
+ "Assignee": "Vastutaja",
+ "Requested by": "Taotleja",
+ "Outcome": "Tulemus",
+ "Ready to claim": "Valmis võtmiseks",
+ "In progress": "Pooleli",
+ "Terminated": "Lõpetatud",
+ "Normal": "Tavaline",
+ "Urgent": "Kiireloomuline",
+ "Overdue by 1 day": "1 päev üle tähtaja",
+ "Overdue by {days} days": "{days} päeva üle tähtaja",
+ "Due today": "Tähtaeg täna",
+ "Due tomorrow": "Tähtaeg homme",
+ "Due in {days} days": "Tähtaeg {days} päeva pärast",
+ "Tasks": "Ülesanded",
+ "Task": "Ülesanne",
+ "Unassigned, open for claiming": "Määramata, avatud võtmiseks",
+ "Claim": "Võta endale",
+ "Complete": "Lõpeta",
+ "Complete: {outcome}": "Lõpeta: {outcome}",
+ "Could not load the task": "Ülesannet ei õnnestunud laadida",
+ "The task refused that action": "Ülesanne keeldus sellest toimingust"
},
"nplurals=2; plural=(n != 1);"
)
diff --git a/l10n/et.json b/l10n/et.json
index 14a0fd06cd..7430dd0f6b 100644
--- a/l10n/et.json
+++ b/l10n/et.json
@@ -1,10 +1,20 @@
{
"translations": {
+ "from amount {amount}": "alates summast {amount}",
+ "Gated transition: {transition}": "Valvatud üleminek: {transition}",
+ "Each declared chain provisions an ordered task sequence when its transition is attempted. Approvers decide in their task inbox, not here.": "Iga deklareeritud ahel avab ülemineku proovimisel järjestatud ülesannete jada. Kinnitajad otsustavad oma ülesannete postkastis, mitte siin.",
+ "Declare x-openregister-approval-chains on this schema to gate a lifecycle transition on approval.": "Deklareeri sellel skeemil x-openregister-approval-chains, et seada elutsükli üleminek kinnituse taha.",
+ "Approval sequences": "Kinnitusjadad",
"%n entries have no hash yet": "%n kirjel pole veel räsi",
"%n entry has no hash yet": "%n kirjel pole veel räsi",
"(Dolphin required)": "(Dolphin nõutav)",
+ "No approval chains declared": "Ühtegi kinnitusahelat pole deklareeritud",
"(no subject)": "(teema puudub)",
"(no title)": "(pealkiri puudub)",
+ "Role {role}": "Roll {role}",
+ "The transition is applied automatically once every step approves.": "Üleminek rakendatakse automaatselt, kui iga samm on kinnitatud.",
+ "The requester may not decide their own approval.": "Taotleja ei tohi otsustada omaenda kinnituse üle.",
+ "Tier routing on field: {field}": "Astmeline suunamine välja järgi: {field}",
"(unnamed)": "(nimetu)",
"(untitled card)": "(pealkirjata kaart)",
"({count} selected)": "({count} valitud)",
@@ -2785,7 +2795,84 @@
"_Successfully restored {count} object_::_Successfully restored {count} objects_": [
"{count} objekt edukalt taastatud",
"{count} objekti edukalt taastatud"
- ]
+ ],
+ "A message identity the notification subsystem resolves.": "Sõnumi identiteet, mille teavitussüsteem lahendab.",
+ "Computed non-working-date rules. kind fixed: {month, day, name, observedShift?: {whenWeekday, days}}. kind easter: {offset, name}, offset in days from Easter Sunday. kind observedShift: a fixed date with a required shift.": "Arvutatud puhkepäevade reeglid. Liik fixed: {month, day, name, observedShift?: {whenWeekday, days}}. Liik easter: {offset, name}, nihe päevades ülestõusmispühade pühapäevast. Liik observedShift: kindel kuupäev kohustusliku ülekandega.",
+ "Date": "Kuupäev",
+ "Day": "Päev",
+ "Day of a fixed or observedShift rule; ignored by an easter rule.": "Reegli fixed või observedShift päev; reegel easter eirab seda.",
+ "Days": "Päevad",
+ "Days from Easter Sunday for an easter rule; ignored by the other kinds.": "Päevad ülestõusmispühade pühapäevast reegli easter jaoks; teised liigid eiravad neid.",
+ "Distance from the deadline, in the offset unit.": "Kaugus tähtajast nihke ühikus.",
+ "Enumerated one-off closures as {date, name}. Allowed alongside rules; refused as the whole calendar.": "Ühekordsed sulgemised loeteluna {date, name}. Lubatud reeglite kõrval; keelatud terve kalendrina.",
+ "Escalate to roles": "Eskaleerimise rollid",
+ "Escalation ladder": "Eskaleerimisredel",
+ "Exception dates": "Erandkuupäevad",
+ "Hours per working day": "Tunde tööpäeva kohta",
+ "How many days the observed date shifts, e.g. -1 for the Saturday before.": "Mitu päeva tähistatav kuupäev üle kandub, nt -1 eelmise laupäeva jaoks.",
+ "Human-readable title.": "Loetav pealkiri.",
+ "ISO weekdays (1 = Monday, 7 = Sunday) that are working days.": "ISO nädalapäevad (1 = esmaspäev, 7 = pühapäev), mis on tööpäevad.",
+ "Kind": "Liik",
+ "Message": "Sõnum",
+ "Month": "Kuu",
+ "Month of a fixed or observedShift rule; ignored by an easter rule.": "Reegli fixed või observedShift kuu; reegel easter eirab seda.",
+ "Non-working-date rules": "Puhkepäevade reeglid",
+ "Notify roles": "Teavitatavad rollid",
+ "Observed shift": "Püha ülekandmine",
+ "Offset": "Nihe",
+ "Offset unit": "Nihke ühik",
+ "Open incident": "Ava intsident",
+ "Optional map from a role name to a concrete recipient descriptor, e.g. {\"teamleader\": \"group:teamleaders\"}. Roles without a binding travel unresolved as role:.": "Valikuline kaardistus rollinimest konkreetse saajani, nt {\"teamleader\": \"group:teamleaders\"}. Seoseta rollid liiguvad lahendamata kujul role:.",
+ "Optional on a fixed rule, required on observedShift: {whenWeekday: weekday name or ISO 1..7, days: integer}.": "Valikuline reegli fixed puhul, kohustuslik observedShift puhul: {whenWeekday: päeva nimi või ISO 1..7, days: täisarv}.",
+ "Ordered rungs: {key, trigger (preBreach|slaBreached), offset, offsetUnit (hours|businessDays|calendarDays), notifyRole[], escalateToRole[], priority, message, openIncident}.": "Järjestatud pulgad: {key, trigger (preBreach|slaBreached), offset, offsetUnit (hours|businessDays|calendarDays), notifyRole[], escalateToRole[], priority, message, openIncident}.",
+ "Priority": "Prioriteet",
+ "Role bindings": "Rolliseosed",
+ "Roles the matter is escalated to at this rung.": "Rollid, kellele asi sellel pulgal eskaleeritakse.",
+ "Roles told at this rung; handler is the subject's own performer.": "Sellel pulgal teavitatavad rollid; handler on asja menetleja.",
+ "Rungs": "Pulgad",
+ "Stable rung identity, e.g. preBreach:14:calendarDays; derived from trigger, offset and unit when absent.": "Pulga püsiv identiteet, nt preBreach:14:calendarDays; puudumisel tuletatakse päästikust, nihkest ja ühikust.",
+ "The calendar's stable name, referenced by a timer's calendar_slug.": "Kalendri püsinimi, millele taimer viitab calendar_slug kaudu.",
+ "The closed date, Y-m-d.": "Suletud kuupäev, Y-m-d.",
+ "The holiday's name.": "Püha nimi.",
+ "The ladder's stable name, referenced by a timer's ladder_slug.": "Redeli püsinimi, millele taimer viitab ladder_slug kaudu.",
+ "The unit of the offset: the same set the SLA accepts.": "Nihke ühik: sama hulk, mida SLA aktsepteerib.",
+ "The urgency the raised transition carries.": "Käivitatud ülemineku kiireloomulisus.",
+ "The weekday (name) on which the date shifts, e.g. sunday for Koningsdag.": "Nädalapäev (nimi), mille korral kuupäev kandub üle, nt sunday Koningsdagi puhul.",
+ "UUID of the organisation this calendar is configured for. Empty for a shared calendar. The resolution order picks an organisation's calendar when the timer names none.": "Organisatsiooni UUID, mille jaoks see kalender on seadistatud. Tühi jagatud kalendri puhul. Kui taimer ühtegi ei nimeta, valib lahendusjärjekord organisatsiooni kalendri.",
+ "UUID of the organisation this ladder is the default for. Empty for the shared default.": "Organisatsiooni UUID, mille jaoks see redel on vaikimisi. Tühi jagatud vaikeväärtuse puhul.",
+ "When weekday": "Kui langeb päevale",
+ "Whether reaching this rung opens an incident.": "Kas selle pulga saavutamine avab intsidendi.",
+ "Why the day is closed.": "Miks see päev on suletud.",
+ "Working calendar": "Töökalender",
+ "Working hours in one working day. Makes hours and businessDays commensurable.": "Töötunnid ühes tööpäevas. Muudab tunnid ja tööpäevad võrreldavaks.",
+ "Working weekdays": "Nädala tööpäevad",
+ "fixed: a month/day; easter: an offset in days from Easter Sunday; observedShift: a month/day with a required observed shift.": "fixed: kuu ja päev; easter: nihe päevades ülestõusmispühade pühapäevast; observedShift: kuu ja päev kohustusliku ülekandega.",
+ "preBreach fires before the deadline, slaBreached at or after it.": "preBreach käivitub enne tähtaega, slaBreached tähtajal või pärast seda.",
+ "No such task": "Sellist ülesannet pole",
+ "The task does not exist, or it is not yours to see.": "Ülesannet pole olemas või teil pole õigust seda näha.",
+ "Details": "Üksikasjad",
+ "Due": "Tähtaeg",
+ "Assignee": "Vastutaja",
+ "Requested by": "Taotleja",
+ "Outcome": "Tulemus",
+ "Ready to claim": "Valmis võtmiseks",
+ "In progress": "Pooleli",
+ "Terminated": "Lõpetatud",
+ "Normal": "Tavaline",
+ "Urgent": "Kiireloomuline",
+ "Overdue by 1 day": "1 päev üle tähtaja",
+ "Overdue by {days} days": "{days} päeva üle tähtaja",
+ "Due today": "Tähtaeg täna",
+ "Due tomorrow": "Tähtaeg homme",
+ "Due in {days} days": "Tähtaeg {days} päeva pärast",
+ "Tasks": "Ülesanded",
+ "Task": "Ülesanne",
+ "Unassigned, open for claiming": "Määramata, avatud võtmiseks",
+ "Claim": "Võta endale",
+ "Complete": "Lõpeta",
+ "Complete: {outcome}": "Lõpeta: {outcome}",
+ "Could not load the task": "Ülesannet ei õnnestunud laadida",
+ "The task refused that action": "Ülesanne keeldus sellest toimingust"
},
"pluralForm": "nplurals=2; plural=(n != 1);",
"plurals": {
diff --git a/l10n/fi.js b/l10n/fi.js
index ff4493ddf5..2a9ad14f69 100644
--- a/l10n/fi.js
+++ b/l10n/fi.js
@@ -3,11 +3,21 @@ OC.L10N.register(
{
"3": "3",
"30": "30",
+ "from amount {amount}": "summasta {amount} alkaen",
+ "Gated transition: {transition}": "Valvottu siirtymä: {transition}",
+ "Each declared chain provisions an ordered task sequence when its transition is attempted. Approvers decide in their task inbox, not here.": "Jokainen määritetty ketju avaa järjestetyn tehtäväsarjan, kun siirtymää yritetään. Hyväksyjät päättävät tehtäväpostilaatikossaan, eivät täällä.",
+ "Declare x-openregister-approval-chains on this schema to gate a lifecycle transition on approval.": "Määritä x-openregister-approval-chains tähän skeemaan, jotta elinkaarisiirtymä vaatii hyväksynnän.",
+ "Approval sequences": "Hyväksyntäsarjat",
"%n entries have no hash yet": "%n merkinnällä ei ole vielä tiivistettä",
"%n entry has no hash yet": "%n merkinnällä ei ole vielä tiivistettä",
"(Dolphin required)": "(Dolphin vaaditaan)",
+ "No approval chains declared": "Hyväksyntäketjuja ei ole määritetty",
"(no subject)": "(ei aihetta)",
"(no title)": "(ei otsikkoa)",
+ "Role {role}": "Rooli {role}",
+ "The transition is applied automatically once every step approves.": "Siirtymä toteutetaan automaattisesti, kun jokainen vaihe on hyväksytty.",
+ "The requester may not decide their own approval.": "Pyytäjä ei saa päättää omasta hyväksynnästään.",
+ "Tier routing on field: {field}": "Porrastettu reititys kentän mukaan: {field}",
"(unnamed)": "(nimetön)",
"(untitled card)": "(nimetön kortti)",
"({count} selected)": "({count} valittu)",
@@ -2738,7 +2748,84 @@ OC.L10N.register(
"_Object successfully deleted_::_Objects successfully deleted_": ["Objekti poistettu onnistuneesti","Objektit poistettu onnistuneesti"],
"_Purge {count} object from database_::_Purge {count} objects from database_": ["Tyhjennä {count} objekti tietokannasta","Tyhjennä {count} objektia tietokannasta"],
"_Restore {count} object_::_Restore {count} objects_": ["Palauta {count} objekti","Palauta {count} objektia"],
- "_Successfully restored {count} object_::_Successfully restored {count} objects_": ["Palautettiin onnistuneesti {count} objekti","Palautettiin onnistuneesti {count} objektia"]
+ "_Successfully restored {count} object_::_Successfully restored {count} objects_": ["Palautettiin onnistuneesti {count} objekti","Palautettiin onnistuneesti {count} objektia"],
+ "A message identity the notification subsystem resolves.": "A message identity the notification subsystem resolves.",
+ "Computed non-working-date rules. kind fixed: {month, day, name, observedShift?: {whenWeekday, days}}. kind easter: {offset, name}, offset in days from Easter Sunday. kind observedShift: a fixed date with a required shift.": "Computed non-working-date rules. kind fixed: {month, day, name, observedShift?: {whenWeekday, days}}. kind easter: {offset, name}, offset in days from Easter Sunday. kind observedShift: a fixed date with a required shift.",
+ "Date": "Date",
+ "Day": "Day",
+ "Day of a fixed or observedShift rule; ignored by an easter rule.": "Day of a fixed or observedShift rule; ignored by an easter rule.",
+ "Days": "Days",
+ "Days from Easter Sunday for an easter rule; ignored by the other kinds.": "Days from Easter Sunday for an easter rule; ignored by the other kinds.",
+ "Distance from the deadline, in the offset unit.": "Distance from the deadline, in the offset unit.",
+ "Enumerated one-off closures as {date, name}. Allowed alongside rules; refused as the whole calendar.": "Enumerated one-off closures as {date, name}. Allowed alongside rules; refused as the whole calendar.",
+ "Escalate to roles": "Escalate to roles",
+ "Escalation ladder": "Escalation ladder",
+ "Exception dates": "Exception dates",
+ "Hours per working day": "Hours per working day",
+ "How many days the observed date shifts, e.g. -1 for the Saturday before.": "How many days the observed date shifts, e.g. -1 for the Saturday before.",
+ "Human-readable title.": "Human-readable title.",
+ "ISO weekdays (1 = Monday, 7 = Sunday) that are working days.": "ISO weekdays (1 = Monday, 7 = Sunday) that are working days.",
+ "Kind": "Kind",
+ "Message": "Message",
+ "Month": "Month",
+ "Month of a fixed or observedShift rule; ignored by an easter rule.": "Month of a fixed or observedShift rule; ignored by an easter rule.",
+ "Non-working-date rules": "Non-working-date rules",
+ "Notify roles": "Notify roles",
+ "Observed shift": "Observed shift",
+ "Offset": "Offset",
+ "Offset unit": "Offset unit",
+ "Open incident": "Open incident",
+ "Optional map from a role name to a concrete recipient descriptor, e.g. {\"teamleader\": \"group:teamleaders\"}. Roles without a binding travel unresolved as role:.": "Optional map from a role name to a concrete recipient descriptor, e.g. {\"teamleader\": \"group:teamleaders\"}. Roles without a binding travel unresolved as role:.",
+ "Optional on a fixed rule, required on observedShift: {whenWeekday: weekday name or ISO 1..7, days: integer}.": "Optional on a fixed rule, required on observedShift: {whenWeekday: weekday name or ISO 1..7, days: integer}.",
+ "Ordered rungs: {key, trigger (preBreach|slaBreached), offset, offsetUnit (hours|businessDays|calendarDays), notifyRole[], escalateToRole[], priority, message, openIncident}.": "Ordered rungs: {key, trigger (preBreach|slaBreached), offset, offsetUnit (hours|businessDays|calendarDays), notifyRole[], escalateToRole[], priority, message, openIncident}.",
+ "Priority": "Priority",
+ "Role bindings": "Role bindings",
+ "Roles the matter is escalated to at this rung.": "Roles the matter is escalated to at this rung.",
+ "Roles told at this rung; handler is the subject's own performer.": "Roles told at this rung; handler is the subject's own performer.",
+ "Rungs": "Rungs",
+ "Stable rung identity, e.g. preBreach:14:calendarDays; derived from trigger, offset and unit when absent.": "Stable rung identity, e.g. preBreach:14:calendarDays; derived from trigger, offset and unit when absent.",
+ "The calendar's stable name, referenced by a timer's calendar_slug.": "The calendar's stable name, referenced by a timer's calendar_slug.",
+ "The closed date, Y-m-d.": "The closed date, Y-m-d.",
+ "The holiday's name.": "The holiday's name.",
+ "The ladder's stable name, referenced by a timer's ladder_slug.": "The ladder's stable name, referenced by a timer's ladder_slug.",
+ "The unit of the offset: the same set the SLA accepts.": "The unit of the offset: the same set the SLA accepts.",
+ "The urgency the raised transition carries.": "The urgency the raised transition carries.",
+ "The weekday (name) on which the date shifts, e.g. sunday for Koningsdag.": "The weekday (name) on which the date shifts, e.g. sunday for Koningsdag.",
+ "UUID of the organisation this calendar is configured for. Empty for a shared calendar. The resolution order picks an organisation's calendar when the timer names none.": "UUID of the organisation this calendar is configured for. Empty for a shared calendar. The resolution order picks an organisation's calendar when the timer names none.",
+ "UUID of the organisation this ladder is the default for. Empty for the shared default.": "UUID of the organisation this ladder is the default for. Empty for the shared default.",
+ "When weekday": "When weekday",
+ "Whether reaching this rung opens an incident.": "Whether reaching this rung opens an incident.",
+ "Why the day is closed.": "Why the day is closed.",
+ "Working calendar": "Working calendar",
+ "Working hours in one working day. Makes hours and businessDays commensurable.": "Working hours in one working day. Makes hours and businessDays commensurable.",
+ "Working weekdays": "Working weekdays",
+ "fixed: a month/day; easter: an offset in days from Easter Sunday; observedShift: a month/day with a required observed shift.": "fixed: a month/day; easter: an offset in days from Easter Sunday; observedShift: a month/day with a required observed shift.",
+ "preBreach fires before the deadline, slaBreached at or after it.": "preBreach fires before the deadline, slaBreached at or after it.",
+ "No such task": "Tehtävää ei löydy",
+ "The task does not exist, or it is not yours to see.": "Tehtävää ei ole, tai sinulla ei ole oikeutta nähdä sitä.",
+ "Details": "Tiedot",
+ "Due": "Määräaika",
+ "Assignee": "Vastuuhenkilö",
+ "Requested by": "Pyytäjä",
+ "Outcome": "Lopputulos",
+ "Ready to claim": "Valmis otettavaksi",
+ "In progress": "Käynnissä",
+ "Terminated": "Päätetty",
+ "Normal": "Normaali",
+ "Urgent": "Kiireellinen",
+ "Overdue by 1 day": "1 päivän myöhässä",
+ "Overdue by {days} days": "{days} päivää myöhässä",
+ "Due today": "Määräaika tänään",
+ "Due tomorrow": "Määräaika huomenna",
+ "Due in {days} days": "Määräaika {days} päivän päästä",
+ "Tasks": "Tehtävät",
+ "Task": "Tehtävä",
+ "Unassigned, open for claiming": "Ei vastuuhenkilöä, vapaasti otettavissa",
+ "Claim": "Ota itselle",
+ "Complete": "Valmis",
+ "Complete: {outcome}": "Valmis: {outcome}",
+ "Could not load the task": "Tehtävän lataus epäonnistui",
+ "The task refused that action": "Tehtävä hylkäsi toiminnon"
},
"nplurals=2; plural=(n != 1);"
)
diff --git a/l10n/fi.json b/l10n/fi.json
index 550c749be7..723754846d 100644
--- a/l10n/fi.json
+++ b/l10n/fi.json
@@ -1,10 +1,20 @@
{
"translations": {
+ "from amount {amount}": "summasta {amount} alkaen",
+ "Gated transition: {transition}": "Valvottu siirtymä: {transition}",
+ "Each declared chain provisions an ordered task sequence when its transition is attempted. Approvers decide in their task inbox, not here.": "Jokainen määritetty ketju avaa järjestetyn tehtäväsarjan, kun siirtymää yritetään. Hyväksyjät päättävät tehtäväpostilaatikossaan, eivät täällä.",
+ "Declare x-openregister-approval-chains on this schema to gate a lifecycle transition on approval.": "Määritä x-openregister-approval-chains tähän skeemaan, jotta elinkaarisiirtymä vaatii hyväksynnän.",
+ "Approval sequences": "Hyväksyntäsarjat",
"%n entries have no hash yet": "%n merkinnällä ei ole vielä tiivistettä",
"%n entry has no hash yet": "%n merkinnällä ei ole vielä tiivistettä",
"(Dolphin required)": "(Dolphin vaaditaan)",
+ "No approval chains declared": "Hyväksyntäketjuja ei ole määritetty",
"(no subject)": "(ei aihetta)",
"(no title)": "(ei otsikkoa)",
+ "Role {role}": "Rooli {role}",
+ "The transition is applied automatically once every step approves.": "Siirtymä toteutetaan automaattisesti, kun jokainen vaihe on hyväksytty.",
+ "The requester may not decide their own approval.": "Pyytäjä ei saa päättää omasta hyväksynnästään.",
+ "Tier routing on field: {field}": "Porrastettu reititys kentän mukaan: {field}",
"(unnamed)": "(nimetön)",
"(untitled card)": "(nimetön kortti)",
"({count} selected)": "({count} valittu)",
@@ -2785,7 +2795,84 @@
"_Successfully restored {count} object_::_Successfully restored {count} objects_": [
"Palautettiin onnistuneesti {count} objekti",
"Palautettiin onnistuneesti {count} objektia"
- ]
+ ],
+ "A message identity the notification subsystem resolves.": "A message identity the notification subsystem resolves.",
+ "Computed non-working-date rules. kind fixed: {month, day, name, observedShift?: {whenWeekday, days}}. kind easter: {offset, name}, offset in days from Easter Sunday. kind observedShift: a fixed date with a required shift.": "Computed non-working-date rules. kind fixed: {month, day, name, observedShift?: {whenWeekday, days}}. kind easter: {offset, name}, offset in days from Easter Sunday. kind observedShift: a fixed date with a required shift.",
+ "Date": "Date",
+ "Day": "Day",
+ "Day of a fixed or observedShift rule; ignored by an easter rule.": "Day of a fixed or observedShift rule; ignored by an easter rule.",
+ "Days": "Days",
+ "Days from Easter Sunday for an easter rule; ignored by the other kinds.": "Days from Easter Sunday for an easter rule; ignored by the other kinds.",
+ "Distance from the deadline, in the offset unit.": "Distance from the deadline, in the offset unit.",
+ "Enumerated one-off closures as {date, name}. Allowed alongside rules; refused as the whole calendar.": "Enumerated one-off closures as {date, name}. Allowed alongside rules; refused as the whole calendar.",
+ "Escalate to roles": "Escalate to roles",
+ "Escalation ladder": "Escalation ladder",
+ "Exception dates": "Exception dates",
+ "Hours per working day": "Hours per working day",
+ "How many days the observed date shifts, e.g. -1 for the Saturday before.": "How many days the observed date shifts, e.g. -1 for the Saturday before.",
+ "Human-readable title.": "Human-readable title.",
+ "ISO weekdays (1 = Monday, 7 = Sunday) that are working days.": "ISO weekdays (1 = Monday, 7 = Sunday) that are working days.",
+ "Kind": "Kind",
+ "Message": "Message",
+ "Month": "Month",
+ "Month of a fixed or observedShift rule; ignored by an easter rule.": "Month of a fixed or observedShift rule; ignored by an easter rule.",
+ "Non-working-date rules": "Non-working-date rules",
+ "Notify roles": "Notify roles",
+ "Observed shift": "Observed shift",
+ "Offset": "Offset",
+ "Offset unit": "Offset unit",
+ "Open incident": "Open incident",
+ "Optional map from a role name to a concrete recipient descriptor, e.g. {\"teamleader\": \"group:teamleaders\"}. Roles without a binding travel unresolved as role:.": "Optional map from a role name to a concrete recipient descriptor, e.g. {\"teamleader\": \"group:teamleaders\"}. Roles without a binding travel unresolved as role:.",
+ "Optional on a fixed rule, required on observedShift: {whenWeekday: weekday name or ISO 1..7, days: integer}.": "Optional on a fixed rule, required on observedShift: {whenWeekday: weekday name or ISO 1..7, days: integer}.",
+ "Ordered rungs: {key, trigger (preBreach|slaBreached), offset, offsetUnit (hours|businessDays|calendarDays), notifyRole[], escalateToRole[], priority, message, openIncident}.": "Ordered rungs: {key, trigger (preBreach|slaBreached), offset, offsetUnit (hours|businessDays|calendarDays), notifyRole[], escalateToRole[], priority, message, openIncident}.",
+ "Priority": "Priority",
+ "Role bindings": "Role bindings",
+ "Roles the matter is escalated to at this rung.": "Roles the matter is escalated to at this rung.",
+ "Roles told at this rung; handler is the subject's own performer.": "Roles told at this rung; handler is the subject's own performer.",
+ "Rungs": "Rungs",
+ "Stable rung identity, e.g. preBreach:14:calendarDays; derived from trigger, offset and unit when absent.": "Stable rung identity, e.g. preBreach:14:calendarDays; derived from trigger, offset and unit when absent.",
+ "The calendar's stable name, referenced by a timer's calendar_slug.": "The calendar's stable name, referenced by a timer's calendar_slug.",
+ "The closed date, Y-m-d.": "The closed date, Y-m-d.",
+ "The holiday's name.": "The holiday's name.",
+ "The ladder's stable name, referenced by a timer's ladder_slug.": "The ladder's stable name, referenced by a timer's ladder_slug.",
+ "The unit of the offset: the same set the SLA accepts.": "The unit of the offset: the same set the SLA accepts.",
+ "The urgency the raised transition carries.": "The urgency the raised transition carries.",
+ "The weekday (name) on which the date shifts, e.g. sunday for Koningsdag.": "The weekday (name) on which the date shifts, e.g. sunday for Koningsdag.",
+ "UUID of the organisation this calendar is configured for. Empty for a shared calendar. The resolution order picks an organisation's calendar when the timer names none.": "UUID of the organisation this calendar is configured for. Empty for a shared calendar. The resolution order picks an organisation's calendar when the timer names none.",
+ "UUID of the organisation this ladder is the default for. Empty for the shared default.": "UUID of the organisation this ladder is the default for. Empty for the shared default.",
+ "When weekday": "When weekday",
+ "Whether reaching this rung opens an incident.": "Whether reaching this rung opens an incident.",
+ "Why the day is closed.": "Why the day is closed.",
+ "Working calendar": "Working calendar",
+ "Working hours in one working day. Makes hours and businessDays commensurable.": "Working hours in one working day. Makes hours and businessDays commensurable.",
+ "Working weekdays": "Working weekdays",
+ "fixed: a month/day; easter: an offset in days from Easter Sunday; observedShift: a month/day with a required observed shift.": "fixed: a month/day; easter: an offset in days from Easter Sunday; observedShift: a month/day with a required observed shift.",
+ "preBreach fires before the deadline, slaBreached at or after it.": "preBreach fires before the deadline, slaBreached at or after it.",
+ "No such task": "Tehtävää ei löydy",
+ "The task does not exist, or it is not yours to see.": "Tehtävää ei ole, tai sinulla ei ole oikeutta nähdä sitä.",
+ "Details": "Tiedot",
+ "Due": "Määräaika",
+ "Assignee": "Vastuuhenkilö",
+ "Requested by": "Pyytäjä",
+ "Outcome": "Lopputulos",
+ "Ready to claim": "Valmis otettavaksi",
+ "In progress": "Käynnissä",
+ "Terminated": "Päätetty",
+ "Normal": "Normaali",
+ "Urgent": "Kiireellinen",
+ "Overdue by 1 day": "1 päivän myöhässä",
+ "Overdue by {days} days": "{days} päivää myöhässä",
+ "Due today": "Määräaika tänään",
+ "Due tomorrow": "Määräaika huomenna",
+ "Due in {days} days": "Määräaika {days} päivän päästä",
+ "Tasks": "Tehtävät",
+ "Task": "Tehtävä",
+ "Unassigned, open for claiming": "Ei vastuuhenkilöä, vapaasti otettavissa",
+ "Claim": "Ota itselle",
+ "Complete": "Valmis",
+ "Complete: {outcome}": "Valmis: {outcome}",
+ "Could not load the task": "Tehtävän lataus epäonnistui",
+ "The task refused that action": "Tehtävä hylkäsi toiminnon"
},
"pluralForm": "nplurals=2; plural=(n != 1);",
"plurals": {
diff --git a/l10n/fr.js b/l10n/fr.js
index 4319250504..0a376c009f 100644
--- a/l10n/fr.js
+++ b/l10n/fr.js
@@ -3,11 +3,21 @@ OC.L10N.register(
{
"3": "3",
"30": "30",
+ "from amount {amount}": "à partir du montant {amount}",
+ "Gated transition: {transition}": "Transition contrôlée : {transition}",
+ "Each declared chain provisions an ordered task sequence when its transition is attempted. Approvers decide in their task inbox, not here.": "Chaque chaîne déclarée ouvre une séquence de tâches ordonnée dès que la transition est tentée. Les approbateurs décident dans leur boîte de tâches, pas ici.",
+ "Declare x-openregister-approval-chains on this schema to gate a lifecycle transition on approval.": "Déclarez x-openregister-approval-chains sur ce schéma pour conditionner une transition de cycle de vie à une approbation.",
+ "Approval sequences": "Séquences d'approbation",
"%n entries have no hash yet": "%n entrées n'ont pas encore de hachage",
"%n entry has no hash yet": "%n entrée n'a pas encore de hachage",
"(Dolphin required)": "(Dolphin requis)",
+ "No approval chains declared": "Aucune chaîne d'approbation déclarée",
"(no subject)": "(sans objet)",
"(no title)": "(sans titre)",
+ "Role {role}": "Rôle {role}",
+ "The transition is applied automatically once every step approves.": "La transition est appliquée automatiquement dès que chaque étape est approuvée.",
+ "The requester may not decide their own approval.": "Le demandeur ne peut pas décider de sa propre approbation.",
+ "Tier routing on field: {field}": "Routage par palier sur le champ : {field}",
"(unnamed)": "(sans nom)",
"(untitled card)": "(carte sans titre)",
"({count} selected)": "({count} sélectionné(s))",
@@ -2738,7 +2748,84 @@ OC.L10N.register(
"_Object successfully deleted_::_Objects successfully deleted_": ["Objet supprimé avec succès","Objets supprimés avec succès","Objets supprimés avec succès"],
"_Purge {count} object from database_::_Purge {count} objects from database_": ["Purger {count} objet de la base de données","Purger {count} objets de la base de données","Purger {count} objets de la base de données"],
"_Restore {count} object_::_Restore {count} objects_": ["Restaurer {count} objet","Restaurer {count} objets","Restaurer {count} objets"],
- "_Successfully restored {count} object_::_Successfully restored {count} objects_": ["{count} objet restauré avec succès","{count} objets restaurés avec succès","{count} objets restaurés avec succès"]
+ "_Successfully restored {count} object_::_Successfully restored {count} objects_": ["{count} objet restauré avec succès","{count} objets restaurés avec succès","{count} objets restaurés avec succès"],
+ "A message identity the notification subsystem resolves.": "Une identité de message que le système de notification résout.",
+ "Computed non-working-date rules. kind fixed: {month, day, name, observedShift?: {whenWeekday, days}}. kind easter: {offset, name}, offset in days from Easter Sunday. kind observedShift: a fixed date with a required shift.": "Règles calculées des jours chômés. Type fixed : {month, day, name, observedShift?: {whenWeekday, days}}. Type easter : {offset, name}, décalage en jours depuis le dimanche de Pâques. Type observedShift : une date fixe avec report obligatoire.",
+ "Date": "Date",
+ "Day": "Jour",
+ "Day of a fixed or observedShift rule; ignored by an easter rule.": "Jour d'une règle fixed ou observedShift ; ignoré par une règle easter.",
+ "Days": "Jours",
+ "Days from Easter Sunday for an easter rule; ignored by the other kinds.": "Jours depuis le dimanche de Pâques pour une règle easter ; ignorés par les autres types.",
+ "Distance from the deadline, in the offset unit.": "Distance à l'échéance, dans l'unité du décalage.",
+ "Enumerated one-off closures as {date, name}. Allowed alongside rules; refused as the whole calendar.": "Fermetures ponctuelles énumérées sous la forme {date, name}. Admises à côté des règles ; refusées comme calendrier entier.",
+ "Escalate to roles": "Rôles d'escalade",
+ "Escalation ladder": "Échelle d'escalade",
+ "Exception dates": "Dates d'exception",
+ "Hours per working day": "Heures par jour ouvré",
+ "How many days the observed date shifts, e.g. -1 for the Saturday before.": "De combien de jours la date observée est reportée, p. ex. -1 pour le samedi précédent.",
+ "Human-readable title.": "Titre lisible.",
+ "ISO weekdays (1 = Monday, 7 = Sunday) that are working days.": "Jours ISO de la semaine (1 = lundi, 7 = dimanche) qui sont ouvrés.",
+ "Kind": "Type",
+ "Message": "Message",
+ "Month": "Mois",
+ "Month of a fixed or observedShift rule; ignored by an easter rule.": "Mois d'une règle fixed ou observedShift ; ignoré par une règle easter.",
+ "Non-working-date rules": "Règles des jours chômés",
+ "Notify roles": "Rôles à notifier",
+ "Observed shift": "Report du jour férié",
+ "Offset": "Décalage",
+ "Offset unit": "Unité du décalage",
+ "Open incident": "Ouvrir un incident",
+ "Optional map from a role name to a concrete recipient descriptor, e.g. {\"teamleader\": \"group:teamleaders\"}. Roles without a binding travel unresolved as role:.": "Table facultative reliant un nom de rôle à un destinataire concret, p. ex. {\"teamleader\": \"group:teamleaders\"}. Les rôles sans liaison voyagent non résolus sous la forme role:.",
+ "Optional on a fixed rule, required on observedShift: {whenWeekday: weekday name or ISO 1..7, days: integer}.": "Facultatif sur une règle fixed, obligatoire sur observedShift : {whenWeekday : nom du jour ou ISO 1..7, days : entier}.",
+ "Ordered rungs: {key, trigger (preBreach|slaBreached), offset, offsetUnit (hours|businessDays|calendarDays), notifyRole[], escalateToRole[], priority, message, openIncident}.": "Échelons ordonnés : {key, trigger (preBreach|slaBreached), offset, offsetUnit (hours|businessDays|calendarDays), notifyRole[], escalateToRole[], priority, message, openIncident}.",
+ "Priority": "Priorité",
+ "Role bindings": "Liaisons de rôles",
+ "Roles the matter is escalated to at this rung.": "Rôles vers lesquels le dossier est escaladé à cet échelon.",
+ "Roles told at this rung; handler is the subject's own performer.": "Rôles notifiés à cet échelon ; handler est la personne en charge du dossier.",
+ "Rungs": "Échelons",
+ "Stable rung identity, e.g. preBreach:14:calendarDays; derived from trigger, offset and unit when absent.": "Identité stable de l'échelon, p. ex. preBreach:14:calendarDays ; dérivée du déclencheur, du décalage et de l'unité si absente.",
+ "The calendar's stable name, referenced by a timer's calendar_slug.": "Le nom stable du calendrier, référencé par le calendar_slug d'un minuteur.",
+ "The closed date, Y-m-d.": "La date de fermeture, Y-m-d.",
+ "The holiday's name.": "Le nom du jour férié.",
+ "The ladder's stable name, referenced by a timer's ladder_slug.": "Le nom stable de l'échelle, référencé par le ladder_slug d'un minuteur.",
+ "The unit of the offset: the same set the SLA accepts.": "L'unité du décalage : le même ensemble que celui accepté par le SLA.",
+ "The urgency the raised transition carries.": "L'urgence portée par la transition déclenchée.",
+ "The weekday (name) on which the date shifts, e.g. sunday for Koningsdag.": "Le jour de la semaine (nom) qui déclenche le report, p. ex. sunday pour Koningsdag.",
+ "UUID of the organisation this calendar is configured for. Empty for a shared calendar. The resolution order picks an organisation's calendar when the timer names none.": "UUID de l'organisation pour laquelle ce calendrier est configuré. Vide pour un calendrier partagé. Si le minuteur n'en nomme aucun, l'ordre de résolution choisit le calendrier de l'organisation.",
+ "UUID of the organisation this ladder is the default for. Empty for the shared default.": "UUID de l'organisation dont cette échelle est l'échelle par défaut. Vide pour le défaut partagé.",
+ "When weekday": "Si le jour tombe un",
+ "Whether reaching this rung opens an incident.": "Si l'atteinte de cet échelon ouvre un incident.",
+ "Why the day is closed.": "Pourquoi ce jour est fermé.",
+ "Working calendar": "Calendrier de travail",
+ "Working hours in one working day. Makes hours and businessDays commensurable.": "Heures travaillées dans un jour ouvré. Rend les heures et les jours ouvrés comparables.",
+ "Working weekdays": "Jours ouvrés de la semaine",
+ "fixed: a month/day; easter: an offset in days from Easter Sunday; observedShift: a month/day with a required observed shift.": "fixed : un mois et un jour ; easter : un décalage en jours depuis le dimanche de Pâques ; observedShift : un mois et un jour avec report obligatoire.",
+ "preBreach fires before the deadline, slaBreached at or after it.": "preBreach se déclenche avant l'échéance, slaBreached à l'échéance ou après.",
+ "No such task": "Aucune tâche trouvée",
+ "The task does not exist, or it is not yours to see.": "La tâche n'existe pas, ou vous n'êtes pas autorisé à la voir.",
+ "Details": "Détails",
+ "Due": "Échéance",
+ "Assignee": "Assigné à",
+ "Requested by": "Demandé par",
+ "Outcome": "Résultat",
+ "Ready to claim": "Prêt à réclamer",
+ "In progress": "En cours",
+ "Terminated": "Terminé",
+ "Normal": "Normale",
+ "Urgent": "Urgent",
+ "Overdue by 1 day": "En retard de 1 jour",
+ "Overdue by {days} days": "En retard de {days} jours",
+ "Due today": "À rendre aujourd'hui",
+ "Due tomorrow": "À rendre demain",
+ "Due in {days} days": "À rendre dans {days} jours",
+ "Tasks": "Tâches",
+ "Task": "Tâche",
+ "Unassigned, open for claiming": "Non assignée, ouverte à la réclamation",
+ "Claim": "Réclamer",
+ "Complete": "Terminer",
+ "Complete: {outcome}": "Terminer : {outcome}",
+ "Could not load the task": "Impossible de charger la tâche",
+ "The task refused that action": "La tâche a refusé cette action"
},
"nplurals=3; plural=(n == 0 || n == 1) ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"
)
diff --git a/l10n/fr.json b/l10n/fr.json
index 2cc0ce5970..6a21508187 100644
--- a/l10n/fr.json
+++ b/l10n/fr.json
@@ -1,10 +1,20 @@
{
"translations": {
+ "from amount {amount}": "à partir du montant {amount}",
+ "Gated transition: {transition}": "Transition contrôlée : {transition}",
+ "Each declared chain provisions an ordered task sequence when its transition is attempted. Approvers decide in their task inbox, not here.": "Chaque chaîne déclarée ouvre une séquence de tâches ordonnée dès que la transition est tentée. Les approbateurs décident dans leur boîte de tâches, pas ici.",
+ "Declare x-openregister-approval-chains on this schema to gate a lifecycle transition on approval.": "Déclarez x-openregister-approval-chains sur ce schéma pour conditionner une transition de cycle de vie à une approbation.",
+ "Approval sequences": "Séquences d'approbation",
"%n entries have no hash yet": "%n entrées n'ont pas encore de hachage",
"%n entry has no hash yet": "%n entrée n'a pas encore de hachage",
"(Dolphin required)": "(Dolphin requis)",
+ "No approval chains declared": "Aucune chaîne d'approbation déclarée",
"(no subject)": "(sans objet)",
"(no title)": "(sans titre)",
+ "Role {role}": "Rôle {role}",
+ "The transition is applied automatically once every step approves.": "La transition est appliquée automatiquement dès que chaque étape est approuvée.",
+ "The requester may not decide their own approval.": "Le demandeur ne peut pas décider de sa propre approbation.",
+ "Tier routing on field: {field}": "Routage par palier sur le champ : {field}",
"(unnamed)": "(sans nom)",
"(untitled card)": "(carte sans titre)",
"({count} selected)": "({count} sélectionné(s))",
@@ -2801,7 +2811,84 @@
"{count} objet restauré avec succès",
"{count} objets restaurés avec succès",
"{count} objets restaurés avec succès"
- ]
+ ],
+ "A message identity the notification subsystem resolves.": "Une identité de message que le système de notification résout.",
+ "Computed non-working-date rules. kind fixed: {month, day, name, observedShift?: {whenWeekday, days}}. kind easter: {offset, name}, offset in days from Easter Sunday. kind observedShift: a fixed date with a required shift.": "Règles calculées des jours chômés. Type fixed : {month, day, name, observedShift?: {whenWeekday, days}}. Type easter : {offset, name}, décalage en jours depuis le dimanche de Pâques. Type observedShift : une date fixe avec report obligatoire.",
+ "Date": "Date",
+ "Day": "Jour",
+ "Day of a fixed or observedShift rule; ignored by an easter rule.": "Jour d'une règle fixed ou observedShift ; ignoré par une règle easter.",
+ "Days": "Jours",
+ "Days from Easter Sunday for an easter rule; ignored by the other kinds.": "Jours depuis le dimanche de Pâques pour une règle easter ; ignorés par les autres types.",
+ "Distance from the deadline, in the offset unit.": "Distance à l'échéance, dans l'unité du décalage.",
+ "Enumerated one-off closures as {date, name}. Allowed alongside rules; refused as the whole calendar.": "Fermetures ponctuelles énumérées sous la forme {date, name}. Admises à côté des règles ; refusées comme calendrier entier.",
+ "Escalate to roles": "Rôles d'escalade",
+ "Escalation ladder": "Échelle d'escalade",
+ "Exception dates": "Dates d'exception",
+ "Hours per working day": "Heures par jour ouvré",
+ "How many days the observed date shifts, e.g. -1 for the Saturday before.": "De combien de jours la date observée est reportée, p. ex. -1 pour le samedi précédent.",
+ "Human-readable title.": "Titre lisible.",
+ "ISO weekdays (1 = Monday, 7 = Sunday) that are working days.": "Jours ISO de la semaine (1 = lundi, 7 = dimanche) qui sont ouvrés.",
+ "Kind": "Type",
+ "Message": "Message",
+ "Month": "Mois",
+ "Month of a fixed or observedShift rule; ignored by an easter rule.": "Mois d'une règle fixed ou observedShift ; ignoré par une règle easter.",
+ "Non-working-date rules": "Règles des jours chômés",
+ "Notify roles": "Rôles à notifier",
+ "Observed shift": "Report du jour férié",
+ "Offset": "Décalage",
+ "Offset unit": "Unité du décalage",
+ "Open incident": "Ouvrir un incident",
+ "Optional map from a role name to a concrete recipient descriptor, e.g. {\"teamleader\": \"group:teamleaders\"}. Roles without a binding travel unresolved as role:.": "Table facultative reliant un nom de rôle à un destinataire concret, p. ex. {\"teamleader\": \"group:teamleaders\"}. Les rôles sans liaison voyagent non résolus sous la forme role:.",
+ "Optional on a fixed rule, required on observedShift: {whenWeekday: weekday name or ISO 1..7, days: integer}.": "Facultatif sur une règle fixed, obligatoire sur observedShift : {whenWeekday : nom du jour ou ISO 1..7, days : entier}.",
+ "Ordered rungs: {key, trigger (preBreach|slaBreached), offset, offsetUnit (hours|businessDays|calendarDays), notifyRole[], escalateToRole[], priority, message, openIncident}.": "Échelons ordonnés : {key, trigger (preBreach|slaBreached), offset, offsetUnit (hours|businessDays|calendarDays), notifyRole[], escalateToRole[], priority, message, openIncident}.",
+ "Priority": "Priorité",
+ "Role bindings": "Liaisons de rôles",
+ "Roles the matter is escalated to at this rung.": "Rôles vers lesquels le dossier est escaladé à cet échelon.",
+ "Roles told at this rung; handler is the subject's own performer.": "Rôles notifiés à cet échelon ; handler est la personne en charge du dossier.",
+ "Rungs": "Échelons",
+ "Stable rung identity, e.g. preBreach:14:calendarDays; derived from trigger, offset and unit when absent.": "Identité stable de l'échelon, p. ex. preBreach:14:calendarDays ; dérivée du déclencheur, du décalage et de l'unité si absente.",
+ "The calendar's stable name, referenced by a timer's calendar_slug.": "Le nom stable du calendrier, référencé par le calendar_slug d'un minuteur.",
+ "The closed date, Y-m-d.": "La date de fermeture, Y-m-d.",
+ "The holiday's name.": "Le nom du jour férié.",
+ "The ladder's stable name, referenced by a timer's ladder_slug.": "Le nom stable de l'échelle, référencé par le ladder_slug d'un minuteur.",
+ "The unit of the offset: the same set the SLA accepts.": "L'unité du décalage : le même ensemble que celui accepté par le SLA.",
+ "The urgency the raised transition carries.": "L'urgence portée par la transition déclenchée.",
+ "The weekday (name) on which the date shifts, e.g. sunday for Koningsdag.": "Le jour de la semaine (nom) qui déclenche le report, p. ex. sunday pour Koningsdag.",
+ "UUID of the organisation this calendar is configured for. Empty for a shared calendar. The resolution order picks an organisation's calendar when the timer names none.": "UUID de l'organisation pour laquelle ce calendrier est configuré. Vide pour un calendrier partagé. Si le minuteur n'en nomme aucun, l'ordre de résolution choisit le calendrier de l'organisation.",
+ "UUID of the organisation this ladder is the default for. Empty for the shared default.": "UUID de l'organisation dont cette échelle est l'échelle par défaut. Vide pour le défaut partagé.",
+ "When weekday": "Si le jour tombe un",
+ "Whether reaching this rung opens an incident.": "Si l'atteinte de cet échelon ouvre un incident.",
+ "Why the day is closed.": "Pourquoi ce jour est fermé.",
+ "Working calendar": "Calendrier de travail",
+ "Working hours in one working day. Makes hours and businessDays commensurable.": "Heures travaillées dans un jour ouvré. Rend les heures et les jours ouvrés comparables.",
+ "Working weekdays": "Jours ouvrés de la semaine",
+ "fixed: a month/day; easter: an offset in days from Easter Sunday; observedShift: a month/day with a required observed shift.": "fixed : un mois et un jour ; easter : un décalage en jours depuis le dimanche de Pâques ; observedShift : un mois et un jour avec report obligatoire.",
+ "preBreach fires before the deadline, slaBreached at or after it.": "preBreach se déclenche avant l'échéance, slaBreached à l'échéance ou après.",
+ "No such task": "Aucune tâche trouvée",
+ "The task does not exist, or it is not yours to see.": "La tâche n'existe pas, ou vous n'êtes pas autorisé à la voir.",
+ "Details": "Détails",
+ "Due": "Échéance",
+ "Assignee": "Assigné à",
+ "Requested by": "Demandé par",
+ "Outcome": "Résultat",
+ "Ready to claim": "Prêt à réclamer",
+ "In progress": "En cours",
+ "Terminated": "Terminé",
+ "Normal": "Normale",
+ "Urgent": "Urgent",
+ "Overdue by 1 day": "En retard de 1 jour",
+ "Overdue by {days} days": "En retard de {days} jours",
+ "Due today": "À rendre aujourd'hui",
+ "Due tomorrow": "À rendre demain",
+ "Due in {days} days": "À rendre dans {days} jours",
+ "Tasks": "Tâches",
+ "Task": "Tâche",
+ "Unassigned, open for claiming": "Non assignée, ouverte à la réclamation",
+ "Claim": "Réclamer",
+ "Complete": "Terminer",
+ "Complete: {outcome}": "Terminer : {outcome}",
+ "Could not load the task": "Impossible de charger la tâche",
+ "The task refused that action": "La tâche a refusé cette action"
},
"pluralForm": "nplurals=3; plural=(n == 0 || n == 1) ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;",
"plurals": {
diff --git a/l10n/ga.js b/l10n/ga.js
index 6680f30cee..6f78a55344 100644
--- a/l10n/ga.js
+++ b/l10n/ga.js
@@ -3,11 +3,21 @@ OC.L10N.register(
{
"3": "3",
"30": "30",
+ "from amount {amount}": "ó mhéid {amount}",
+ "Gated transition: {transition}": "Aistriú faoi gharda: {transition}",
+ "Each declared chain provisions an ordered task sequence when its transition is attempted. Approvers decide in their task inbox, not here.": "Osclaíonn gach slabhra dearbhaithe seicheamh ordaithe tascanna nuair a dhéantar iarracht ar an aistriú. Cinneann ceadaitheoirí ina mbosca isteach tascanna, ní anseo.",
+ "Declare x-openregister-approval-chains on this schema to gate a lifecycle transition on approval.": "Dearbhaigh x-openregister-approval-chains ar an scéimre seo chun ceadú a éileamh roimh aistriú saolré.",
+ "Approval sequences": "Seichimh cheadaithe",
"%n entries have no hash yet": "Níl hais ag %n iontráil fós",
"%n entry has no hash yet": "Níl hais ag %n iontráil fós",
"(Dolphin required)": "(Dolphin riachtanach)",
+ "No approval chains declared": "Níl aon slabhraí ceadaithe dearbhaithe",
"(no subject)": "(gan ábhar)",
"(no title)": "(gan teideal)",
+ "Role {role}": "Ról {role}",
+ "The transition is applied automatically once every step approves.": "Cuirtear an t-aistriú i bhfeidhm go huathoibríoch nuair a cheadaítear gach céim.",
+ "The requester may not decide their own approval.": "Ní féidir leis an iarrthóir cinneadh a dhéanamh faoina cheadú féin.",
+ "Tier routing on field: {field}": "Ródú de réir céime ar an réimse: {field}",
"(unnamed)": "(gan ainm)",
"(untitled card)": "(cárta gan teideal)",
"({count} selected)": "({count} roghnaithe)",
@@ -2738,7 +2748,84 @@ OC.L10N.register(
"_Object successfully deleted_::_Objects successfully deleted_": ["Scriosadh an réad go rathúil","Scriosadh na réada go rathúil","Scriosadh na réada go rathúil","Scriosadh na réada go rathúil","Scriosadh na réada go rathúil"],
"_Purge {count} object from database_::_Purge {count} objects from database_": ["Glan {count} réad ón mbunachar sonraí","Glan {count} réad ón mbunachar sonraí","Glan {count} réada ón mbunachar sonraí","Glan {count} réad ón mbunachar sonraí","Glan {count} réad ón mbunachar sonraí"],
"_Restore {count} object_::_Restore {count} objects_": ["Athchóirigh {count} réad","Athchóirigh {count} réad","Athchóirigh {count} réada","Athchóirigh {count} réad","Athchóirigh {count} réad"],
- "_Successfully restored {count} object_::_Successfully restored {count} objects_": ["Athchóiríodh {count} réad go rathúil","Athchóiríodh {count} réad go rathúil","Athchóiríodh {count} réada go rathúil","Athchóiríodh {count} réad go rathúil","Athchóiríodh {count} réad go rathúil"]
+ "_Successfully restored {count} object_::_Successfully restored {count} objects_": ["Athchóiríodh {count} réad go rathúil","Athchóiríodh {count} réad go rathúil","Athchóiríodh {count} réada go rathúil","Athchóiríodh {count} réad go rathúil","Athchóiríodh {count} réad go rathúil"],
+ "A message identity the notification subsystem resolves.": "Aitheantas teachtaireachta a réitíonn an fochóras fógraí.",
+ "Computed non-working-date rules. kind fixed: {month, day, name, observedShift?: {whenWeekday, days}}. kind easter: {offset, name}, offset in days from Easter Sunday. kind observedShift: a fixed date with a required shift.": "Rialacha ríofa na laethanta neamhoibre. Cineál fixed: {month, day, name, observedShift?: {whenWeekday, days}}. Cineál easter: {offset, name}, fritháireamh i laethanta ó Dhomhnach Cásca. Cineál observedShift: dáta seasta le haistriú éigeantach.",
+ "Date": "Dáta",
+ "Day": "Lá",
+ "Day of a fixed or observedShift rule; ignored by an easter rule.": "Lá rialach fixed nó observedShift; déanann riail easter neamhaird de.",
+ "Days": "Laethanta",
+ "Days from Easter Sunday for an easter rule; ignored by the other kinds.": "Laethanta ó Dhomhnach Cásca do riail easter; déanann na cineálacha eile neamhaird díobh.",
+ "Distance from the deadline, in the offset unit.": "Fad ón spriocdháta, in aonad an fhritháirimh.",
+ "Enumerated one-off closures as {date, name}. Allowed alongside rules; refused as the whole calendar.": "Dúntaí aonuaire liostaithe mar {date, name}. Ceadaithe in éineacht le rialacha; diúltaithe mar an féilire iomlán.",
+ "Escalate to roles": "Róil ghéaraithe",
+ "Escalation ladder": "Dréimire géaraithe",
+ "Exception dates": "Dátaí eisceachta",
+ "Hours per working day": "Uaireanta in aghaidh an lae oibre",
+ "How many days the observed date shifts, e.g. -1 for the Saturday before.": "Cé mhéad lá a aistrítear an dáta ceiliúrtha, m.sh. -1 don Satharn roimhe.",
+ "Human-readable title.": "Teideal inléite.",
+ "ISO weekdays (1 = Monday, 7 = Sunday) that are working days.": "Laethanta ISO na seachtaine (1 = Luan, 7 = Domhnach) ar laethanta oibre iad.",
+ "Kind": "Cineál",
+ "Message": "Teachtaireacht",
+ "Month": "Mí",
+ "Month of a fixed or observedShift rule; ignored by an easter rule.": "Mí rialach fixed nó observedShift; déanann riail easter neamhaird de.",
+ "Non-working-date rules": "Rialacha na laethanta neamhoibre",
+ "Notify roles": "Róil le cur ar an eolas",
+ "Observed shift": "Aistriú na saoire",
+ "Offset": "Fritháireamh",
+ "Offset unit": "Aonad an fhritháirimh",
+ "Open incident": "Oscail teagmhas",
+ "Optional map from a role name to a concrete recipient descriptor, e.g. {\"teamleader\": \"group:teamleaders\"}. Roles without a binding travel unresolved as role:.": "Mapa roghnach ó ainm róil go faighteoir nithiúil, m.sh. {\"teamleader\": \"group:teamleaders\"}. Taistealaíonn róil gan cheangal gan réiteach mar role:.",
+ "Optional on a fixed rule, required on observedShift: {whenWeekday: weekday name or ISO 1..7, days: integer}.": "Roghnach ar riail fixed, éigeantach ar observedShift: {whenWeekday: ainm an lae nó ISO 1..7, days: slánuimhir}.",
+ "Ordered rungs: {key, trigger (preBreach|slaBreached), offset, offsetUnit (hours|businessDays|calendarDays), notifyRole[], escalateToRole[], priority, message, openIncident}.": "Runganna in ord: {key, trigger (preBreach|slaBreached), offset, offsetUnit (hours|businessDays|calendarDays), notifyRole[], escalateToRole[], priority, message, openIncident}.",
+ "Priority": "Tosaíocht",
+ "Role bindings": "Ceangail ról",
+ "Roles the matter is escalated to at this rung.": "Róil a ngéaraítear an cás chucu ag an runga seo.",
+ "Roles told at this rung; handler is the subject's own performer.": "Róil a chuirtear ar an eolas ag an runga seo; is é handler an duine atá i mbun an cháis.",
+ "Rungs": "Runganna",
+ "Stable rung identity, e.g. preBreach:14:calendarDays; derived from trigger, offset and unit when absent.": "Aitheantas seasta an runga, m.sh. preBreach:14:calendarDays; nuair a bhíonn sé ar iarraidh, díorthaítear é ón truicear, ón bhfritháireamh agus ón aonad.",
+ "The calendar's stable name, referenced by a timer's calendar_slug.": "Ainm seasta an fhéilire, a dtagraíonn amadóir dó trí calendar_slug.",
+ "The closed date, Y-m-d.": "Dáta an dúnta, Y-m-d.",
+ "The holiday's name.": "Ainm na saoire.",
+ "The ladder's stable name, referenced by a timer's ladder_slug.": "Ainm seasta an dréimire, a dtagraíonn amadóir dó trí ladder_slug.",
+ "The unit of the offset: the same set the SLA accepts.": "Aonad an fhritháirimh: an tacar céanna a nglacann an SLA leis.",
+ "The urgency the raised transition carries.": "An phráinn a iompraíonn an t-aistriú a lasadh.",
+ "The weekday (name) on which the date shifts, e.g. sunday for Koningsdag.": "Lá na seachtaine (ainm) a n-aistrítear an dáta air, m.sh. sunday do Koningsdag.",
+ "UUID of the organisation this calendar is configured for. Empty for a shared calendar. The resolution order picks an organisation's calendar when the timer names none.": "UUID na heagraíochta a bhfuil an féilire seo cumraithe di. Folamh i gcás féilire comhroinnte. Mura n-ainmníonn an t-amadóir ceann ar bith, roghnaíonn an t-ord réitigh féilire na heagraíochta.",
+ "UUID of the organisation this ladder is the default for. Empty for the shared default.": "UUID na heagraíochta a bhfuil an dréimire seo réamhshocraithe di. Folamh don réamhshocrú comhroinnte.",
+ "When weekday": "Má thiteann sé ar",
+ "Whether reaching this rung opens an incident.": "Cé acu an osclaíonn an runga seo a bhaint amach teagmhas nó nach n-osclaíonn.",
+ "Why the day is closed.": "Cén fáth a bhfuil an lá dúnta.",
+ "Working calendar": "Féilire oibre",
+ "Working hours in one working day. Makes hours and businessDays commensurable.": "Uaireanta oibre in aon lá oibre amháin. Déanann sé uaireanta agus laethanta oibre inchomparáide.",
+ "Working weekdays": "Laethanta oibre na seachtaine",
+ "fixed: a month/day; easter: an offset in days from Easter Sunday; observedShift: a month/day with a required observed shift.": "fixed: mí agus lá; easter: fritháireamh i laethanta ó Dhomhnach Cásca; observedShift: mí agus lá le haistriú éigeantach.",
+ "preBreach fires before the deadline, slaBreached at or after it.": "Lasann preBreach roimh an spriocdháta, slaBreached ar an spriocdháta nó ina dhiaidh.",
+ "No such task": "Níl a leithéid de thasc ann",
+ "The task does not exist, or it is not yours to see.": "Níl an tasc ann, nó níl cead agat é a fheiceáil.",
+ "Details": "Sonraí",
+ "Due": "Spriocdháta",
+ "Assignee": "Sannaí",
+ "Requested by": "Iarrtha ag",
+ "Outcome": "Toradh",
+ "Ready to claim": "Réidh le héileamh",
+ "In progress": "Ar siúl",
+ "Terminated": "Foirceanta",
+ "Normal": "Gnáth",
+ "Urgent": "Práinneach",
+ "Overdue by 1 day": "1 lá thar téarma",
+ "Overdue by {days} days": "{days} lá thar téarma",
+ "Due today": "Le déanamh inniu",
+ "Due tomorrow": "Le déanamh amárach",
+ "Due in {days} days": "Le déanamh i gceann {days} lá",
+ "Tasks": "Tascanna",
+ "Task": "Tasc",
+ "Unassigned, open for claiming": "Gan sannadh, ar oscailt le héileamh",
+ "Claim": "Éiligh",
+ "Complete": "Críochnaigh",
+ "Complete: {outcome}": "Críochnaigh: {outcome}",
+ "Could not load the task": "Níorbh fhéidir an tasc a lódáil",
+ "The task refused that action": "Dhiúltaigh an tasc don ghníomh sin"
},
"nplurals=5; plural=(n==1 ? 0 : n==2 ? 1 : n<7 ? 2 : n<11 ? 3 : 4);"
)
diff --git a/l10n/ga.json b/l10n/ga.json
index 03331ff25b..350a8c3653 100644
--- a/l10n/ga.json
+++ b/l10n/ga.json
@@ -1,10 +1,20 @@
{
"translations": {
+ "from amount {amount}": "ó mhéid {amount}",
+ "Gated transition: {transition}": "Aistriú faoi gharda: {transition}",
+ "Each declared chain provisions an ordered task sequence when its transition is attempted. Approvers decide in their task inbox, not here.": "Osclaíonn gach slabhra dearbhaithe seicheamh ordaithe tascanna nuair a dhéantar iarracht ar an aistriú. Cinneann ceadaitheoirí ina mbosca isteach tascanna, ní anseo.",
+ "Declare x-openregister-approval-chains on this schema to gate a lifecycle transition on approval.": "Dearbhaigh x-openregister-approval-chains ar an scéimre seo chun ceadú a éileamh roimh aistriú saolré.",
+ "Approval sequences": "Seichimh cheadaithe",
"%n entries have no hash yet": "Níl hais ag %n iontráil fós",
"%n entry has no hash yet": "Níl hais ag %n iontráil fós",
"(Dolphin required)": "(Dolphin riachtanach)",
+ "No approval chains declared": "Níl aon slabhraí ceadaithe dearbhaithe",
"(no subject)": "(gan ábhar)",
"(no title)": "(gan teideal)",
+ "Role {role}": "Ról {role}",
+ "The transition is applied automatically once every step approves.": "Cuirtear an t-aistriú i bhfeidhm go huathoibríoch nuair a cheadaítear gach céim.",
+ "The requester may not decide their own approval.": "Ní féidir leis an iarrthóir cinneadh a dhéanamh faoina cheadú féin.",
+ "Tier routing on field: {field}": "Ródú de réir céime ar an réimse: {field}",
"(unnamed)": "(gan ainm)",
"(untitled card)": "(cárta gan teideal)",
"({count} selected)": "({count} roghnaithe)",
@@ -2833,7 +2843,84 @@
"Athchóiríodh {count} réada go rathúil",
"Athchóiríodh {count} réad go rathúil",
"Athchóiríodh {count} réad go rathúil"
- ]
+ ],
+ "A message identity the notification subsystem resolves.": "Aitheantas teachtaireachta a réitíonn an fochóras fógraí.",
+ "Computed non-working-date rules. kind fixed: {month, day, name, observedShift?: {whenWeekday, days}}. kind easter: {offset, name}, offset in days from Easter Sunday. kind observedShift: a fixed date with a required shift.": "Rialacha ríofa na laethanta neamhoibre. Cineál fixed: {month, day, name, observedShift?: {whenWeekday, days}}. Cineál easter: {offset, name}, fritháireamh i laethanta ó Dhomhnach Cásca. Cineál observedShift: dáta seasta le haistriú éigeantach.",
+ "Date": "Dáta",
+ "Day": "Lá",
+ "Day of a fixed or observedShift rule; ignored by an easter rule.": "Lá rialach fixed nó observedShift; déanann riail easter neamhaird de.",
+ "Days": "Laethanta",
+ "Days from Easter Sunday for an easter rule; ignored by the other kinds.": "Laethanta ó Dhomhnach Cásca do riail easter; déanann na cineálacha eile neamhaird díobh.",
+ "Distance from the deadline, in the offset unit.": "Fad ón spriocdháta, in aonad an fhritháirimh.",
+ "Enumerated one-off closures as {date, name}. Allowed alongside rules; refused as the whole calendar.": "Dúntaí aonuaire liostaithe mar {date, name}. Ceadaithe in éineacht le rialacha; diúltaithe mar an féilire iomlán.",
+ "Escalate to roles": "Róil ghéaraithe",
+ "Escalation ladder": "Dréimire géaraithe",
+ "Exception dates": "Dátaí eisceachta",
+ "Hours per working day": "Uaireanta in aghaidh an lae oibre",
+ "How many days the observed date shifts, e.g. -1 for the Saturday before.": "Cé mhéad lá a aistrítear an dáta ceiliúrtha, m.sh. -1 don Satharn roimhe.",
+ "Human-readable title.": "Teideal inléite.",
+ "ISO weekdays (1 = Monday, 7 = Sunday) that are working days.": "Laethanta ISO na seachtaine (1 = Luan, 7 = Domhnach) ar laethanta oibre iad.",
+ "Kind": "Cineál",
+ "Message": "Teachtaireacht",
+ "Month": "Mí",
+ "Month of a fixed or observedShift rule; ignored by an easter rule.": "Mí rialach fixed nó observedShift; déanann riail easter neamhaird de.",
+ "Non-working-date rules": "Rialacha na laethanta neamhoibre",
+ "Notify roles": "Róil le cur ar an eolas",
+ "Observed shift": "Aistriú na saoire",
+ "Offset": "Fritháireamh",
+ "Offset unit": "Aonad an fhritháirimh",
+ "Open incident": "Oscail teagmhas",
+ "Optional map from a role name to a concrete recipient descriptor, e.g. {\"teamleader\": \"group:teamleaders\"}. Roles without a binding travel unresolved as role:.": "Mapa roghnach ó ainm róil go faighteoir nithiúil, m.sh. {\"teamleader\": \"group:teamleaders\"}. Taistealaíonn róil gan cheangal gan réiteach mar role:.",
+ "Optional on a fixed rule, required on observedShift: {whenWeekday: weekday name or ISO 1..7, days: integer}.": "Roghnach ar riail fixed, éigeantach ar observedShift: {whenWeekday: ainm an lae nó ISO 1..7, days: slánuimhir}.",
+ "Ordered rungs: {key, trigger (preBreach|slaBreached), offset, offsetUnit (hours|businessDays|calendarDays), notifyRole[], escalateToRole[], priority, message, openIncident}.": "Runganna in ord: {key, trigger (preBreach|slaBreached), offset, offsetUnit (hours|businessDays|calendarDays), notifyRole[], escalateToRole[], priority, message, openIncident}.",
+ "Priority": "Tosaíocht",
+ "Role bindings": "Ceangail ról",
+ "Roles the matter is escalated to at this rung.": "Róil a ngéaraítear an cás chucu ag an runga seo.",
+ "Roles told at this rung; handler is the subject's own performer.": "Róil a chuirtear ar an eolas ag an runga seo; is é handler an duine atá i mbun an cháis.",
+ "Rungs": "Runganna",
+ "Stable rung identity, e.g. preBreach:14:calendarDays; derived from trigger, offset and unit when absent.": "Aitheantas seasta an runga, m.sh. preBreach:14:calendarDays; nuair a bhíonn sé ar iarraidh, díorthaítear é ón truicear, ón bhfritháireamh agus ón aonad.",
+ "The calendar's stable name, referenced by a timer's calendar_slug.": "Ainm seasta an fhéilire, a dtagraíonn amadóir dó trí calendar_slug.",
+ "The closed date, Y-m-d.": "Dáta an dúnta, Y-m-d.",
+ "The holiday's name.": "Ainm na saoire.",
+ "The ladder's stable name, referenced by a timer's ladder_slug.": "Ainm seasta an dréimire, a dtagraíonn amadóir dó trí ladder_slug.",
+ "The unit of the offset: the same set the SLA accepts.": "Aonad an fhritháirimh: an tacar céanna a nglacann an SLA leis.",
+ "The urgency the raised transition carries.": "An phráinn a iompraíonn an t-aistriú a lasadh.",
+ "The weekday (name) on which the date shifts, e.g. sunday for Koningsdag.": "Lá na seachtaine (ainm) a n-aistrítear an dáta air, m.sh. sunday do Koningsdag.",
+ "UUID of the organisation this calendar is configured for. Empty for a shared calendar. The resolution order picks an organisation's calendar when the timer names none.": "UUID na heagraíochta a bhfuil an féilire seo cumraithe di. Folamh i gcás féilire comhroinnte. Mura n-ainmníonn an t-amadóir ceann ar bith, roghnaíonn an t-ord réitigh féilire na heagraíochta.",
+ "UUID of the organisation this ladder is the default for. Empty for the shared default.": "UUID na heagraíochta a bhfuil an dréimire seo réamhshocraithe di. Folamh don réamhshocrú comhroinnte.",
+ "When weekday": "Má thiteann sé ar",
+ "Whether reaching this rung opens an incident.": "Cé acu an osclaíonn an runga seo a bhaint amach teagmhas nó nach n-osclaíonn.",
+ "Why the day is closed.": "Cén fáth a bhfuil an lá dúnta.",
+ "Working calendar": "Féilire oibre",
+ "Working hours in one working day. Makes hours and businessDays commensurable.": "Uaireanta oibre in aon lá oibre amháin. Déanann sé uaireanta agus laethanta oibre inchomparáide.",
+ "Working weekdays": "Laethanta oibre na seachtaine",
+ "fixed: a month/day; easter: an offset in days from Easter Sunday; observedShift: a month/day with a required observed shift.": "fixed: mí agus lá; easter: fritháireamh i laethanta ó Dhomhnach Cásca; observedShift: mí agus lá le haistriú éigeantach.",
+ "preBreach fires before the deadline, slaBreached at or after it.": "Lasann preBreach roimh an spriocdháta, slaBreached ar an spriocdháta nó ina dhiaidh.",
+ "No such task": "Níl a leithéid de thasc ann",
+ "The task does not exist, or it is not yours to see.": "Níl an tasc ann, nó níl cead agat é a fheiceáil.",
+ "Details": "Sonraí",
+ "Due": "Spriocdháta",
+ "Assignee": "Sannaí",
+ "Requested by": "Iarrtha ag",
+ "Outcome": "Toradh",
+ "Ready to claim": "Réidh le héileamh",
+ "In progress": "Ar siúl",
+ "Terminated": "Foirceanta",
+ "Normal": "Gnáth",
+ "Urgent": "Práinneach",
+ "Overdue by 1 day": "1 lá thar téarma",
+ "Overdue by {days} days": "{days} lá thar téarma",
+ "Due today": "Le déanamh inniu",
+ "Due tomorrow": "Le déanamh amárach",
+ "Due in {days} days": "Le déanamh i gceann {days} lá",
+ "Tasks": "Tascanna",
+ "Task": "Tasc",
+ "Unassigned, open for claiming": "Gan sannadh, ar oscailt le héileamh",
+ "Claim": "Éiligh",
+ "Complete": "Críochnaigh",
+ "Complete: {outcome}": "Críochnaigh: {outcome}",
+ "Could not load the task": "Níorbh fhéidir an tasc a lódáil",
+ "The task refused that action": "Dhiúltaigh an tasc don ghníomh sin"
},
"pluralForm": "nplurals=5; plural=(n==1 ? 0 : n==2 ? 1 : n<7 ? 2 : n<11 ? 3 : 4);",
"plurals": {
diff --git a/l10n/hr.js b/l10n/hr.js
index dbd3d5987b..56cfd5ade7 100644
--- a/l10n/hr.js
+++ b/l10n/hr.js
@@ -3,11 +3,21 @@ OC.L10N.register(
{
"3": "3",
"30": "30",
+ "from amount {amount}": "od iznosa {amount}",
+ "Gated transition: {transition}": "Nadzirani prijelaz: {transition}",
+ "Each declared chain provisions an ordered task sequence when its transition is attempted. Approvers decide in their task inbox, not here.": "Svaki deklarirani lanac otvara uređeni niz zadataka kad se prijelaz pokuša. Odobravatelji odlučuju u svojoj ulaznoj listi zadataka, ne ovdje.",
+ "Declare x-openregister-approval-chains on this schema to gate a lifecycle transition on approval.": "Deklarirajte x-openregister-approval-chains na ovoj shemi kako biste prijelaz životnog ciklusa uvjetovali odobrenjem.",
+ "Approval sequences": "Nizovi odobravanja",
"%n entries have no hash yet": "%n unosa još nema hash",
"%n entry has no hash yet": "%n unos još nema hash",
"(Dolphin required)": "(Potreban Dolphin)",
+ "No approval chains declared": "Nema deklariranih lanaca odobravanja",
"(no subject)": "(bez predmeta)",
"(no title)": "(bez naslova)",
+ "Role {role}": "Uloga {role}",
+ "The transition is applied automatically once every step approves.": "Prijelaz se primjenjuje automatski čim je svaki korak odobren.",
+ "The requester may not decide their own approval.": "Podnositelj zahtjeva ne može odlučivati o vlastitom odobrenju.",
+ "Tier routing on field: {field}": "Usmjeravanje po razredima prema polju: {field}",
"(unnamed)": "(bez naziva)",
"(untitled card)": "(kartica bez naslova)",
"({count} selected)": "({count} odabrano)",
@@ -2738,7 +2748,84 @@ OC.L10N.register(
"_Object successfully deleted_::_Objects successfully deleted_": ["Objekt je uspješno izbrisan","Objekti su uspješno izbrisani","Objekti su uspješno izbrisani"],
"_Purge {count} object from database_::_Purge {count} objects from database_": ["Trajno ukloni {count} objekt iz baze podataka","Trajno ukloni {count} objekta iz baze podataka","Trajno ukloni {count} objekata iz baze podataka"],
"_Restore {count} object_::_Restore {count} objects_": ["Vrati {count} objekt","Vrati {count} objekta","Vrati {count} objekata"],
- "_Successfully restored {count} object_::_Successfully restored {count} objects_": ["Uspješno vraćen {count} objekt","Uspješno vraćena {count} objekta","Uspješno vraćeno {count} objekata"]
+ "_Successfully restored {count} object_::_Successfully restored {count} objects_": ["Uspješno vraćen {count} objekt","Uspješno vraćena {count} objekta","Uspješno vraćeno {count} objekata"],
+ "A message identity the notification subsystem resolves.": "Identitet poruke koji razrješava sustav obavijesti.",
+ "Computed non-working-date rules. kind fixed: {month, day, name, observedShift?: {whenWeekday, days}}. kind easter: {offset, name}, offset in days from Easter Sunday. kind observedShift: a fixed date with a required shift.": "Izračunata pravila neradnih dana. Vrsta fixed: {month, day, name, observedShift?: {whenWeekday, days}}. Vrsta easter: {offset, name}, odmak u danima od Uskrsne nedjelje. Vrsta observedShift: nepomičan datum s obveznim premještanjem.",
+ "Date": "Datum",
+ "Day": "Dan",
+ "Day of a fixed or observedShift rule; ignored by an easter rule.": "Dan pravila fixed ili observedShift; pravilo easter ga zanemaruje.",
+ "Days": "Dani",
+ "Days from Easter Sunday for an easter rule; ignored by the other kinds.": "Dani od Uskrsne nedjelje za pravilo easter; druge ih vrste zanemaruju.",
+ "Distance from the deadline, in the offset unit.": "Udaljenost od roka u jedinici odmaka.",
+ "Enumerated one-off closures as {date, name}. Allowed alongside rules; refused as the whole calendar.": "Pojedinačna zatvaranja nabrojena kao {date, name}. Dopuštena uz pravila; odbijena kao cijeli kalendar.",
+ "Escalate to roles": "Uloge za eskalaciju",
+ "Escalation ladder": "Ljestvica eskalacije",
+ "Exception dates": "Iznimni datumi",
+ "Hours per working day": "Sati po radnom danu",
+ "How many days the observed date shifts, e.g. -1 for the Saturday before.": "Za koliko se dana slavljeni datum premješta, npr. -1 za subotu prije.",
+ "Human-readable title.": "Čitljiv naslov.",
+ "ISO weekdays (1 = Monday, 7 = Sunday) that are working days.": "ISO dani u tjednu (1 = ponedjeljak, 7 = nedjelja) koji su radni.",
+ "Kind": "Vrsta",
+ "Message": "Poruka",
+ "Month": "Mjesec",
+ "Month of a fixed or observedShift rule; ignored by an easter rule.": "Mjesec pravila fixed ili observedShift; pravilo easter ga zanemaruje.",
+ "Non-working-date rules": "Pravila neradnih dana",
+ "Notify roles": "Uloge za obavijest",
+ "Observed shift": "Premještanje blagdana",
+ "Offset": "Odmak",
+ "Offset unit": "Jedinica odmaka",
+ "Open incident": "Otvori incident",
+ "Optional map from a role name to a concrete recipient descriptor, e.g. {\"teamleader\": \"group:teamleaders\"}. Roles without a binding travel unresolved as role:.": "Neobvezna mapa imena uloge na konkretnog primatelja, npr. {\"teamleader\": \"group:teamleaders\"}. Uloge bez poveznice putuju nerazriješene kao role:.",
+ "Optional on a fixed rule, required on observedShift: {whenWeekday: weekday name or ISO 1..7, days: integer}.": "Neobvezno kod pravila fixed, obvezno kod observedShift: {whenWeekday: ime dana ili ISO 1..7, days: cijeli broj}.",
+ "Ordered rungs: {key, trigger (preBreach|slaBreached), offset, offsetUnit (hours|businessDays|calendarDays), notifyRole[], escalateToRole[], priority, message, openIncident}.": "Poredane prečke: {key, trigger (preBreach|slaBreached), offset, offsetUnit (hours|businessDays|calendarDays), notifyRole[], escalateToRole[], priority, message, openIncident}.",
+ "Priority": "Prioritet",
+ "Role bindings": "Poveznice uloga",
+ "Roles the matter is escalated to at this rung.": "Uloge na koje se predmet na ovoj prečki eskalira.",
+ "Roles told at this rung; handler is the subject's own performer.": "Uloge obaviještene na ovoj prečki; handler je osoba koja rješava predmet.",
+ "Rungs": "Prečke",
+ "Stable rung identity, e.g. preBreach:14:calendarDays; derived from trigger, offset and unit when absent.": "Stalni identitet prečke, npr. preBreach:14:calendarDays; ako nedostaje, izvodi se iz okidača, odmaka i jedinice.",
+ "The calendar's stable name, referenced by a timer's calendar_slug.": "Stalno ime kalendara na koje se tajmer poziva putem calendar_slug.",
+ "The closed date, Y-m-d.": "Datum zatvaranja, Y-m-d.",
+ "The holiday's name.": "Ime blagdana.",
+ "The ladder's stable name, referenced by a timer's ladder_slug.": "Stalno ime ljestvice na koje se tajmer poziva putem ladder_slug.",
+ "The unit of the offset: the same set the SLA accepts.": "Jedinica odmaka: isti skup koji SLA prihvaća.",
+ "The urgency the raised transition carries.": "Hitnost koju nosi pokrenuti prijelaz.",
+ "The weekday (name) on which the date shifts, e.g. sunday for Koningsdag.": "Dan u tjednu (ime) na koji se datum premješta, npr. sunday za Koningsdag.",
+ "UUID of the organisation this calendar is configured for. Empty for a shared calendar. The resolution order picks an organisation's calendar when the timer names none.": "UUID organizacije za koju je ovaj kalendar postavljen. Prazno za dijeljeni kalendar. Ne imenuje li tajmer nijedan, redoslijed razrješavanja bira kalendar organizacije.",
+ "UUID of the organisation this ladder is the default for. Empty for the shared default.": "UUID organizacije kojoj je ova ljestvica zadana. Prazno za dijeljenu zadanu.",
+ "When weekday": "Padne li na",
+ "Whether reaching this rung opens an incident.": "Otvara li dosezanje ove prečke incident.",
+ "Why the day is closed.": "Zašto je dan zatvoren.",
+ "Working calendar": "Radni kalendar",
+ "Working hours in one working day. Makes hours and businessDays commensurable.": "Radni sati u jednom radnom danu. Čini sate i radne dane usporedivima.",
+ "Working weekdays": "Radni dani u tjednu",
+ "fixed: a month/day; easter: an offset in days from Easter Sunday; observedShift: a month/day with a required observed shift.": "fixed: mjesec i dan; easter: odmak u danima od Uskrsne nedjelje; observedShift: mjesec i dan s obveznim premještanjem.",
+ "preBreach fires before the deadline, slaBreached at or after it.": "preBreach se okida prije roka, slaBreached na rok ili poslije njega.",
+ "No such task": "Nema takvog zadatka",
+ "The task does not exist, or it is not yours to see.": "Zadatak ne postoji ili ga ne smijete vidjeti.",
+ "Details": "Detalji",
+ "Due": "Rok",
+ "Assignee": "Dodijeljeno",
+ "Requested by": "Zatražio",
+ "Outcome": "Ishod",
+ "Ready to claim": "Spremno za preuzimanje",
+ "In progress": "U tijeku",
+ "Terminated": "Prekinuto",
+ "Normal": "Normalno",
+ "Urgent": "Hitno",
+ "Overdue by 1 day": "Kasni 1 dan",
+ "Overdue by {days} days": "Kasni {days} dana",
+ "Due today": "Rok je danas",
+ "Due tomorrow": "Rok je sutra",
+ "Due in {days} days": "Rok za {days} dana",
+ "Tasks": "Zadaci",
+ "Task": "Zadatak",
+ "Unassigned, open for claiming": "Nedodijeljeno, otvoreno za preuzimanje",
+ "Claim": "Preuzmi",
+ "Complete": "Dovrši",
+ "Complete: {outcome}": "Dovrši: {outcome}",
+ "Could not load the task": "Zadatak se ne može učitati",
+ "The task refused that action": "Zadatak je odbio tu radnju"
},
"nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;"
)
diff --git a/l10n/hr.json b/l10n/hr.json
index 86f991d6e1..0517a277e8 100644
--- a/l10n/hr.json
+++ b/l10n/hr.json
@@ -1,10 +1,20 @@
{
"translations": {
+ "from amount {amount}": "od iznosa {amount}",
+ "Gated transition: {transition}": "Nadzirani prijelaz: {transition}",
+ "Each declared chain provisions an ordered task sequence when its transition is attempted. Approvers decide in their task inbox, not here.": "Svaki deklarirani lanac otvara uređeni niz zadataka kad se prijelaz pokuša. Odobravatelji odlučuju u svojoj ulaznoj listi zadataka, ne ovdje.",
+ "Declare x-openregister-approval-chains on this schema to gate a lifecycle transition on approval.": "Deklarirajte x-openregister-approval-chains na ovoj shemi kako biste prijelaz životnog ciklusa uvjetovali odobrenjem.",
+ "Approval sequences": "Nizovi odobravanja",
"%n entries have no hash yet": "%n unosa još nema hash",
"%n entry has no hash yet": "%n unos još nema hash",
"(Dolphin required)": "(Potreban Dolphin)",
+ "No approval chains declared": "Nema deklariranih lanaca odobravanja",
"(no subject)": "(bez predmeta)",
"(no title)": "(bez naslova)",
+ "Role {role}": "Uloga {role}",
+ "The transition is applied automatically once every step approves.": "Prijelaz se primjenjuje automatski čim je svaki korak odobren.",
+ "The requester may not decide their own approval.": "Podnositelj zahtjeva ne može odlučivati o vlastitom odobrenju.",
+ "Tier routing on field: {field}": "Usmjeravanje po razredima prema polju: {field}",
"(unnamed)": "(bez naziva)",
"(untitled card)": "(kartica bez naslova)",
"({count} selected)": "({count} odabrano)",
@@ -2801,7 +2811,84 @@
"Uspješno vraćen {count} objekt",
"Uspješno vraćena {count} objekta",
"Uspješno vraćeno {count} objekata"
- ]
+ ],
+ "A message identity the notification subsystem resolves.": "Identitet poruke koji razrješava sustav obavijesti.",
+ "Computed non-working-date rules. kind fixed: {month, day, name, observedShift?: {whenWeekday, days}}. kind easter: {offset, name}, offset in days from Easter Sunday. kind observedShift: a fixed date with a required shift.": "Izračunata pravila neradnih dana. Vrsta fixed: {month, day, name, observedShift?: {whenWeekday, days}}. Vrsta easter: {offset, name}, odmak u danima od Uskrsne nedjelje. Vrsta observedShift: nepomičan datum s obveznim premještanjem.",
+ "Date": "Datum",
+ "Day": "Dan",
+ "Day of a fixed or observedShift rule; ignored by an easter rule.": "Dan pravila fixed ili observedShift; pravilo easter ga zanemaruje.",
+ "Days": "Dani",
+ "Days from Easter Sunday for an easter rule; ignored by the other kinds.": "Dani od Uskrsne nedjelje za pravilo easter; druge ih vrste zanemaruju.",
+ "Distance from the deadline, in the offset unit.": "Udaljenost od roka u jedinici odmaka.",
+ "Enumerated one-off closures as {date, name}. Allowed alongside rules; refused as the whole calendar.": "Pojedinačna zatvaranja nabrojena kao {date, name}. Dopuštena uz pravila; odbijena kao cijeli kalendar.",
+ "Escalate to roles": "Uloge za eskalaciju",
+ "Escalation ladder": "Ljestvica eskalacije",
+ "Exception dates": "Iznimni datumi",
+ "Hours per working day": "Sati po radnom danu",
+ "How many days the observed date shifts, e.g. -1 for the Saturday before.": "Za koliko se dana slavljeni datum premješta, npr. -1 za subotu prije.",
+ "Human-readable title.": "Čitljiv naslov.",
+ "ISO weekdays (1 = Monday, 7 = Sunday) that are working days.": "ISO dani u tjednu (1 = ponedjeljak, 7 = nedjelja) koji su radni.",
+ "Kind": "Vrsta",
+ "Message": "Poruka",
+ "Month": "Mjesec",
+ "Month of a fixed or observedShift rule; ignored by an easter rule.": "Mjesec pravila fixed ili observedShift; pravilo easter ga zanemaruje.",
+ "Non-working-date rules": "Pravila neradnih dana",
+ "Notify roles": "Uloge za obavijest",
+ "Observed shift": "Premještanje blagdana",
+ "Offset": "Odmak",
+ "Offset unit": "Jedinica odmaka",
+ "Open incident": "Otvori incident",
+ "Optional map from a role name to a concrete recipient descriptor, e.g. {\"teamleader\": \"group:teamleaders\"}. Roles without a binding travel unresolved as role:.": "Neobvezna mapa imena uloge na konkretnog primatelja, npr. {\"teamleader\": \"group:teamleaders\"}. Uloge bez poveznice putuju nerazriješene kao role:.",
+ "Optional on a fixed rule, required on observedShift: {whenWeekday: weekday name or ISO 1..7, days: integer}.": "Neobvezno kod pravila fixed, obvezno kod observedShift: {whenWeekday: ime dana ili ISO 1..7, days: cijeli broj}.",
+ "Ordered rungs: {key, trigger (preBreach|slaBreached), offset, offsetUnit (hours|businessDays|calendarDays), notifyRole[], escalateToRole[], priority, message, openIncident}.": "Poredane prečke: {key, trigger (preBreach|slaBreached), offset, offsetUnit (hours|businessDays|calendarDays), notifyRole[], escalateToRole[], priority, message, openIncident}.",
+ "Priority": "Prioritet",
+ "Role bindings": "Poveznice uloga",
+ "Roles the matter is escalated to at this rung.": "Uloge na koje se predmet na ovoj prečki eskalira.",
+ "Roles told at this rung; handler is the subject's own performer.": "Uloge obaviještene na ovoj prečki; handler je osoba koja rješava predmet.",
+ "Rungs": "Prečke",
+ "Stable rung identity, e.g. preBreach:14:calendarDays; derived from trigger, offset and unit when absent.": "Stalni identitet prečke, npr. preBreach:14:calendarDays; ako nedostaje, izvodi se iz okidača, odmaka i jedinice.",
+ "The calendar's stable name, referenced by a timer's calendar_slug.": "Stalno ime kalendara na koje se tajmer poziva putem calendar_slug.",
+ "The closed date, Y-m-d.": "Datum zatvaranja, Y-m-d.",
+ "The holiday's name.": "Ime blagdana.",
+ "The ladder's stable name, referenced by a timer's ladder_slug.": "Stalno ime ljestvice na koje se tajmer poziva putem ladder_slug.",
+ "The unit of the offset: the same set the SLA accepts.": "Jedinica odmaka: isti skup koji SLA prihvaća.",
+ "The urgency the raised transition carries.": "Hitnost koju nosi pokrenuti prijelaz.",
+ "The weekday (name) on which the date shifts, e.g. sunday for Koningsdag.": "Dan u tjednu (ime) na koji se datum premješta, npr. sunday za Koningsdag.",
+ "UUID of the organisation this calendar is configured for. Empty for a shared calendar. The resolution order picks an organisation's calendar when the timer names none.": "UUID organizacije za koju je ovaj kalendar postavljen. Prazno za dijeljeni kalendar. Ne imenuje li tajmer nijedan, redoslijed razrješavanja bira kalendar organizacije.",
+ "UUID of the organisation this ladder is the default for. Empty for the shared default.": "UUID organizacije kojoj je ova ljestvica zadana. Prazno za dijeljenu zadanu.",
+ "When weekday": "Padne li na",
+ "Whether reaching this rung opens an incident.": "Otvara li dosezanje ove prečke incident.",
+ "Why the day is closed.": "Zašto je dan zatvoren.",
+ "Working calendar": "Radni kalendar",
+ "Working hours in one working day. Makes hours and businessDays commensurable.": "Radni sati u jednom radnom danu. Čini sate i radne dane usporedivima.",
+ "Working weekdays": "Radni dani u tjednu",
+ "fixed: a month/day; easter: an offset in days from Easter Sunday; observedShift: a month/day with a required observed shift.": "fixed: mjesec i dan; easter: odmak u danima od Uskrsne nedjelje; observedShift: mjesec i dan s obveznim premještanjem.",
+ "preBreach fires before the deadline, slaBreached at or after it.": "preBreach se okida prije roka, slaBreached na rok ili poslije njega.",
+ "No such task": "Nema takvog zadatka",
+ "The task does not exist, or it is not yours to see.": "Zadatak ne postoji ili ga ne smijete vidjeti.",
+ "Details": "Detalji",
+ "Due": "Rok",
+ "Assignee": "Dodijeljeno",
+ "Requested by": "Zatražio",
+ "Outcome": "Ishod",
+ "Ready to claim": "Spremno za preuzimanje",
+ "In progress": "U tijeku",
+ "Terminated": "Prekinuto",
+ "Normal": "Normalno",
+ "Urgent": "Hitno",
+ "Overdue by 1 day": "Kasni 1 dan",
+ "Overdue by {days} days": "Kasni {days} dana",
+ "Due today": "Rok je danas",
+ "Due tomorrow": "Rok je sutra",
+ "Due in {days} days": "Rok za {days} dana",
+ "Tasks": "Zadaci",
+ "Task": "Zadatak",
+ "Unassigned, open for claiming": "Nedodijeljeno, otvoreno za preuzimanje",
+ "Claim": "Preuzmi",
+ "Complete": "Dovrši",
+ "Complete: {outcome}": "Dovrši: {outcome}",
+ "Could not load the task": "Zadatak se ne može učitati",
+ "The task refused that action": "Zadatak je odbio tu radnju"
},
"pluralForm": "nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;",
"plurals": {
diff --git a/l10n/hu.js b/l10n/hu.js
index 61aaa83545..70ca52daaf 100644
--- a/l10n/hu.js
+++ b/l10n/hu.js
@@ -3,11 +3,21 @@ OC.L10N.register(
{
"3": "3",
"30": "30",
+ "from amount {amount}": "{amount} összegtől",
+ "Gated transition: {transition}": "Őrzött átmenet: {transition}",
+ "Each declared chain provisions an ordered task sequence when its transition is attempted. Approvers decide in their task inbox, not here.": "Minden deklarált lánc rendezett feladatsorozatot nyit, amikor az átmenetet megkísérlik. A jóváhagyók a feladat-bejövőjükben döntenek, nem itt.",
+ "Declare x-openregister-approval-chains on this schema to gate a lifecycle transition on approval.": "Deklarálja az x-openregister-approval-chains kulcsot ezen a sémán, hogy egy életciklus-átmenet jóváhagyáshoz legyen kötve.",
+ "Approval sequences": "Jóváhagyási sorozatok",
"%n entries have no hash yet": "%n bejegyzésnek még nincs kivonata",
"%n entry has no hash yet": "%n bejegyzésnek még nincs kivonata",
"(Dolphin required)": "(Dolphin szükséges)",
+ "No approval chains declared": "Nincs deklarált jóváhagyási lánc",
"(no subject)": "(nincs tárgy)",
"(no title)": "(nincs cím)",
+ "Role {role}": "Szerep {role}",
+ "The transition is applied automatically once every step approves.": "Az átmenet automatikusan végbemegy, amint minden lépést jóváhagytak.",
+ "The requester may not decide their own approval.": "A kérelmező nem dönthet a saját jóváhagyásáról.",
+ "Tier routing on field: {field}": "Sávos útválasztás a mező alapján: {field}",
"(unnamed)": "(névtelen)",
"(untitled card)": "(cím nélküli kártya)",
"({count} selected)": "({count} kiválasztva)",
@@ -2738,7 +2748,84 @@ OC.L10N.register(
"_Object successfully deleted_::_Objects successfully deleted_": ["Az objektum sikeresen törölve","Az objektumok sikeresen törölve"],
"_Purge {count} object from database_::_Purge {count} objects from database_": ["{count} objektum végleges törlése az adatbázisból","{count} objektum végleges törlése az adatbázisból"],
"_Restore {count} object_::_Restore {count} objects_": ["{count} objektum visszaállítása","{count} objektum visszaállítása"],
- "_Successfully restored {count} object_::_Successfully restored {count} objects_": ["{count} objektum sikeresen visszaállítva","{count} objektum sikeresen visszaállítva"]
+ "_Successfully restored {count} object_::_Successfully restored {count} objects_": ["{count} objektum sikeresen visszaállítva","{count} objektum sikeresen visszaállítva"],
+ "A message identity the notification subsystem resolves.": "A message identity the notification subsystem resolves.",
+ "Computed non-working-date rules. kind fixed: {month, day, name, observedShift?: {whenWeekday, days}}. kind easter: {offset, name}, offset in days from Easter Sunday. kind observedShift: a fixed date with a required shift.": "Computed non-working-date rules. kind fixed: {month, day, name, observedShift?: {whenWeekday, days}}. kind easter: {offset, name}, offset in days from Easter Sunday. kind observedShift: a fixed date with a required shift.",
+ "Date": "Date",
+ "Day": "Day",
+ "Day of a fixed or observedShift rule; ignored by an easter rule.": "Day of a fixed or observedShift rule; ignored by an easter rule.",
+ "Days": "Days",
+ "Days from Easter Sunday for an easter rule; ignored by the other kinds.": "Days from Easter Sunday for an easter rule; ignored by the other kinds.",
+ "Distance from the deadline, in the offset unit.": "Distance from the deadline, in the offset unit.",
+ "Enumerated one-off closures as {date, name}. Allowed alongside rules; refused as the whole calendar.": "Enumerated one-off closures as {date, name}. Allowed alongside rules; refused as the whole calendar.",
+ "Escalate to roles": "Escalate to roles",
+ "Escalation ladder": "Escalation ladder",
+ "Exception dates": "Exception dates",
+ "Hours per working day": "Hours per working day",
+ "How many days the observed date shifts, e.g. -1 for the Saturday before.": "How many days the observed date shifts, e.g. -1 for the Saturday before.",
+ "Human-readable title.": "Human-readable title.",
+ "ISO weekdays (1 = Monday, 7 = Sunday) that are working days.": "ISO weekdays (1 = Monday, 7 = Sunday) that are working days.",
+ "Kind": "Kind",
+ "Message": "Message",
+ "Month": "Month",
+ "Month of a fixed or observedShift rule; ignored by an easter rule.": "Month of a fixed or observedShift rule; ignored by an easter rule.",
+ "Non-working-date rules": "Non-working-date rules",
+ "Notify roles": "Notify roles",
+ "Observed shift": "Observed shift",
+ "Offset": "Offset",
+ "Offset unit": "Offset unit",
+ "Open incident": "Open incident",
+ "Optional map from a role name to a concrete recipient descriptor, e.g. {\"teamleader\": \"group:teamleaders\"}. Roles without a binding travel unresolved as role:.": "Optional map from a role name to a concrete recipient descriptor, e.g. {\"teamleader\": \"group:teamleaders\"}. Roles without a binding travel unresolved as role:.",
+ "Optional on a fixed rule, required on observedShift: {whenWeekday: weekday name or ISO 1..7, days: integer}.": "Optional on a fixed rule, required on observedShift: {whenWeekday: weekday name or ISO 1..7, days: integer}.",
+ "Ordered rungs: {key, trigger (preBreach|slaBreached), offset, offsetUnit (hours|businessDays|calendarDays), notifyRole[], escalateToRole[], priority, message, openIncident}.": "Ordered rungs: {key, trigger (preBreach|slaBreached), offset, offsetUnit (hours|businessDays|calendarDays), notifyRole[], escalateToRole[], priority, message, openIncident}.",
+ "Priority": "Priority",
+ "Role bindings": "Role bindings",
+ "Roles the matter is escalated to at this rung.": "Roles the matter is escalated to at this rung.",
+ "Roles told at this rung; handler is the subject's own performer.": "Roles told at this rung; handler is the subject's own performer.",
+ "Rungs": "Rungs",
+ "Stable rung identity, e.g. preBreach:14:calendarDays; derived from trigger, offset and unit when absent.": "Stable rung identity, e.g. preBreach:14:calendarDays; derived from trigger, offset and unit when absent.",
+ "The calendar's stable name, referenced by a timer's calendar_slug.": "The calendar's stable name, referenced by a timer's calendar_slug.",
+ "The closed date, Y-m-d.": "The closed date, Y-m-d.",
+ "The holiday's name.": "The holiday's name.",
+ "The ladder's stable name, referenced by a timer's ladder_slug.": "The ladder's stable name, referenced by a timer's ladder_slug.",
+ "The unit of the offset: the same set the SLA accepts.": "The unit of the offset: the same set the SLA accepts.",
+ "The urgency the raised transition carries.": "The urgency the raised transition carries.",
+ "The weekday (name) on which the date shifts, e.g. sunday for Koningsdag.": "The weekday (name) on which the date shifts, e.g. sunday for Koningsdag.",
+ "UUID of the organisation this calendar is configured for. Empty for a shared calendar. The resolution order picks an organisation's calendar when the timer names none.": "UUID of the organisation this calendar is configured for. Empty for a shared calendar. The resolution order picks an organisation's calendar when the timer names none.",
+ "UUID of the organisation this ladder is the default for. Empty for the shared default.": "UUID of the organisation this ladder is the default for. Empty for the shared default.",
+ "When weekday": "When weekday",
+ "Whether reaching this rung opens an incident.": "Whether reaching this rung opens an incident.",
+ "Why the day is closed.": "Why the day is closed.",
+ "Working calendar": "Working calendar",
+ "Working hours in one working day. Makes hours and businessDays commensurable.": "Working hours in one working day. Makes hours and businessDays commensurable.",
+ "Working weekdays": "Working weekdays",
+ "fixed: a month/day; easter: an offset in days from Easter Sunday; observedShift: a month/day with a required observed shift.": "fixed: a month/day; easter: an offset in days from Easter Sunday; observedShift: a month/day with a required observed shift.",
+ "preBreach fires before the deadline, slaBreached at or after it.": "preBreach fires before the deadline, slaBreached at or after it.",
+ "No such task": "Nincs ilyen feladat",
+ "The task does not exist, or it is not yours to see.": "A feladat nem létezik, vagy nem láthatja.",
+ "Details": "Részletek",
+ "Due": "Határidő",
+ "Assignee": "Felelős",
+ "Requested by": "Kérte",
+ "Outcome": "Eredmény",
+ "Ready to claim": "Átvehető",
+ "In progress": "Folyamatban",
+ "Terminated": "Megszakítva",
+ "Normal": "Normál",
+ "Urgent": "Sürgős",
+ "Overdue by 1 day": "1 napja lejárt",
+ "Overdue by {days} days": "{days} napja lejárt",
+ "Due today": "Ma esedékes",
+ "Due tomorrow": "Holnap esedékes",
+ "Due in {days} days": "{days} nap múlva esedékes",
+ "Tasks": "Feladatok",
+ "Task": "Feladat",
+ "Unassigned, open for claiming": "Nincs felelős, átvehető",
+ "Claim": "Átvétel",
+ "Complete": "Befejezés",
+ "Complete: {outcome}": "Befejezés: {outcome}",
+ "Could not load the task": "A feladat nem tölthető be",
+ "The task refused that action": "A feladat elutasította a műveletet"
},
"nplurals=2; plural=(n != 1);"
)
diff --git a/l10n/hu.json b/l10n/hu.json
index f19f05a909..1fc9ed2458 100644
--- a/l10n/hu.json
+++ b/l10n/hu.json
@@ -1,10 +1,20 @@
{
"translations": {
+ "from amount {amount}": "{amount} összegtől",
+ "Gated transition: {transition}": "Őrzött átmenet: {transition}",
+ "Each declared chain provisions an ordered task sequence when its transition is attempted. Approvers decide in their task inbox, not here.": "Minden deklarált lánc rendezett feladatsorozatot nyit, amikor az átmenetet megkísérlik. A jóváhagyók a feladat-bejövőjükben döntenek, nem itt.",
+ "Declare x-openregister-approval-chains on this schema to gate a lifecycle transition on approval.": "Deklarálja az x-openregister-approval-chains kulcsot ezen a sémán, hogy egy életciklus-átmenet jóváhagyáshoz legyen kötve.",
+ "Approval sequences": "Jóváhagyási sorozatok",
"%n entries have no hash yet": "%n bejegyzésnek még nincs kivonata",
"%n entry has no hash yet": "%n bejegyzésnek még nincs kivonata",
"(Dolphin required)": "(Dolphin szükséges)",
+ "No approval chains declared": "Nincs deklarált jóváhagyási lánc",
"(no subject)": "(nincs tárgy)",
"(no title)": "(nincs cím)",
+ "Role {role}": "Szerep {role}",
+ "The transition is applied automatically once every step approves.": "Az átmenet automatikusan végbemegy, amint minden lépést jóváhagytak.",
+ "The requester may not decide their own approval.": "A kérelmező nem dönthet a saját jóváhagyásáról.",
+ "Tier routing on field: {field}": "Sávos útválasztás a mező alapján: {field}",
"(unnamed)": "(névtelen)",
"(untitled card)": "(cím nélküli kártya)",
"({count} selected)": "({count} kiválasztva)",
@@ -2785,7 +2795,84 @@
"_Successfully restored {count} object_::_Successfully restored {count} objects_": [
"{count} objektum sikeresen visszaállítva",
"{count} objektum sikeresen visszaállítva"
- ]
+ ],
+ "A message identity the notification subsystem resolves.": "A message identity the notification subsystem resolves.",
+ "Computed non-working-date rules. kind fixed: {month, day, name, observedShift?: {whenWeekday, days}}. kind easter: {offset, name}, offset in days from Easter Sunday. kind observedShift: a fixed date with a required shift.": "Computed non-working-date rules. kind fixed: {month, day, name, observedShift?: {whenWeekday, days}}. kind easter: {offset, name}, offset in days from Easter Sunday. kind observedShift: a fixed date with a required shift.",
+ "Date": "Date",
+ "Day": "Day",
+ "Day of a fixed or observedShift rule; ignored by an easter rule.": "Day of a fixed or observedShift rule; ignored by an easter rule.",
+ "Days": "Days",
+ "Days from Easter Sunday for an easter rule; ignored by the other kinds.": "Days from Easter Sunday for an easter rule; ignored by the other kinds.",
+ "Distance from the deadline, in the offset unit.": "Distance from the deadline, in the offset unit.",
+ "Enumerated one-off closures as {date, name}. Allowed alongside rules; refused as the whole calendar.": "Enumerated one-off closures as {date, name}. Allowed alongside rules; refused as the whole calendar.",
+ "Escalate to roles": "Escalate to roles",
+ "Escalation ladder": "Escalation ladder",
+ "Exception dates": "Exception dates",
+ "Hours per working day": "Hours per working day",
+ "How many days the observed date shifts, e.g. -1 for the Saturday before.": "How many days the observed date shifts, e.g. -1 for the Saturday before.",
+ "Human-readable title.": "Human-readable title.",
+ "ISO weekdays (1 = Monday, 7 = Sunday) that are working days.": "ISO weekdays (1 = Monday, 7 = Sunday) that are working days.",
+ "Kind": "Kind",
+ "Message": "Message",
+ "Month": "Month",
+ "Month of a fixed or observedShift rule; ignored by an easter rule.": "Month of a fixed or observedShift rule; ignored by an easter rule.",
+ "Non-working-date rules": "Non-working-date rules",
+ "Notify roles": "Notify roles",
+ "Observed shift": "Observed shift",
+ "Offset": "Offset",
+ "Offset unit": "Offset unit",
+ "Open incident": "Open incident",
+ "Optional map from a role name to a concrete recipient descriptor, e.g. {\"teamleader\": \"group:teamleaders\"}. Roles without a binding travel unresolved as role:.": "Optional map from a role name to a concrete recipient descriptor, e.g. {\"teamleader\": \"group:teamleaders\"}. Roles without a binding travel unresolved as role:.",
+ "Optional on a fixed rule, required on observedShift: {whenWeekday: weekday name or ISO 1..7, days: integer}.": "Optional on a fixed rule, required on observedShift: {whenWeekday: weekday name or ISO 1..7, days: integer}.",
+ "Ordered rungs: {key, trigger (preBreach|slaBreached), offset, offsetUnit (hours|businessDays|calendarDays), notifyRole[], escalateToRole[], priority, message, openIncident}.": "Ordered rungs: {key, trigger (preBreach|slaBreached), offset, offsetUnit (hours|businessDays|calendarDays), notifyRole[], escalateToRole[], priority, message, openIncident}.",
+ "Priority": "Priority",
+ "Role bindings": "Role bindings",
+ "Roles the matter is escalated to at this rung.": "Roles the matter is escalated to at this rung.",
+ "Roles told at this rung; handler is the subject's own performer.": "Roles told at this rung; handler is the subject's own performer.",
+ "Rungs": "Rungs",
+ "Stable rung identity, e.g. preBreach:14:calendarDays; derived from trigger, offset and unit when absent.": "Stable rung identity, e.g. preBreach:14:calendarDays; derived from trigger, offset and unit when absent.",
+ "The calendar's stable name, referenced by a timer's calendar_slug.": "The calendar's stable name, referenced by a timer's calendar_slug.",
+ "The closed date, Y-m-d.": "The closed date, Y-m-d.",
+ "The holiday's name.": "The holiday's name.",
+ "The ladder's stable name, referenced by a timer's ladder_slug.": "The ladder's stable name, referenced by a timer's ladder_slug.",
+ "The unit of the offset: the same set the SLA accepts.": "The unit of the offset: the same set the SLA accepts.",
+ "The urgency the raised transition carries.": "The urgency the raised transition carries.",
+ "The weekday (name) on which the date shifts, e.g. sunday for Koningsdag.": "The weekday (name) on which the date shifts, e.g. sunday for Koningsdag.",
+ "UUID of the organisation this calendar is configured for. Empty for a shared calendar. The resolution order picks an organisation's calendar when the timer names none.": "UUID of the organisation this calendar is configured for. Empty for a shared calendar. The resolution order picks an organisation's calendar when the timer names none.",
+ "UUID of the organisation this ladder is the default for. Empty for the shared default.": "UUID of the organisation this ladder is the default for. Empty for the shared default.",
+ "When weekday": "When weekday",
+ "Whether reaching this rung opens an incident.": "Whether reaching this rung opens an incident.",
+ "Why the day is closed.": "Why the day is closed.",
+ "Working calendar": "Working calendar",
+ "Working hours in one working day. Makes hours and businessDays commensurable.": "Working hours in one working day. Makes hours and businessDays commensurable.",
+ "Working weekdays": "Working weekdays",
+ "fixed: a month/day; easter: an offset in days from Easter Sunday; observedShift: a month/day with a required observed shift.": "fixed: a month/day; easter: an offset in days from Easter Sunday; observedShift: a month/day with a required observed shift.",
+ "preBreach fires before the deadline, slaBreached at or after it.": "preBreach fires before the deadline, slaBreached at or after it.",
+ "No such task": "Nincs ilyen feladat",
+ "The task does not exist, or it is not yours to see.": "A feladat nem létezik, vagy nem láthatja.",
+ "Details": "Részletek",
+ "Due": "Határidő",
+ "Assignee": "Felelős",
+ "Requested by": "Kérte",
+ "Outcome": "Eredmény",
+ "Ready to claim": "Átvehető",
+ "In progress": "Folyamatban",
+ "Terminated": "Megszakítva",
+ "Normal": "Normál",
+ "Urgent": "Sürgős",
+ "Overdue by 1 day": "1 napja lejárt",
+ "Overdue by {days} days": "{days} napja lejárt",
+ "Due today": "Ma esedékes",
+ "Due tomorrow": "Holnap esedékes",
+ "Due in {days} days": "{days} nap múlva esedékes",
+ "Tasks": "Feladatok",
+ "Task": "Feladat",
+ "Unassigned, open for claiming": "Nincs felelős, átvehető",
+ "Claim": "Átvétel",
+ "Complete": "Befejezés",
+ "Complete: {outcome}": "Befejezés: {outcome}",
+ "Could not load the task": "A feladat nem tölthető be",
+ "The task refused that action": "A feladat elutasította a műveletet"
},
"pluralForm": "nplurals=2; plural=(n != 1);",
"plurals": {
diff --git a/l10n/is.js b/l10n/is.js
index 6a0deec75d..78c5eda719 100644
--- a/l10n/is.js
+++ b/l10n/is.js
@@ -3,11 +3,21 @@ OC.L10N.register(
{
"3": "3",
"30": "30",
+ "from amount {amount}": "frá upphæð {amount}",
+ "Gated transition: {transition}": "Vöktuð umskipti: {transition}",
+ "Each declared chain provisions an ordered task sequence when its transition is attempted. Approvers decide in their task inbox, not here.": "Hver skilgreind keðja opnar raðaða verkefnaröð þegar reynt er við umskiptin. Samþykkjendur ákveða í verkefnahólfinu sínu, ekki hér.",
+ "Declare x-openregister-approval-chains on this schema to gate a lifecycle transition on approval.": "Skilgreindu x-openregister-approval-chains á þessu skema svo að umskipti í lífsferli krefjist samþykkis.",
+ "Approval sequences": "Samþykktarraðir",
"%n entries have no hash yet": "%n færslur hafa ekki enn tætigildi",
"%n entry has no hash yet": "%n færsla hefur ekki enn tætigildi",
"(Dolphin required)": "(Dolphin krafist)",
+ "No approval chains declared": "Engar samþykktarkeðjur skilgreindar",
"(no subject)": "(ekkert efni)",
"(no title)": "(ekkert titill)",
+ "Role {role}": "Hlutverk {role}",
+ "The transition is applied automatically once every step approves.": "Umskiptin taka gildi sjálfkrafa þegar hvert skref hefur verið samþykkt.",
+ "The requester may not decide their own approval.": "Beiðandi má ekki ákveða eigin samþykki.",
+ "Tier routing on field: {field}": "Þrepabundin beining eftir reitnum: {field}",
"(unnamed)": "(ónefnt)",
"(untitled card)": "(kort án titils)",
"({count} selected)": "({count} valin)",
@@ -2738,7 +2748,84 @@ OC.L10N.register(
"_Object successfully deleted_::_Objects successfully deleted_": ["Hlutur eytt","Hlutir eyddir"],
"_Purge {count} object from database_::_Purge {count} objects from database_": ["Hreinsa {count} hlut úr gagnagrunni","Hreinsa {count} hluti úr gagnagrunni"],
"_Restore {count} object_::_Restore {count} objects_": ["Endurheimta {count} hlut","Endurheimta {count} hluti"],
- "_Successfully restored {count} object_::_Successfully restored {count} objects_": ["{count} hlutur endurheimtur","{count} hlutir endurheimtir"]
+ "_Successfully restored {count} object_::_Successfully restored {count} objects_": ["{count} hlutur endurheimtur","{count} hlutir endurheimtir"],
+ "A message identity the notification subsystem resolves.": "Auðkenni skilaboða sem tilkynningakerfið leysir úr.",
+ "Computed non-working-date rules. kind fixed: {month, day, name, observedShift?: {whenWeekday, days}}. kind easter: {offset, name}, offset in days from Easter Sunday. kind observedShift: a fixed date with a required shift.": "Reiknaðar reglur um frídaga. Tegund fixed: {month, day, name, observedShift?: {whenWeekday, days}}. Tegund easter: {offset, name}, hliðrun í dögum frá páskadegi. Tegund observedShift: föst dagsetning með skyldufærslu.",
+ "Date": "Dagsetning",
+ "Day": "Dagur",
+ "Day of a fixed or observedShift rule; ignored by an easter rule.": "Dagur reglu af tegund fixed eða observedShift; easter-regla hunsar hann.",
+ "Days": "Dagar",
+ "Days from Easter Sunday for an easter rule; ignored by the other kinds.": "Dagar frá páskadegi fyrir easter-reglu; aðrar tegundir hunsa þá.",
+ "Distance from the deadline, in the offset unit.": "Fjarlægð frá frestinum í einingu hliðrunarinnar.",
+ "Enumerated one-off closures as {date, name}. Allowed alongside rules; refused as the whole calendar.": "Stakar lokanir taldar upp sem {date, name}. Leyfðar með reglum; hafnað sem allt dagatalið.",
+ "Escalate to roles": "Hlutverk stigmögnunar",
+ "Escalation ladder": "Stigmögnunarstigi",
+ "Exception dates": "Undantekningardagsetningar",
+ "Hours per working day": "Klukkustundir á virkan dag",
+ "How many days the observed date shifts, e.g. -1 for the Saturday before.": "Hve marga daga hátíðardagurinn færist, t.d. -1 fyrir laugardaginn á undan.",
+ "Human-readable title.": "Læsilegur titill.",
+ "ISO weekdays (1 = Monday, 7 = Sunday) that are working days.": "ISO vikudagar (1 = mánudagur, 7 = sunnudagur) sem eru virkir dagar.",
+ "Kind": "Tegund",
+ "Message": "Skilaboð",
+ "Month": "Mánuður",
+ "Month of a fixed or observedShift rule; ignored by an easter rule.": "Mánuður reglu af tegund fixed eða observedShift; easter-regla hunsar hann.",
+ "Non-working-date rules": "Reglur um frídaga",
+ "Notify roles": "Hlutverk til að láta vita",
+ "Observed shift": "Færsla frídags",
+ "Offset": "Hliðrun",
+ "Offset unit": "Eining hliðrunar",
+ "Open incident": "Opna atvik",
+ "Optional map from a role name to a concrete recipient descriptor, e.g. {\"teamleader\": \"group:teamleaders\"}. Roles without a binding travel unresolved as role:.": "Valkvæð vörpun frá heiti hlutverks í ákveðinn viðtakanda, t.d. {\"teamleader\": \"group:teamleaders\"}. Hlutverk án tengingar ferðast óleyst sem role:.",
+ "Optional on a fixed rule, required on observedShift: {whenWeekday: weekday name or ISO 1..7, days: integer}.": "Valkvætt í fixed-reglu, skylda í observedShift: {whenWeekday: heiti dags eða ISO 1..7, days: heiltala}.",
+ "Ordered rungs: {key, trigger (preBreach|slaBreached), offset, offsetUnit (hours|businessDays|calendarDays), notifyRole[], escalateToRole[], priority, message, openIncident}.": "Röðuð þrep: {key, trigger (preBreach|slaBreached), offset, offsetUnit (hours|businessDays|calendarDays), notifyRole[], escalateToRole[], priority, message, openIncident}.",
+ "Priority": "Forgangur",
+ "Role bindings": "Hlutverkatengingar",
+ "Roles the matter is escalated to at this rung.": "Hlutverk sem málið er stigmagnað til á þessu þrepi.",
+ "Roles told at this rung; handler is the subject's own performer.": "Hlutverk sem fá tilkynningu á þessu þrepi; handler er sá sem fer með málið.",
+ "Rungs": "Þrep",
+ "Stable rung identity, e.g. preBreach:14:calendarDays; derived from trigger, offset and unit when absent.": "Fast auðkenni þrepsins, t.d. preBreach:14:calendarDays; vanti það er það leitt af gikk, hliðrun og einingu.",
+ "The calendar's stable name, referenced by a timer's calendar_slug.": "Fast heiti dagatalsins sem tímamælir vísar til með calendar_slug.",
+ "The closed date, Y-m-d.": "Lokunardagsetningin, Y-m-d.",
+ "The holiday's name.": "Heiti frídagsins.",
+ "The ladder's stable name, referenced by a timer's ladder_slug.": "Fast heiti stigans sem tímamælir vísar til með ladder_slug.",
+ "The unit of the offset: the same set the SLA accepts.": "Eining hliðrunarinnar: sama mengi og SLA samþykkir.",
+ "The urgency the raised transition carries.": "Brýnin sem umskiptin sem fara af stað bera.",
+ "The weekday (name) on which the date shifts, e.g. sunday for Koningsdag.": "Vikudagurinn (heiti) sem dagsetningin færist á, t.d. sunday fyrir Koningsdag.",
+ "UUID of the organisation this calendar is configured for. Empty for a shared calendar. The resolution order picks an organisation's calendar when the timer names none.": "UUID stofnunarinnar sem þetta dagatal er stillt fyrir. Tómt fyrir sameiginlegt dagatal. Ef tímamælirinn nefnir ekkert velur úrlausnarröðin dagatal stofnunarinnar.",
+ "UUID of the organisation this ladder is the default for. Empty for the shared default.": "UUID stofnunarinnar sem þessi stigi er sjálfgefinn fyrir. Tómt fyrir sameiginlega sjálfgefna stigann.",
+ "When weekday": "Ef ber upp á",
+ "Whether reaching this rung opens an incident.": "Hvort það að ná þessu þrepi opni atvik.",
+ "Why the day is closed.": "Hvers vegna dagurinn er lokaður.",
+ "Working calendar": "Vinnudagatal",
+ "Working hours in one working day. Makes hours and businessDays commensurable.": "Vinnustundir á einum virkum degi. Gerir klukkustundir og virka daga samanburðarhæfa.",
+ "Working weekdays": "Virkir dagar vikunnar",
+ "fixed: a month/day; easter: an offset in days from Easter Sunday; observedShift: a month/day with a required observed shift.": "fixed: mánuður og dagur; easter: hliðrun í dögum frá páskadegi; observedShift: mánuður og dagur með skyldufærslu.",
+ "preBreach fires before the deadline, slaBreached at or after it.": "preBreach fer af stað fyrir frestinn, slaBreached á fresti eða eftir hann.",
+ "No such task": "Engin slík verkefni",
+ "The task does not exist, or it is not yours to see.": "Verkefnið er ekki til, eða þú mátt ekki sjá það.",
+ "Details": "Nánar",
+ "Due": "Frestur",
+ "Assignee": "Úthlutað á",
+ "Requested by": "Óskað af",
+ "Outcome": "Niðurstaða",
+ "Ready to claim": "Tilbúið til að taka",
+ "In progress": "Í vinnslu",
+ "Terminated": "Hætt",
+ "Normal": "Venjulegt",
+ "Urgent": "Áríðandi",
+ "Overdue by 1 day": "1 degi yfir frest",
+ "Overdue by {days} days": "{days} dögum yfir frest",
+ "Due today": "Frestur í dag",
+ "Due tomorrow": "Frestur á morgun",
+ "Due in {days} days": "Frestur eftir {days} daga",
+ "Tasks": "Verkefni",
+ "Task": "Verkefni",
+ "Unassigned, open for claiming": "Óúthlutað, opið til að taka",
+ "Claim": "Taka",
+ "Complete": "Ljúka",
+ "Complete: {outcome}": "Ljúka: {outcome}",
+ "Could not load the task": "Gat ekki hlaðið verkefninu",
+ "The task refused that action": "Verkefnið hafnaði þeirri aðgerð"
},
"nplurals=2; plural=(n != 1);"
)
diff --git a/l10n/is.json b/l10n/is.json
index 47676bf7ad..58adb654dd 100644
--- a/l10n/is.json
+++ b/l10n/is.json
@@ -1,10 +1,20 @@
{
"translations": {
+ "from amount {amount}": "frá upphæð {amount}",
+ "Gated transition: {transition}": "Vöktuð umskipti: {transition}",
+ "Each declared chain provisions an ordered task sequence when its transition is attempted. Approvers decide in their task inbox, not here.": "Hver skilgreind keðja opnar raðaða verkefnaröð þegar reynt er við umskiptin. Samþykkjendur ákveða í verkefnahólfinu sínu, ekki hér.",
+ "Declare x-openregister-approval-chains on this schema to gate a lifecycle transition on approval.": "Skilgreindu x-openregister-approval-chains á þessu skema svo að umskipti í lífsferli krefjist samþykkis.",
+ "Approval sequences": "Samþykktarraðir",
"%n entries have no hash yet": "%n færslur hafa ekki enn tætigildi",
"%n entry has no hash yet": "%n færsla hefur ekki enn tætigildi",
"(Dolphin required)": "(Dolphin krafist)",
+ "No approval chains declared": "Engar samþykktarkeðjur skilgreindar",
"(no subject)": "(ekkert efni)",
"(no title)": "(ekkert titill)",
+ "Role {role}": "Hlutverk {role}",
+ "The transition is applied automatically once every step approves.": "Umskiptin taka gildi sjálfkrafa þegar hvert skref hefur verið samþykkt.",
+ "The requester may not decide their own approval.": "Beiðandi má ekki ákveða eigin samþykki.",
+ "Tier routing on field: {field}": "Þrepabundin beining eftir reitnum: {field}",
"(unnamed)": "(ónefnt)",
"(untitled card)": "(kort án titils)",
"({count} selected)": "({count} valin)",
@@ -2785,7 +2795,84 @@
"_Successfully restored {count} object_::_Successfully restored {count} objects_": [
"{count} hlutur endurheimtur",
"{count} hlutir endurheimtir"
- ]
+ ],
+ "A message identity the notification subsystem resolves.": "Auðkenni skilaboða sem tilkynningakerfið leysir úr.",
+ "Computed non-working-date rules. kind fixed: {month, day, name, observedShift?: {whenWeekday, days}}. kind easter: {offset, name}, offset in days from Easter Sunday. kind observedShift: a fixed date with a required shift.": "Reiknaðar reglur um frídaga. Tegund fixed: {month, day, name, observedShift?: {whenWeekday, days}}. Tegund easter: {offset, name}, hliðrun í dögum frá páskadegi. Tegund observedShift: föst dagsetning með skyldufærslu.",
+ "Date": "Dagsetning",
+ "Day": "Dagur",
+ "Day of a fixed or observedShift rule; ignored by an easter rule.": "Dagur reglu af tegund fixed eða observedShift; easter-regla hunsar hann.",
+ "Days": "Dagar",
+ "Days from Easter Sunday for an easter rule; ignored by the other kinds.": "Dagar frá páskadegi fyrir easter-reglu; aðrar tegundir hunsa þá.",
+ "Distance from the deadline, in the offset unit.": "Fjarlægð frá frestinum í einingu hliðrunarinnar.",
+ "Enumerated one-off closures as {date, name}. Allowed alongside rules; refused as the whole calendar.": "Stakar lokanir taldar upp sem {date, name}. Leyfðar með reglum; hafnað sem allt dagatalið.",
+ "Escalate to roles": "Hlutverk stigmögnunar",
+ "Escalation ladder": "Stigmögnunarstigi",
+ "Exception dates": "Undantekningardagsetningar",
+ "Hours per working day": "Klukkustundir á virkan dag",
+ "How many days the observed date shifts, e.g. -1 for the Saturday before.": "Hve marga daga hátíðardagurinn færist, t.d. -1 fyrir laugardaginn á undan.",
+ "Human-readable title.": "Læsilegur titill.",
+ "ISO weekdays (1 = Monday, 7 = Sunday) that are working days.": "ISO vikudagar (1 = mánudagur, 7 = sunnudagur) sem eru virkir dagar.",
+ "Kind": "Tegund",
+ "Message": "Skilaboð",
+ "Month": "Mánuður",
+ "Month of a fixed or observedShift rule; ignored by an easter rule.": "Mánuður reglu af tegund fixed eða observedShift; easter-regla hunsar hann.",
+ "Non-working-date rules": "Reglur um frídaga",
+ "Notify roles": "Hlutverk til að láta vita",
+ "Observed shift": "Færsla frídags",
+ "Offset": "Hliðrun",
+ "Offset unit": "Eining hliðrunar",
+ "Open incident": "Opna atvik",
+ "Optional map from a role name to a concrete recipient descriptor, e.g. {\"teamleader\": \"group:teamleaders\"}. Roles without a binding travel unresolved as role:.": "Valkvæð vörpun frá heiti hlutverks í ákveðinn viðtakanda, t.d. {\"teamleader\": \"group:teamleaders\"}. Hlutverk án tengingar ferðast óleyst sem role:.",
+ "Optional on a fixed rule, required on observedShift: {whenWeekday: weekday name or ISO 1..7, days: integer}.": "Valkvætt í fixed-reglu, skylda í observedShift: {whenWeekday: heiti dags eða ISO 1..7, days: heiltala}.",
+ "Ordered rungs: {key, trigger (preBreach|slaBreached), offset, offsetUnit (hours|businessDays|calendarDays), notifyRole[], escalateToRole[], priority, message, openIncident}.": "Röðuð þrep: {key, trigger (preBreach|slaBreached), offset, offsetUnit (hours|businessDays|calendarDays), notifyRole[], escalateToRole[], priority, message, openIncident}.",
+ "Priority": "Forgangur",
+ "Role bindings": "Hlutverkatengingar",
+ "Roles the matter is escalated to at this rung.": "Hlutverk sem málið er stigmagnað til á þessu þrepi.",
+ "Roles told at this rung; handler is the subject's own performer.": "Hlutverk sem fá tilkynningu á þessu þrepi; handler er sá sem fer með málið.",
+ "Rungs": "Þrep",
+ "Stable rung identity, e.g. preBreach:14:calendarDays; derived from trigger, offset and unit when absent.": "Fast auðkenni þrepsins, t.d. preBreach:14:calendarDays; vanti það er það leitt af gikk, hliðrun og einingu.",
+ "The calendar's stable name, referenced by a timer's calendar_slug.": "Fast heiti dagatalsins sem tímamælir vísar til með calendar_slug.",
+ "The closed date, Y-m-d.": "Lokunardagsetningin, Y-m-d.",
+ "The holiday's name.": "Heiti frídagsins.",
+ "The ladder's stable name, referenced by a timer's ladder_slug.": "Fast heiti stigans sem tímamælir vísar til með ladder_slug.",
+ "The unit of the offset: the same set the SLA accepts.": "Eining hliðrunarinnar: sama mengi og SLA samþykkir.",
+ "The urgency the raised transition carries.": "Brýnin sem umskiptin sem fara af stað bera.",
+ "The weekday (name) on which the date shifts, e.g. sunday for Koningsdag.": "Vikudagurinn (heiti) sem dagsetningin færist á, t.d. sunday fyrir Koningsdag.",
+ "UUID of the organisation this calendar is configured for. Empty for a shared calendar. The resolution order picks an organisation's calendar when the timer names none.": "UUID stofnunarinnar sem þetta dagatal er stillt fyrir. Tómt fyrir sameiginlegt dagatal. Ef tímamælirinn nefnir ekkert velur úrlausnarröðin dagatal stofnunarinnar.",
+ "UUID of the organisation this ladder is the default for. Empty for the shared default.": "UUID stofnunarinnar sem þessi stigi er sjálfgefinn fyrir. Tómt fyrir sameiginlega sjálfgefna stigann.",
+ "When weekday": "Ef ber upp á",
+ "Whether reaching this rung opens an incident.": "Hvort það að ná þessu þrepi opni atvik.",
+ "Why the day is closed.": "Hvers vegna dagurinn er lokaður.",
+ "Working calendar": "Vinnudagatal",
+ "Working hours in one working day. Makes hours and businessDays commensurable.": "Vinnustundir á einum virkum degi. Gerir klukkustundir og virka daga samanburðarhæfa.",
+ "Working weekdays": "Virkir dagar vikunnar",
+ "fixed: a month/day; easter: an offset in days from Easter Sunday; observedShift: a month/day with a required observed shift.": "fixed: mánuður og dagur; easter: hliðrun í dögum frá páskadegi; observedShift: mánuður og dagur með skyldufærslu.",
+ "preBreach fires before the deadline, slaBreached at or after it.": "preBreach fer af stað fyrir frestinn, slaBreached á fresti eða eftir hann.",
+ "No such task": "Engin slík verkefni",
+ "The task does not exist, or it is not yours to see.": "Verkefnið er ekki til, eða þú mátt ekki sjá það.",
+ "Details": "Nánar",
+ "Due": "Frestur",
+ "Assignee": "Úthlutað á",
+ "Requested by": "Óskað af",
+ "Outcome": "Niðurstaða",
+ "Ready to claim": "Tilbúið til að taka",
+ "In progress": "Í vinnslu",
+ "Terminated": "Hætt",
+ "Normal": "Venjulegt",
+ "Urgent": "Áríðandi",
+ "Overdue by 1 day": "1 degi yfir frest",
+ "Overdue by {days} days": "{days} dögum yfir frest",
+ "Due today": "Frestur í dag",
+ "Due tomorrow": "Frestur á morgun",
+ "Due in {days} days": "Frestur eftir {days} daga",
+ "Tasks": "Verkefni",
+ "Task": "Verkefni",
+ "Unassigned, open for claiming": "Óúthlutað, opið til að taka",
+ "Claim": "Taka",
+ "Complete": "Ljúka",
+ "Complete: {outcome}": "Ljúka: {outcome}",
+ "Could not load the task": "Gat ekki hlaðið verkefninu",
+ "The task refused that action": "Verkefnið hafnaði þeirri aðgerð"
},
"pluralForm": "nplurals=2; plural=(n != 1);",
"plurals": {
diff --git a/l10n/it.js b/l10n/it.js
index 52da4e1e18..a6ac33e01d 100644
--- a/l10n/it.js
+++ b/l10n/it.js
@@ -3,11 +3,21 @@ OC.L10N.register(
{
"3": "3",
"30": "30",
+ "from amount {amount}": "a partire dall'importo {amount}",
+ "Gated transition: {transition}": "Transizione controllata: {transition}",
+ "Each declared chain provisions an ordered task sequence when its transition is attempted. Approvers decide in their task inbox, not here.": "Ogni catena dichiarata apre una sequenza ordinata di attività quando la transizione viene tentata. Gli approvatori decidono nella loro casella attività, non qui.",
+ "Declare x-openregister-approval-chains on this schema to gate a lifecycle transition on approval.": "Dichiara x-openregister-approval-chains su questo schema per vincolare una transizione del ciclo di vita a un'approvazione.",
+ "Approval sequences": "Sequenze di approvazione",
"%n entries have no hash yet": "%n voci non hanno ancora un hash",
"%n entry has no hash yet": "%n voce non ha ancora un hash",
"(Dolphin required)": "(Dolphin richiesto)",
+ "No approval chains declared": "Nessuna catena di approvazione dichiarata",
"(no subject)": "(nessun oggetto)",
"(no title)": "(nessun titolo)",
+ "Role {role}": "Ruolo {role}",
+ "The transition is applied automatically once every step approves.": "La transizione viene applicata automaticamente quando ogni passaggio è approvato.",
+ "The requester may not decide their own approval.": "Il richiedente non può decidere sulla propria approvazione.",
+ "Tier routing on field: {field}": "Instradamento a scaglioni sul campo: {field}",
"(unnamed)": "(senza nome)",
"(untitled card)": "(scheda senza titolo)",
"({count} selected)": "({count} selezionati)",
@@ -2738,7 +2748,84 @@ OC.L10N.register(
"_Object successfully deleted_::_Objects successfully deleted_": ["Oggetto eliminato correttamente","Oggetti eliminati correttamente","Oggetti eliminati correttamente"],
"_Purge {count} object from database_::_Purge {count} objects from database_": ["Elimina definitivamente {count} oggetto dal database","Elimina definitivamente {count} oggetti dal database","Elimina definitivamente {count} oggetti dal database"],
"_Restore {count} object_::_Restore {count} objects_": ["Ripristina {count} oggetto","Ripristina {count} oggetti","Ripristina {count} oggetti"],
- "_Successfully restored {count} object_::_Successfully restored {count} objects_": ["Ripristinato correttamente {count} oggetto","Ripristinati correttamente {count} oggetti","Ripristinati correttamente {count} oggetti"]
+ "_Successfully restored {count} object_::_Successfully restored {count} objects_": ["Ripristinato correttamente {count} oggetto","Ripristinati correttamente {count} oggetti","Ripristinati correttamente {count} oggetti"],
+ "A message identity the notification subsystem resolves.": "Un'identità di messaggio risolta dal sistema di notifica.",
+ "Computed non-working-date rules. kind fixed: {month, day, name, observedShift?: {whenWeekday, days}}. kind easter: {offset, name}, offset in days from Easter Sunday. kind observedShift: a fixed date with a required shift.": "Regole calcolate dei giorni non lavorativi. Tipo fixed: {month, day, name, observedShift?: {whenWeekday, days}}. Tipo easter: {offset, name}, scostamento in giorni dalla domenica di Pasqua. Tipo observedShift: una data fissa con spostamento obbligatorio.",
+ "Date": "Data",
+ "Day": "Giorno",
+ "Day of a fixed or observedShift rule; ignored by an easter rule.": "Giorno di una regola fixed o observedShift; una regola easter lo ignora.",
+ "Days": "Giorni",
+ "Days from Easter Sunday for an easter rule; ignored by the other kinds.": "Giorni dalla domenica di Pasqua per una regola easter; gli altri tipi li ignorano.",
+ "Distance from the deadline, in the offset unit.": "Distanza dalla scadenza, nell'unità dello scostamento.",
+ "Enumerated one-off closures as {date, name}. Allowed alongside rules; refused as the whole calendar.": "Chiusure singole elencate come {date, name}. Ammesse accanto alle regole; rifiutate come intero calendario.",
+ "Escalate to roles": "Ruoli di escalation",
+ "Escalation ladder": "Scala di escalation",
+ "Exception dates": "Date di eccezione",
+ "Hours per working day": "Ore per giorno lavorativo",
+ "How many days the observed date shifts, e.g. -1 for the Saturday before.": "Di quanti giorni si sposta la data osservata, ad es. -1 per il sabato precedente.",
+ "Human-readable title.": "Titolo leggibile.",
+ "ISO weekdays (1 = Monday, 7 = Sunday) that are working days.": "Giorni ISO della settimana (1 = lunedì, 7 = domenica) che sono lavorativi.",
+ "Kind": "Tipo",
+ "Message": "Messaggio",
+ "Month": "Mese",
+ "Month of a fixed or observedShift rule; ignored by an easter rule.": "Mese di una regola fixed o observedShift; una regola easter lo ignora.",
+ "Non-working-date rules": "Regole dei giorni non lavorativi",
+ "Notify roles": "Ruoli da avvisare",
+ "Observed shift": "Spostamento della festività",
+ "Offset": "Scostamento",
+ "Offset unit": "Unità dello scostamento",
+ "Open incident": "Aprire un incidente",
+ "Optional map from a role name to a concrete recipient descriptor, e.g. {\"teamleader\": \"group:teamleaders\"}. Roles without a binding travel unresolved as role:.": "Mappa facoltativa da un nome di ruolo a un destinatario concreto, ad es. {\"teamleader\": \"group:teamleaders\"}. I ruoli senza associazione viaggiano irrisolti come role:.",
+ "Optional on a fixed rule, required on observedShift: {whenWeekday: weekday name or ISO 1..7, days: integer}.": "Facoltativo in una regola fixed, obbligatorio in observedShift: {whenWeekday: nome del giorno o ISO 1..7, days: intero}.",
+ "Ordered rungs: {key, trigger (preBreach|slaBreached), offset, offsetUnit (hours|businessDays|calendarDays), notifyRole[], escalateToRole[], priority, message, openIncident}.": "Gradini ordinati: {key, trigger (preBreach|slaBreached), offset, offsetUnit (hours|businessDays|calendarDays), notifyRole[], escalateToRole[], priority, message, openIncident}.",
+ "Priority": "Priorità",
+ "Role bindings": "Associazioni dei ruoli",
+ "Roles the matter is escalated to at this rung.": "Ruoli a cui la pratica viene fatta risalire a questo gradino.",
+ "Roles told at this rung; handler is the subject's own performer.": "Ruoli avvisati a questo gradino; handler è la persona incaricata della pratica.",
+ "Rungs": "Gradini",
+ "Stable rung identity, e.g. preBreach:14:calendarDays; derived from trigger, offset and unit when absent.": "Identità stabile del gradino, ad es. preBreach:14:calendarDays; se assente è derivata da innesco, scostamento e unità.",
+ "The calendar's stable name, referenced by a timer's calendar_slug.": "Il nome stabile del calendario, richiamato dal calendar_slug di un timer.",
+ "The closed date, Y-m-d.": "La data di chiusura, Y-m-d.",
+ "The holiday's name.": "Il nome della festività.",
+ "The ladder's stable name, referenced by a timer's ladder_slug.": "Il nome stabile della scala, richiamato dal ladder_slug di un timer.",
+ "The unit of the offset: the same set the SLA accepts.": "L'unità dello scostamento: lo stesso insieme accettato dallo SLA.",
+ "The urgency the raised transition carries.": "L'urgenza portata dalla transizione innescata.",
+ "The weekday (name) on which the date shifts, e.g. sunday for Koningsdag.": "Il giorno della settimana (nome) in cui la data viene spostata, ad es. sunday per Koningsdag.",
+ "UUID of the organisation this calendar is configured for. Empty for a shared calendar. The resolution order picks an organisation's calendar when the timer names none.": "UUID dell'organizzazione per cui questo calendario è configurato. Vuoto per un calendario condiviso. Se il timer non ne indica nessuno, l'ordine di risoluzione sceglie il calendario dell'organizzazione.",
+ "UUID of the organisation this ladder is the default for. Empty for the shared default.": "UUID dell'organizzazione per cui questa scala è la predefinita. Vuoto per il valore condiviso.",
+ "When weekday": "Se cade di",
+ "Whether reaching this rung opens an incident.": "Se il raggiungimento di questo gradino apre un incidente.",
+ "Why the day is closed.": "Perché quel giorno è chiuso.",
+ "Working calendar": "Calendario lavorativo",
+ "Working hours in one working day. Makes hours and businessDays commensurable.": "Ore lavorate in un giorno lavorativo. Rende confrontabili ore e giorni lavorativi.",
+ "Working weekdays": "Giorni lavorativi della settimana",
+ "fixed: a month/day; easter: an offset in days from Easter Sunday; observedShift: a month/day with a required observed shift.": "fixed: mese e giorno; easter: uno scostamento in giorni dalla domenica di Pasqua; observedShift: mese e giorno con spostamento obbligatorio.",
+ "preBreach fires before the deadline, slaBreached at or after it.": "preBreach scatta prima della scadenza, slaBreached alla scadenza o dopo.",
+ "No such task": "Nessuna attività trovata",
+ "The task does not exist, or it is not yours to see.": "L'attività non esiste o non puoi vederla.",
+ "Details": "Dettagli",
+ "Due": "Scadenza",
+ "Assignee": "Assegnatario",
+ "Requested by": "Richiesto da",
+ "Outcome": "Esito",
+ "Ready to claim": "Pronto da prendere in carico",
+ "In progress": "In corso",
+ "Terminated": "Terminata",
+ "Normal": "Normale",
+ "Urgent": "Urgente",
+ "Overdue by 1 day": "In ritardo di 1 giorno",
+ "Overdue by {days} days": "In ritardo di {days} giorni",
+ "Due today": "Scade oggi",
+ "Due tomorrow": "Scade domani",
+ "Due in {days} days": "Scade tra {days} giorni",
+ "Tasks": "Attività",
+ "Task": "Attività",
+ "Unassigned, open for claiming": "Non assegnata, aperta alla presa in carico",
+ "Claim": "Prendi in carico",
+ "Complete": "Completa",
+ "Complete: {outcome}": "Completa: {outcome}",
+ "Could not load the task": "Impossibile caricare l'attività",
+ "The task refused that action": "L'attività ha rifiutato l'azione"
},
"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"
)
diff --git a/l10n/it.json b/l10n/it.json
index 5191833a9a..8243d48077 100644
--- a/l10n/it.json
+++ b/l10n/it.json
@@ -1,10 +1,20 @@
{
"translations": {
+ "from amount {amount}": "a partire dall'importo {amount}",
+ "Gated transition: {transition}": "Transizione controllata: {transition}",
+ "Each declared chain provisions an ordered task sequence when its transition is attempted. Approvers decide in their task inbox, not here.": "Ogni catena dichiarata apre una sequenza ordinata di attività quando la transizione viene tentata. Gli approvatori decidono nella loro casella attività, non qui.",
+ "Declare x-openregister-approval-chains on this schema to gate a lifecycle transition on approval.": "Dichiara x-openregister-approval-chains su questo schema per vincolare una transizione del ciclo di vita a un'approvazione.",
+ "Approval sequences": "Sequenze di approvazione",
"%n entries have no hash yet": "%n voci non hanno ancora un hash",
"%n entry has no hash yet": "%n voce non ha ancora un hash",
"(Dolphin required)": "(Dolphin richiesto)",
+ "No approval chains declared": "Nessuna catena di approvazione dichiarata",
"(no subject)": "(nessun oggetto)",
"(no title)": "(nessun titolo)",
+ "Role {role}": "Ruolo {role}",
+ "The transition is applied automatically once every step approves.": "La transizione viene applicata automaticamente quando ogni passaggio è approvato.",
+ "The requester may not decide their own approval.": "Il richiedente non può decidere sulla propria approvazione.",
+ "Tier routing on field: {field}": "Instradamento a scaglioni sul campo: {field}",
"(unnamed)": "(senza nome)",
"(untitled card)": "(scheda senza titolo)",
"({count} selected)": "({count} selezionati)",
@@ -2801,7 +2811,84 @@
"Ripristinato correttamente {count} oggetto",
"Ripristinati correttamente {count} oggetti",
"Ripristinati correttamente {count} oggetti"
- ]
+ ],
+ "A message identity the notification subsystem resolves.": "Un'identità di messaggio risolta dal sistema di notifica.",
+ "Computed non-working-date rules. kind fixed: {month, day, name, observedShift?: {whenWeekday, days}}. kind easter: {offset, name}, offset in days from Easter Sunday. kind observedShift: a fixed date with a required shift.": "Regole calcolate dei giorni non lavorativi. Tipo fixed: {month, day, name, observedShift?: {whenWeekday, days}}. Tipo easter: {offset, name}, scostamento in giorni dalla domenica di Pasqua. Tipo observedShift: una data fissa con spostamento obbligatorio.",
+ "Date": "Data",
+ "Day": "Giorno",
+ "Day of a fixed or observedShift rule; ignored by an easter rule.": "Giorno di una regola fixed o observedShift; una regola easter lo ignora.",
+ "Days": "Giorni",
+ "Days from Easter Sunday for an easter rule; ignored by the other kinds.": "Giorni dalla domenica di Pasqua per una regola easter; gli altri tipi li ignorano.",
+ "Distance from the deadline, in the offset unit.": "Distanza dalla scadenza, nell'unità dello scostamento.",
+ "Enumerated one-off closures as {date, name}. Allowed alongside rules; refused as the whole calendar.": "Chiusure singole elencate come {date, name}. Ammesse accanto alle regole; rifiutate come intero calendario.",
+ "Escalate to roles": "Ruoli di escalation",
+ "Escalation ladder": "Scala di escalation",
+ "Exception dates": "Date di eccezione",
+ "Hours per working day": "Ore per giorno lavorativo",
+ "How many days the observed date shifts, e.g. -1 for the Saturday before.": "Di quanti giorni si sposta la data osservata, ad es. -1 per il sabato precedente.",
+ "Human-readable title.": "Titolo leggibile.",
+ "ISO weekdays (1 = Monday, 7 = Sunday) that are working days.": "Giorni ISO della settimana (1 = lunedì, 7 = domenica) che sono lavorativi.",
+ "Kind": "Tipo",
+ "Message": "Messaggio",
+ "Month": "Mese",
+ "Month of a fixed or observedShift rule; ignored by an easter rule.": "Mese di una regola fixed o observedShift; una regola easter lo ignora.",
+ "Non-working-date rules": "Regole dei giorni non lavorativi",
+ "Notify roles": "Ruoli da avvisare",
+ "Observed shift": "Spostamento della festività",
+ "Offset": "Scostamento",
+ "Offset unit": "Unità dello scostamento",
+ "Open incident": "Aprire un incidente",
+ "Optional map from a role name to a concrete recipient descriptor, e.g. {\"teamleader\": \"group:teamleaders\"}. Roles without a binding travel unresolved as role:.": "Mappa facoltativa da un nome di ruolo a un destinatario concreto, ad es. {\"teamleader\": \"group:teamleaders\"}. I ruoli senza associazione viaggiano irrisolti come role:.",
+ "Optional on a fixed rule, required on observedShift: {whenWeekday: weekday name or ISO 1..7, days: integer}.": "Facoltativo in una regola fixed, obbligatorio in observedShift: {whenWeekday: nome del giorno o ISO 1..7, days: intero}.",
+ "Ordered rungs: {key, trigger (preBreach|slaBreached), offset, offsetUnit (hours|businessDays|calendarDays), notifyRole[], escalateToRole[], priority, message, openIncident}.": "Gradini ordinati: {key, trigger (preBreach|slaBreached), offset, offsetUnit (hours|businessDays|calendarDays), notifyRole[], escalateToRole[], priority, message, openIncident}.",
+ "Priority": "Priorità",
+ "Role bindings": "Associazioni dei ruoli",
+ "Roles the matter is escalated to at this rung.": "Ruoli a cui la pratica viene fatta risalire a questo gradino.",
+ "Roles told at this rung; handler is the subject's own performer.": "Ruoli avvisati a questo gradino; handler è la persona incaricata della pratica.",
+ "Rungs": "Gradini",
+ "Stable rung identity, e.g. preBreach:14:calendarDays; derived from trigger, offset and unit when absent.": "Identità stabile del gradino, ad es. preBreach:14:calendarDays; se assente è derivata da innesco, scostamento e unità.",
+ "The calendar's stable name, referenced by a timer's calendar_slug.": "Il nome stabile del calendario, richiamato dal calendar_slug di un timer.",
+ "The closed date, Y-m-d.": "La data di chiusura, Y-m-d.",
+ "The holiday's name.": "Il nome della festività.",
+ "The ladder's stable name, referenced by a timer's ladder_slug.": "Il nome stabile della scala, richiamato dal ladder_slug di un timer.",
+ "The unit of the offset: the same set the SLA accepts.": "L'unità dello scostamento: lo stesso insieme accettato dallo SLA.",
+ "The urgency the raised transition carries.": "L'urgenza portata dalla transizione innescata.",
+ "The weekday (name) on which the date shifts, e.g. sunday for Koningsdag.": "Il giorno della settimana (nome) in cui la data viene spostata, ad es. sunday per Koningsdag.",
+ "UUID of the organisation this calendar is configured for. Empty for a shared calendar. The resolution order picks an organisation's calendar when the timer names none.": "UUID dell'organizzazione per cui questo calendario è configurato. Vuoto per un calendario condiviso. Se il timer non ne indica nessuno, l'ordine di risoluzione sceglie il calendario dell'organizzazione.",
+ "UUID of the organisation this ladder is the default for. Empty for the shared default.": "UUID dell'organizzazione per cui questa scala è la predefinita. Vuoto per il valore condiviso.",
+ "When weekday": "Se cade di",
+ "Whether reaching this rung opens an incident.": "Se il raggiungimento di questo gradino apre un incidente.",
+ "Why the day is closed.": "Perché quel giorno è chiuso.",
+ "Working calendar": "Calendario lavorativo",
+ "Working hours in one working day. Makes hours and businessDays commensurable.": "Ore lavorate in un giorno lavorativo. Rende confrontabili ore e giorni lavorativi.",
+ "Working weekdays": "Giorni lavorativi della settimana",
+ "fixed: a month/day; easter: an offset in days from Easter Sunday; observedShift: a month/day with a required observed shift.": "fixed: mese e giorno; easter: uno scostamento in giorni dalla domenica di Pasqua; observedShift: mese e giorno con spostamento obbligatorio.",
+ "preBreach fires before the deadline, slaBreached at or after it.": "preBreach scatta prima della scadenza, slaBreached alla scadenza o dopo.",
+ "No such task": "Nessuna attività trovata",
+ "The task does not exist, or it is not yours to see.": "L'attività non esiste o non puoi vederla.",
+ "Details": "Dettagli",
+ "Due": "Scadenza",
+ "Assignee": "Assegnatario",
+ "Requested by": "Richiesto da",
+ "Outcome": "Esito",
+ "Ready to claim": "Pronto da prendere in carico",
+ "In progress": "In corso",
+ "Terminated": "Terminata",
+ "Normal": "Normale",
+ "Urgent": "Urgente",
+ "Overdue by 1 day": "In ritardo di 1 giorno",
+ "Overdue by {days} days": "In ritardo di {days} giorni",
+ "Due today": "Scade oggi",
+ "Due tomorrow": "Scade domani",
+ "Due in {days} days": "Scade tra {days} giorni",
+ "Tasks": "Attività",
+ "Task": "Attività",
+ "Unassigned, open for claiming": "Non assegnata, aperta alla presa in carico",
+ "Claim": "Prendi in carico",
+ "Complete": "Completa",
+ "Complete: {outcome}": "Completa: {outcome}",
+ "Could not load the task": "Impossibile caricare l'attività",
+ "The task refused that action": "L'attività ha rifiutato l'azione"
},
"pluralForm": "nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;",
"plurals": {
diff --git a/l10n/lb.js b/l10n/lb.js
index a5922f21e3..eb8951da29 100644
--- a/l10n/lb.js
+++ b/l10n/lb.js
@@ -3,11 +3,21 @@ OC.L10N.register(
{
"3": "3",
"30": "30",
+ "from amount {amount}": "ab Betrag {amount}",
+ "Gated transition: {transition}": "Iwwerwaachten Iwwergang: {transition}",
+ "Each declared chain provisions an ordered task sequence when its transition is attempted. Approvers decide in their task inbox, not here.": "All deklaréiert Kette mécht eng geuerdnet Aufgabesequenz op, wann den Iwwergang probéiert gëtt. Genehmeger entscheeden an hirer Aufgabemailbox, net hei.",
+ "Declare x-openregister-approval-chains on this schema to gate a lifecycle transition on approval.": "Deklaréiert x-openregister-approval-chains op dësem Schema, fir datt en Iwwergang am Liewenszyklus eng Genehmegung brauch.",
+ "Approval sequences": "Genehmegungssequenzen",
"%n entries have no hash yet": "%n Anträg hunn nach kee Hash",
"%n entry has no hash yet": "%n Antrag huet nach kee Hash",
"(Dolphin required)": "(Dolphin vereist)",
+ "No approval chains declared": "Keng Genehmegungsketten deklaréiert",
"(no subject)": "(kee Sujet)",
"(no title)": "(keen Titel)",
+ "Role {role}": "Roll {role}",
+ "The transition is applied automatically once every step approves.": "Den Iwwergang gëtt automatesch ugewannt, soubal all Schrëtt genehmegt ass.",
+ "The requester may not decide their own approval.": "Wien ufreet, dierf net iwwer seng eege Genehmegung entscheeden.",
+ "Tier routing on field: {field}": "Stufeweis Routing iwwert d'Feld: {field}",
"(unnamed)": "(ouni Numm)",
"(untitled card)": "(Kaart ouni Titel)",
"({count} selected)": "({count} geselecteerd)",
@@ -2738,7 +2748,84 @@ OC.L10N.register(
"_Object successfully deleted_::_Objects successfully deleted_": ["Object succesvol verwijderd","Objecten succesvol verwijderd"],
"_Purge {count} object from database_::_Purge {count} objects from database_": ["Verwijder {count} object uit de database","Verwijder {count} objecten uit de database"],
"_Restore {count} object_::_Restore {count} objects_": ["Herstel {count} object","Herstel {count} objecten"],
- "_Successfully restored {count} object_::_Successfully restored {count} objects_": ["{count} object succesvol hersteld","{count} objecten succesvol hersteld"]
+ "_Successfully restored {count} object_::_Successfully restored {count} objects_": ["{count} object succesvol hersteld","{count} objecten succesvol hersteld"],
+ "A message identity the notification subsystem resolves.": "Eng Message-Identitéit, déi den Notifikatiounssystem opléist.",
+ "Computed non-working-date rules. kind fixed: {month, day, name, observedShift?: {whenWeekday, days}}. kind easter: {offset, name}, offset in days from Easter Sunday. kind observedShift: a fixed date with a required shift.": "Berechent Reegele fir aarbechtsfräi Deeg. Zort fixed: {month, day, name, observedShift?: {whenWeekday, days}}. Zort easter: {offset, name}, Ofstand an Deeg vum Ouschtersonndeg. Zort observedShift: e fixen Datum mat obligatorescher Verréckelung.",
+ "Date": "Datum",
+ "Day": "Dag",
+ "Day of a fixed or observedShift rule; ignored by an easter rule.": "Den Dag vun enger fixed- oder observedShift-Reegel; eng easter-Reegel ignoréiert en.",
+ "Days": "Deeg",
+ "Days from Easter Sunday for an easter rule; ignored by the other kinds.": "Deeg vum Ouschtersonndeg fir eng easter-Reegel; déi aner Zorten ignoréiere se.",
+ "Distance from the deadline, in the offset unit.": "Distanz bis zur Frist, an der Eenheet vum Ofstand.",
+ "Enumerated one-off closures as {date, name}. Allowed alongside rules; refused as the whole calendar.": "Eenzel Zoumaachungen opgelëscht als {date, name}. Niewent Reegelen erlaabt; als ganze Kalenner refuséiert.",
+ "Escalate to roles": "Rolle fir d'Eskalatioun",
+ "Escalation ladder": "Eskalatiounsleeder",
+ "Exception dates": "Ausnamedatumer",
+ "Hours per working day": "Stonnen pro Aarbechtsdag",
+ "How many days the observed date shifts, e.g. -1 for the Saturday before.": "Ëm wéi vill Deeg de gefeierten Datum verréckelt gëtt, z. B. -1 fir de Samschdeg virdrun.",
+ "Human-readable title.": "Liesbaren Titel.",
+ "ISO weekdays (1 = Monday, 7 = Sunday) that are working days.": "ISO-Wochendeeg (1 = Méindeg, 7 = Sonndeg), déi Aarbechtsdeeg sinn.",
+ "Kind": "Zort",
+ "Message": "Message",
+ "Month": "Mount",
+ "Month of a fixed or observedShift rule; ignored by an easter rule.": "De Mount vun enger fixed- oder observedShift-Reegel; eng easter-Reegel ignoréiert en.",
+ "Non-working-date rules": "Reegele fir aarbechtsfräi Deeg",
+ "Notify roles": "Rollen déi informéiert ginn",
+ "Observed shift": "Verréckele vum Feierdag",
+ "Offset": "Ofstand",
+ "Offset unit": "Eenheet vum Ofstand",
+ "Open incident": "Incident opmaachen",
+ "Optional map from a role name to a concrete recipient descriptor, e.g. {\"teamleader\": \"group:teamleaders\"}. Roles without a binding travel unresolved as role:.": "Optional Zuerdnung vun engem Rollennumm op e konkreten Empfänger, z. B. {\"teamleader\": \"group:teamleaders\"}. Rollen ouni Zuerdnung reesen onopgeléist als role:.",
+ "Optional on a fixed rule, required on observedShift: {whenWeekday: weekday name or ISO 1..7, days: integer}.": "Optional bei enger fixed-Reegel, obligatoresch bei observedShift: {whenWeekday: Numm vum Dag oder ISO 1..7, days: ganz Zuel}.",
+ "Ordered rungs: {key, trigger (preBreach|slaBreached), offset, offsetUnit (hours|businessDays|calendarDays), notifyRole[], escalateToRole[], priority, message, openIncident}.": "Geuerdent Sprossen: {key, trigger (preBreach|slaBreached), offset, offsetUnit (hours|businessDays|calendarDays), notifyRole[], escalateToRole[], priority, message, openIncident}.",
+ "Priority": "Prioritéit",
+ "Role bindings": "Rollenzuerdnungen",
+ "Roles the matter is escalated to at this rung.": "Rollen, un déi de Fall op dëser Spross eskaléiert gëtt.",
+ "Roles told at this rung; handler is the subject's own performer.": "Rollen, déi op dëser Spross informéiert ginn; handler ass déi Persoun, déi de Fall behandelt.",
+ "Rungs": "Sprossen",
+ "Stable rung identity, e.g. preBreach:14:calendarDays; derived from trigger, offset and unit when absent.": "Fest Identitéit vun der Spross, z. B. preBreach:14:calendarDays; feelt se, gëtt se aus Ausléiser, Ofstand an Eenheet ofgeleet.",
+ "The calendar's stable name, referenced by a timer's calendar_slug.": "De feste Numm vum Kalenner, op deen en Timer iwwer calendar_slug verweist.",
+ "The closed date, Y-m-d.": "Den Datum vun der Zoumaachung, Y-m-d.",
+ "The holiday's name.": "Den Numm vum Feierdag.",
+ "The ladder's stable name, referenced by a timer's ladder_slug.": "De feste Numm vun der Leeder, op déi en Timer iwwer ladder_slug verweist.",
+ "The unit of the offset: the same set the SLA accepts.": "D'Eenheet vum Ofstand: déiselwecht Wäerter, déi den SLA akzeptéiert.",
+ "The urgency the raised transition carries.": "D'Dringlechkeet, déi den ausgeléisten Iwwergank dréit.",
+ "The weekday (name) on which the date shifts, e.g. sunday for Koningsdag.": "De Wochendag (Numm), op deem den Datum verréckelt gëtt, z. B. sunday fir Koningsdag.",
+ "UUID of the organisation this calendar is configured for. Empty for a shared calendar. The resolution order picks an organisation's calendar when the timer names none.": "UUID vun der Organisatioun, fir déi dëse Kalenner agestallt ass. Eidel bei engem gedeelte Kalenner. Nennt den Timer kengen, wielt d'Opléisungsuerdnung de Kalenner vun der Organisatioun.",
+ "UUID of the organisation this ladder is the default for. Empty for the shared default.": "UUID vun der Organisatioun, fir déi dës Leeder de Standard ass. Eidel beim gedeelte Standard.",
+ "When weekday": "Wann e fällt op",
+ "Whether reaching this rung opens an incident.": "Ob d'Erreeche vun dëser Spross en Incident opmécht.",
+ "Why the day is closed.": "Firwat dësen Dag zou ass.",
+ "Working calendar": "Aarbechtskalenner",
+ "Working hours in one working day. Makes hours and businessDays commensurable.": "Aarbechtsstonnen an engem Aarbechtsdag. Mécht Stonnen an Aarbechtsdeeg vergläichbar.",
+ "Working weekdays": "Aarbechtsdeeg vun der Woch",
+ "fixed: a month/day; easter: an offset in days from Easter Sunday; observedShift: a month/day with a required observed shift.": "fixed: Mount an Dag; easter: en Ofstand an Deeg vum Ouschtersonndeg; observedShift: Mount an Dag mat obligatorescher Verréckelung.",
+ "preBreach fires before the deadline, slaBreached at or after it.": "preBreach léist virun der Frist aus, slaBreached op der Frist oder duerno.",
+ "No such task": "Keng esou Aufgab",
+ "The task does not exist, or it is not yours to see.": "D'Aufgab existéiert net, oder Dir däerft se net gesinn.",
+ "Details": "Detailer",
+ "Due": "Frist",
+ "Assignee": "Zougewisen un",
+ "Requested by": "Ugefrot vun",
+ "Outcome": "Resultat",
+ "Ready to claim": "Prett fir z'iwwerhuelen",
+ "In progress": "Amgaang",
+ "Terminated": "Ofgeschloss",
+ "Normal": "Normal",
+ "Urgent": "Dréngend",
+ "Overdue by 1 day": "1 Dag iwwerfälleg",
+ "Overdue by {days} days": "{days} Deeg iwwerfälleg",
+ "Due today": "Haut fälleg",
+ "Due tomorrow": "Muer fälleg",
+ "Due in {days} days": "Fälleg an {days} Deeg",
+ "Tasks": "Aufgaben",
+ "Task": "Aufgab",
+ "Unassigned, open for claiming": "Net zougewisen, op fir z'iwwerhuelen",
+ "Claim": "Iwwerhuelen",
+ "Complete": "Ofschléissen",
+ "Complete: {outcome}": "Ofschléissen: {outcome}",
+ "Could not load the task": "D'Aufgab konnt net geluede ginn",
+ "The task refused that action": "D'Aufgab huet dës Aktioun refuséiert"
},
"nplurals=2; plural=(n != 1);"
)
diff --git a/l10n/lb.json b/l10n/lb.json
index 6be7a459f9..d41f330bc5 100644
--- a/l10n/lb.json
+++ b/l10n/lb.json
@@ -1,10 +1,20 @@
{
"translations": {
+ "from amount {amount}": "ab Betrag {amount}",
+ "Gated transition: {transition}": "Iwwerwaachten Iwwergang: {transition}",
+ "Each declared chain provisions an ordered task sequence when its transition is attempted. Approvers decide in their task inbox, not here.": "All deklaréiert Kette mécht eng geuerdnet Aufgabesequenz op, wann den Iwwergang probéiert gëtt. Genehmeger entscheeden an hirer Aufgabemailbox, net hei.",
+ "Declare x-openregister-approval-chains on this schema to gate a lifecycle transition on approval.": "Deklaréiert x-openregister-approval-chains op dësem Schema, fir datt en Iwwergang am Liewenszyklus eng Genehmegung brauch.",
+ "Approval sequences": "Genehmegungssequenzen",
"%n entries have no hash yet": "%n Anträg hunn nach kee Hash",
"%n entry has no hash yet": "%n Antrag huet nach kee Hash",
"(Dolphin required)": "(Dolphin vereist)",
+ "No approval chains declared": "Keng Genehmegungsketten deklaréiert",
"(no subject)": "(kee Sujet)",
"(no title)": "(keen Titel)",
+ "Role {role}": "Roll {role}",
+ "The transition is applied automatically once every step approves.": "Den Iwwergang gëtt automatesch ugewannt, soubal all Schrëtt genehmegt ass.",
+ "The requester may not decide their own approval.": "Wien ufreet, dierf net iwwer seng eege Genehmegung entscheeden.",
+ "Tier routing on field: {field}": "Stufeweis Routing iwwert d'Feld: {field}",
"(unnamed)": "(ouni Numm)",
"(untitled card)": "(Kaart ouni Titel)",
"({count} selected)": "({count} geselecteerd)",
@@ -2785,7 +2795,84 @@
"_Successfully restored {count} object_::_Successfully restored {count} objects_": [
"{count} object succesvol hersteld",
"{count} objecten succesvol hersteld"
- ]
+ ],
+ "A message identity the notification subsystem resolves.": "Eng Message-Identitéit, déi den Notifikatiounssystem opléist.",
+ "Computed non-working-date rules. kind fixed: {month, day, name, observedShift?: {whenWeekday, days}}. kind easter: {offset, name}, offset in days from Easter Sunday. kind observedShift: a fixed date with a required shift.": "Berechent Reegele fir aarbechtsfräi Deeg. Zort fixed: {month, day, name, observedShift?: {whenWeekday, days}}. Zort easter: {offset, name}, Ofstand an Deeg vum Ouschtersonndeg. Zort observedShift: e fixen Datum mat obligatorescher Verréckelung.",
+ "Date": "Datum",
+ "Day": "Dag",
+ "Day of a fixed or observedShift rule; ignored by an easter rule.": "Den Dag vun enger fixed- oder observedShift-Reegel; eng easter-Reegel ignoréiert en.",
+ "Days": "Deeg",
+ "Days from Easter Sunday for an easter rule; ignored by the other kinds.": "Deeg vum Ouschtersonndeg fir eng easter-Reegel; déi aner Zorten ignoréiere se.",
+ "Distance from the deadline, in the offset unit.": "Distanz bis zur Frist, an der Eenheet vum Ofstand.",
+ "Enumerated one-off closures as {date, name}. Allowed alongside rules; refused as the whole calendar.": "Eenzel Zoumaachungen opgelëscht als {date, name}. Niewent Reegelen erlaabt; als ganze Kalenner refuséiert.",
+ "Escalate to roles": "Rolle fir d'Eskalatioun",
+ "Escalation ladder": "Eskalatiounsleeder",
+ "Exception dates": "Ausnamedatumer",
+ "Hours per working day": "Stonnen pro Aarbechtsdag",
+ "How many days the observed date shifts, e.g. -1 for the Saturday before.": "Ëm wéi vill Deeg de gefeierten Datum verréckelt gëtt, z. B. -1 fir de Samschdeg virdrun.",
+ "Human-readable title.": "Liesbaren Titel.",
+ "ISO weekdays (1 = Monday, 7 = Sunday) that are working days.": "ISO-Wochendeeg (1 = Méindeg, 7 = Sonndeg), déi Aarbechtsdeeg sinn.",
+ "Kind": "Zort",
+ "Message": "Message",
+ "Month": "Mount",
+ "Month of a fixed or observedShift rule; ignored by an easter rule.": "De Mount vun enger fixed- oder observedShift-Reegel; eng easter-Reegel ignoréiert en.",
+ "Non-working-date rules": "Reegele fir aarbechtsfräi Deeg",
+ "Notify roles": "Rollen déi informéiert ginn",
+ "Observed shift": "Verréckele vum Feierdag",
+ "Offset": "Ofstand",
+ "Offset unit": "Eenheet vum Ofstand",
+ "Open incident": "Incident opmaachen",
+ "Optional map from a role name to a concrete recipient descriptor, e.g. {\"teamleader\": \"group:teamleaders\"}. Roles without a binding travel unresolved as role:.": "Optional Zuerdnung vun engem Rollennumm op e konkreten Empfänger, z. B. {\"teamleader\": \"group:teamleaders\"}. Rollen ouni Zuerdnung reesen onopgeléist als role:.",
+ "Optional on a fixed rule, required on observedShift: {whenWeekday: weekday name or ISO 1..7, days: integer}.": "Optional bei enger fixed-Reegel, obligatoresch bei observedShift: {whenWeekday: Numm vum Dag oder ISO 1..7, days: ganz Zuel}.",
+ "Ordered rungs: {key, trigger (preBreach|slaBreached), offset, offsetUnit (hours|businessDays|calendarDays), notifyRole[], escalateToRole[], priority, message, openIncident}.": "Geuerdent Sprossen: {key, trigger (preBreach|slaBreached), offset, offsetUnit (hours|businessDays|calendarDays), notifyRole[], escalateToRole[], priority, message, openIncident}.",
+ "Priority": "Prioritéit",
+ "Role bindings": "Rollenzuerdnungen",
+ "Roles the matter is escalated to at this rung.": "Rollen, un déi de Fall op dëser Spross eskaléiert gëtt.",
+ "Roles told at this rung; handler is the subject's own performer.": "Rollen, déi op dëser Spross informéiert ginn; handler ass déi Persoun, déi de Fall behandelt.",
+ "Rungs": "Sprossen",
+ "Stable rung identity, e.g. preBreach:14:calendarDays; derived from trigger, offset and unit when absent.": "Fest Identitéit vun der Spross, z. B. preBreach:14:calendarDays; feelt se, gëtt se aus Ausléiser, Ofstand an Eenheet ofgeleet.",
+ "The calendar's stable name, referenced by a timer's calendar_slug.": "De feste Numm vum Kalenner, op deen en Timer iwwer calendar_slug verweist.",
+ "The closed date, Y-m-d.": "Den Datum vun der Zoumaachung, Y-m-d.",
+ "The holiday's name.": "Den Numm vum Feierdag.",
+ "The ladder's stable name, referenced by a timer's ladder_slug.": "De feste Numm vun der Leeder, op déi en Timer iwwer ladder_slug verweist.",
+ "The unit of the offset: the same set the SLA accepts.": "D'Eenheet vum Ofstand: déiselwecht Wäerter, déi den SLA akzeptéiert.",
+ "The urgency the raised transition carries.": "D'Dringlechkeet, déi den ausgeléisten Iwwergank dréit.",
+ "The weekday (name) on which the date shifts, e.g. sunday for Koningsdag.": "De Wochendag (Numm), op deem den Datum verréckelt gëtt, z. B. sunday fir Koningsdag.",
+ "UUID of the organisation this calendar is configured for. Empty for a shared calendar. The resolution order picks an organisation's calendar when the timer names none.": "UUID vun der Organisatioun, fir déi dëse Kalenner agestallt ass. Eidel bei engem gedeelte Kalenner. Nennt den Timer kengen, wielt d'Opléisungsuerdnung de Kalenner vun der Organisatioun.",
+ "UUID of the organisation this ladder is the default for. Empty for the shared default.": "UUID vun der Organisatioun, fir déi dës Leeder de Standard ass. Eidel beim gedeelte Standard.",
+ "When weekday": "Wann e fällt op",
+ "Whether reaching this rung opens an incident.": "Ob d'Erreeche vun dëser Spross en Incident opmécht.",
+ "Why the day is closed.": "Firwat dësen Dag zou ass.",
+ "Working calendar": "Aarbechtskalenner",
+ "Working hours in one working day. Makes hours and businessDays commensurable.": "Aarbechtsstonnen an engem Aarbechtsdag. Mécht Stonnen an Aarbechtsdeeg vergläichbar.",
+ "Working weekdays": "Aarbechtsdeeg vun der Woch",
+ "fixed: a month/day; easter: an offset in days from Easter Sunday; observedShift: a month/day with a required observed shift.": "fixed: Mount an Dag; easter: en Ofstand an Deeg vum Ouschtersonndeg; observedShift: Mount an Dag mat obligatorescher Verréckelung.",
+ "preBreach fires before the deadline, slaBreached at or after it.": "preBreach léist virun der Frist aus, slaBreached op der Frist oder duerno.",
+ "No such task": "Keng esou Aufgab",
+ "The task does not exist, or it is not yours to see.": "D'Aufgab existéiert net, oder Dir däerft se net gesinn.",
+ "Details": "Detailer",
+ "Due": "Frist",
+ "Assignee": "Zougewisen un",
+ "Requested by": "Ugefrot vun",
+ "Outcome": "Resultat",
+ "Ready to claim": "Prett fir z'iwwerhuelen",
+ "In progress": "Amgaang",
+ "Terminated": "Ofgeschloss",
+ "Normal": "Normal",
+ "Urgent": "Dréngend",
+ "Overdue by 1 day": "1 Dag iwwerfälleg",
+ "Overdue by {days} days": "{days} Deeg iwwerfälleg",
+ "Due today": "Haut fälleg",
+ "Due tomorrow": "Muer fälleg",
+ "Due in {days} days": "Fälleg an {days} Deeg",
+ "Tasks": "Aufgaben",
+ "Task": "Aufgab",
+ "Unassigned, open for claiming": "Net zougewisen, op fir z'iwwerhuelen",
+ "Claim": "Iwwerhuelen",
+ "Complete": "Ofschléissen",
+ "Complete: {outcome}": "Ofschléissen: {outcome}",
+ "Could not load the task": "D'Aufgab konnt net geluede ginn",
+ "The task refused that action": "D'Aufgab huet dës Aktioun refuséiert"
},
"pluralForm": "nplurals=2; plural=(n != 1);",
"plurals": {
diff --git a/l10n/lt.js b/l10n/lt.js
index c36d576439..3e1ddcd54e 100644
--- a/l10n/lt.js
+++ b/l10n/lt.js
@@ -3,11 +3,21 @@ OC.L10N.register(
{
"3": "3",
"30": "30",
+ "from amount {amount}": "nuo sumos {amount}",
+ "Gated transition: {transition}": "Prižiūrimas perėjimas: {transition}",
+ "Each declared chain provisions an ordered task sequence when its transition is attempted. Approvers decide in their task inbox, not here.": "Kiekviena deklaruota grandinė atveria surikiuotą užduočių seką, kai bandomas perėjimas. Tvirtintojai sprendžia savo užduočių aplanke, ne čia.",
+ "Declare x-openregister-approval-chains on this schema to gate a lifecycle transition on approval.": "Deklaruokite x-openregister-approval-chains šioje schemoje, kad gyvavimo ciklo perėjimui reikėtų patvirtinimo.",
+ "Approval sequences": "Tvirtinimo sekos",
"%n entries have no hash yet": "%n įrašų dar neturi maišos",
"%n entry has no hash yet": "%n įrašas dar neturi maišos",
"(Dolphin required)": "(reikalingas Dolphin)",
+ "No approval chains declared": "Nedeklaruota jokių tvirtinimo grandinių",
"(no subject)": "(be temos)",
"(no title)": "(be pavadinimo)",
+ "Role {role}": "Vaidmuo {role}",
+ "The transition is applied automatically once every step approves.": "Perėjimas pritaikomas automatiškai, kai patvirtinamas kiekvienas žingsnis.",
+ "The requester may not decide their own approval.": "Prašytojas negali spręsti dėl savo paties patvirtinimo.",
+ "Tier routing on field: {field}": "Pakopinis nukreipimas pagal lauką: {field}",
"(unnamed)": "(be vardo)",
"(untitled card)": "(kortelė be pavadinimo)",
"({count} selected)": "(pasirinkta: {count})",
@@ -2738,7 +2748,84 @@ OC.L10N.register(
"_Object successfully deleted_::_Objects successfully deleted_": ["Objektas sėkmingai ištrintas","Objektai sėkmingai ištrinti","Objektai sėkmingai ištrinti"],
"_Purge {count} object from database_::_Purge {count} objects from database_": ["Išvalyti {count} objektą iš duomenų bazės","Išvalyti {count} objektus iš duomenų bazės","Išvalyti {count} objektų iš duomenų bazės"],
"_Restore {count} object_::_Restore {count} objects_": ["Atkurti {count} objektą","Atkurti {count} objektus","Atkurti {count} objektų"],
- "_Successfully restored {count} object_::_Successfully restored {count} objects_": ["Sėkmingai atkurtas {count} objektas","Sėkmingai atkurti {count} objektai","Sėkmingai atkurta {count} objektų"]
+ "_Successfully restored {count} object_::_Successfully restored {count} objects_": ["Sėkmingai atkurtas {count} objektas","Sėkmingai atkurti {count} objektai","Sėkmingai atkurta {count} objektų"],
+ "A message identity the notification subsystem resolves.": "Žinutės tapatybė, kurią išsprendžia pranešimų sistema.",
+ "Computed non-working-date rules. kind fixed: {month, day, name, observedShift?: {whenWeekday, days}}. kind easter: {offset, name}, offset in days from Easter Sunday. kind observedShift: a fixed date with a required shift.": "Apskaičiuotos nedarbo dienų taisyklės. Rūšis fixed: {month, day, name, observedShift?: {whenWeekday, days}}. Rūšis easter: {offset, name}, poslinkis dienomis nuo Velykų sekmadienio. Rūšis observedShift: fiksuota data su privalomu perkėlimu.",
+ "Date": "Data",
+ "Day": "Diena",
+ "Day of a fixed or observedShift rule; ignored by an easter rule.": "Taisyklės fixed arba observedShift diena; taisyklė easter ją ignoruoja.",
+ "Days": "Dienos",
+ "Days from Easter Sunday for an easter rule; ignored by the other kinds.": "Dienos nuo Velykų sekmadienio taisyklei easter; kitos rūšys jas ignoruoja.",
+ "Distance from the deadline, in the offset unit.": "Atstumas iki termino poslinkio vienetu.",
+ "Enumerated one-off closures as {date, name}. Allowed alongside rules; refused as the whole calendar.": "Pavieniai uždarymai, išvardyti kaip {date, name}. Leidžiami šalia taisyklių; atmesti kaip visas kalendorius.",
+ "Escalate to roles": "Eskalavimo vaidmenys",
+ "Escalation ladder": "Eskalavimo kopėčios",
+ "Exception dates": "Išimčių datos",
+ "Hours per working day": "Valandų per darbo dieną",
+ "How many days the observed date shifts, e.g. -1 for the Saturday before.": "Keliomis dienomis švenčiama data perkeliama, pvz. -1 ankstesniam šeštadieniui.",
+ "Human-readable title.": "Įskaitomas pavadinimas.",
+ "ISO weekdays (1 = Monday, 7 = Sunday) that are working days.": "ISO savaitės dienos (1 = pirmadienis, 7 = sekmadienis), kurios yra darbo dienos.",
+ "Kind": "Rūšis",
+ "Message": "Žinutė",
+ "Month": "Mėnuo",
+ "Month of a fixed or observedShift rule; ignored by an easter rule.": "Taisyklės fixed arba observedShift mėnuo; taisyklė easter jį ignoruoja.",
+ "Non-working-date rules": "Nedarbo dienų taisyklės",
+ "Notify roles": "Informuojami vaidmenys",
+ "Observed shift": "Šventės perkėlimas",
+ "Offset": "Poslinkis",
+ "Offset unit": "Poslinkio vienetas",
+ "Open incident": "Atidaryti incidentą",
+ "Optional map from a role name to a concrete recipient descriptor, e.g. {\"teamleader\": \"group:teamleaders\"}. Roles without a binding travel unresolved as role:.": "Neprivalomas žemėlapis iš vaidmens pavadinimo į konkretų gavėją, pvz. {\"teamleader\": \"group:teamleaders\"}. Nesusieti vaidmenys keliauja neišspręsti kaip role:.",
+ "Optional on a fixed rule, required on observedShift: {whenWeekday: weekday name or ISO 1..7, days: integer}.": "Neprivaloma taisyklei fixed, privaloma observedShift: {whenWeekday: dienos pavadinimas arba ISO 1..7, days: sveikasis skaičius}.",
+ "Ordered rungs: {key, trigger (preBreach|slaBreached), offset, offsetUnit (hours|businessDays|calendarDays), notifyRole[], escalateToRole[], priority, message, openIncident}.": "Surikiuotos pakopos: {key, trigger (preBreach|slaBreached), offset, offsetUnit (hours|businessDays|calendarDays), notifyRole[], escalateToRole[], priority, message, openIncident}.",
+ "Priority": "Prioritetas",
+ "Role bindings": "Vaidmenų susiejimai",
+ "Roles the matter is escalated to at this rung.": "Vaidmenys, kuriems byla šioje pakopoje eskaluojama.",
+ "Roles told at this rung; handler is the subject's own performer.": "Šioje pakopoje informuojami vaidmenys; handler yra bylą tvarkantis asmuo.",
+ "Rungs": "Pakopos",
+ "Stable rung identity, e.g. preBreach:14:calendarDays; derived from trigger, offset and unit when absent.": "Pastovi pakopos tapatybė, pvz. preBreach:14:calendarDays; jos nesant, išvedama iš trigerio, poslinkio ir vieneto.",
+ "The calendar's stable name, referenced by a timer's calendar_slug.": "Pastovus kalendoriaus pavadinimas, į kurį laikmatis rodo per calendar_slug.",
+ "The closed date, Y-m-d.": "Uždarymo data, Y-m-d.",
+ "The holiday's name.": "Šventės pavadinimas.",
+ "The ladder's stable name, referenced by a timer's ladder_slug.": "Pastovus kopėčių pavadinimas, į kurį laikmatis rodo per ladder_slug.",
+ "The unit of the offset: the same set the SLA accepts.": "Poslinkio vienetas: ta pati aibė, kurią priima SLA.",
+ "The urgency the raised transition carries.": "Skuba, kurią neša sukeltas perėjimas.",
+ "The weekday (name) on which the date shifts, e.g. sunday for Koningsdag.": "Savaitės diena (pavadinimas), kurią data perkeliama, pvz. sunday Koningsdag atveju.",
+ "UUID of the organisation this calendar is configured for. Empty for a shared calendar. The resolution order picks an organisation's calendar when the timer names none.": "Organizacijos, kuriai šis kalendorius nustatytas, UUID. Tuščia bendram kalendoriui. Jei laikmatis nenurodo jokio, sprendimo tvarka parenka organizacijos kalendorių.",
+ "UUID of the organisation this ladder is the default for. Empty for the shared default.": "Organizacijos, kuriai šios kopėčios yra numatytosios, UUID. Tuščia bendram numatytajam.",
+ "When weekday": "Jei išpuola",
+ "Whether reaching this rung opens an incident.": "Ar šios pakopos pasiekimas atidaro incidentą.",
+ "Why the day is closed.": "Kodėl ta diena uždaryta.",
+ "Working calendar": "Darbo kalendorius",
+ "Working hours in one working day. Makes hours and businessDays commensurable.": "Darbo valandos vienoje darbo dienoje. Padaro valandas ir darbo dienas palyginamas.",
+ "Working weekdays": "Savaitės darbo dienos",
+ "fixed: a month/day; easter: an offset in days from Easter Sunday; observedShift: a month/day with a required observed shift.": "fixed: mėnuo ir diena; easter: poslinkis dienomis nuo Velykų sekmadienio; observedShift: mėnuo ir diena su privalomu perkėlimu.",
+ "preBreach fires before the deadline, slaBreached at or after it.": "preBreach suveikia prieš terminą, slaBreached terminą pasiekus arba po jo.",
+ "No such task": "Tokios užduoties nėra",
+ "The task does not exist, or it is not yours to see.": "Užduotis neegzistuoja arba neturite teisės jos matyti.",
+ "Details": "Išsami informacija",
+ "Due": "Terminas",
+ "Assignee": "Vykdytojas",
+ "Requested by": "Užklausė",
+ "Outcome": "Rezultatas",
+ "Ready to claim": "Paruošta perimti",
+ "In progress": "Vykdoma",
+ "Terminated": "Nutraukta",
+ "Normal": "Įprastas",
+ "Urgent": "Skubu",
+ "Overdue by 1 day": "Vėluoja 1 dieną",
+ "Overdue by {days} days": "Vėluoja {days} dienas",
+ "Due today": "Terminas šiandien",
+ "Due tomorrow": "Terminas rytoj",
+ "Due in {days} days": "Terminas po {days} dienų",
+ "Tasks": "Užduotys",
+ "Task": "Užduotis",
+ "Unassigned, open for claiming": "Nepriskirta, galima perimti",
+ "Claim": "Perimti",
+ "Complete": "Užbaigti",
+ "Complete: {outcome}": "Užbaigti: {outcome}",
+ "Could not load the task": "Nepavyko įkelti užduoties",
+ "The task refused that action": "Užduotis atmetė šį veiksmą"
},
"nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && (n%100<10 || n%100>=20) ? 1 : 2);"
)
diff --git a/l10n/lt.json b/l10n/lt.json
index 778ebb2550..b9e0893b07 100644
--- a/l10n/lt.json
+++ b/l10n/lt.json
@@ -1,10 +1,20 @@
{
"translations": {
+ "from amount {amount}": "nuo sumos {amount}",
+ "Gated transition: {transition}": "Prižiūrimas perėjimas: {transition}",
+ "Each declared chain provisions an ordered task sequence when its transition is attempted. Approvers decide in their task inbox, not here.": "Kiekviena deklaruota grandinė atveria surikiuotą užduočių seką, kai bandomas perėjimas. Tvirtintojai sprendžia savo užduočių aplanke, ne čia.",
+ "Declare x-openregister-approval-chains on this schema to gate a lifecycle transition on approval.": "Deklaruokite x-openregister-approval-chains šioje schemoje, kad gyvavimo ciklo perėjimui reikėtų patvirtinimo.",
+ "Approval sequences": "Tvirtinimo sekos",
"%n entries have no hash yet": "%n įrašų dar neturi maišos",
"%n entry has no hash yet": "%n įrašas dar neturi maišos",
"(Dolphin required)": "(reikalingas Dolphin)",
+ "No approval chains declared": "Nedeklaruota jokių tvirtinimo grandinių",
"(no subject)": "(be temos)",
"(no title)": "(be pavadinimo)",
+ "Role {role}": "Vaidmuo {role}",
+ "The transition is applied automatically once every step approves.": "Perėjimas pritaikomas automatiškai, kai patvirtinamas kiekvienas žingsnis.",
+ "The requester may not decide their own approval.": "Prašytojas negali spręsti dėl savo paties patvirtinimo.",
+ "Tier routing on field: {field}": "Pakopinis nukreipimas pagal lauką: {field}",
"(unnamed)": "(be vardo)",
"(untitled card)": "(kortelė be pavadinimo)",
"({count} selected)": "(pasirinkta: {count})",
@@ -2801,7 +2811,84 @@
"Sėkmingai atkurtas {count} objektas",
"Sėkmingai atkurti {count} objektai",
"Sėkmingai atkurta {count} objektų"
- ]
+ ],
+ "A message identity the notification subsystem resolves.": "Žinutės tapatybė, kurią išsprendžia pranešimų sistema.",
+ "Computed non-working-date rules. kind fixed: {month, day, name, observedShift?: {whenWeekday, days}}. kind easter: {offset, name}, offset in days from Easter Sunday. kind observedShift: a fixed date with a required shift.": "Apskaičiuotos nedarbo dienų taisyklės. Rūšis fixed: {month, day, name, observedShift?: {whenWeekday, days}}. Rūšis easter: {offset, name}, poslinkis dienomis nuo Velykų sekmadienio. Rūšis observedShift: fiksuota data su privalomu perkėlimu.",
+ "Date": "Data",
+ "Day": "Diena",
+ "Day of a fixed or observedShift rule; ignored by an easter rule.": "Taisyklės fixed arba observedShift diena; taisyklė easter ją ignoruoja.",
+ "Days": "Dienos",
+ "Days from Easter Sunday for an easter rule; ignored by the other kinds.": "Dienos nuo Velykų sekmadienio taisyklei easter; kitos rūšys jas ignoruoja.",
+ "Distance from the deadline, in the offset unit.": "Atstumas iki termino poslinkio vienetu.",
+ "Enumerated one-off closures as {date, name}. Allowed alongside rules; refused as the whole calendar.": "Pavieniai uždarymai, išvardyti kaip {date, name}. Leidžiami šalia taisyklių; atmesti kaip visas kalendorius.",
+ "Escalate to roles": "Eskalavimo vaidmenys",
+ "Escalation ladder": "Eskalavimo kopėčios",
+ "Exception dates": "Išimčių datos",
+ "Hours per working day": "Valandų per darbo dieną",
+ "How many days the observed date shifts, e.g. -1 for the Saturday before.": "Keliomis dienomis švenčiama data perkeliama, pvz. -1 ankstesniam šeštadieniui.",
+ "Human-readable title.": "Įskaitomas pavadinimas.",
+ "ISO weekdays (1 = Monday, 7 = Sunday) that are working days.": "ISO savaitės dienos (1 = pirmadienis, 7 = sekmadienis), kurios yra darbo dienos.",
+ "Kind": "Rūšis",
+ "Message": "Žinutė",
+ "Month": "Mėnuo",
+ "Month of a fixed or observedShift rule; ignored by an easter rule.": "Taisyklės fixed arba observedShift mėnuo; taisyklė easter jį ignoruoja.",
+ "Non-working-date rules": "Nedarbo dienų taisyklės",
+ "Notify roles": "Informuojami vaidmenys",
+ "Observed shift": "Šventės perkėlimas",
+ "Offset": "Poslinkis",
+ "Offset unit": "Poslinkio vienetas",
+ "Open incident": "Atidaryti incidentą",
+ "Optional map from a role name to a concrete recipient descriptor, e.g. {\"teamleader\": \"group:teamleaders\"}. Roles without a binding travel unresolved as role:.": "Neprivalomas žemėlapis iš vaidmens pavadinimo į konkretų gavėją, pvz. {\"teamleader\": \"group:teamleaders\"}. Nesusieti vaidmenys keliauja neišspręsti kaip role:.",
+ "Optional on a fixed rule, required on observedShift: {whenWeekday: weekday name or ISO 1..7, days: integer}.": "Neprivaloma taisyklei fixed, privaloma observedShift: {whenWeekday: dienos pavadinimas arba ISO 1..7, days: sveikasis skaičius}.",
+ "Ordered rungs: {key, trigger (preBreach|slaBreached), offset, offsetUnit (hours|businessDays|calendarDays), notifyRole[], escalateToRole[], priority, message, openIncident}.": "Surikiuotos pakopos: {key, trigger (preBreach|slaBreached), offset, offsetUnit (hours|businessDays|calendarDays), notifyRole[], escalateToRole[], priority, message, openIncident}.",
+ "Priority": "Prioritetas",
+ "Role bindings": "Vaidmenų susiejimai",
+ "Roles the matter is escalated to at this rung.": "Vaidmenys, kuriems byla šioje pakopoje eskaluojama.",
+ "Roles told at this rung; handler is the subject's own performer.": "Šioje pakopoje informuojami vaidmenys; handler yra bylą tvarkantis asmuo.",
+ "Rungs": "Pakopos",
+ "Stable rung identity, e.g. preBreach:14:calendarDays; derived from trigger, offset and unit when absent.": "Pastovi pakopos tapatybė, pvz. preBreach:14:calendarDays; jos nesant, išvedama iš trigerio, poslinkio ir vieneto.",
+ "The calendar's stable name, referenced by a timer's calendar_slug.": "Pastovus kalendoriaus pavadinimas, į kurį laikmatis rodo per calendar_slug.",
+ "The closed date, Y-m-d.": "Uždarymo data, Y-m-d.",
+ "The holiday's name.": "Šventės pavadinimas.",
+ "The ladder's stable name, referenced by a timer's ladder_slug.": "Pastovus kopėčių pavadinimas, į kurį laikmatis rodo per ladder_slug.",
+ "The unit of the offset: the same set the SLA accepts.": "Poslinkio vienetas: ta pati aibė, kurią priima SLA.",
+ "The urgency the raised transition carries.": "Skuba, kurią neša sukeltas perėjimas.",
+ "The weekday (name) on which the date shifts, e.g. sunday for Koningsdag.": "Savaitės diena (pavadinimas), kurią data perkeliama, pvz. sunday Koningsdag atveju.",
+ "UUID of the organisation this calendar is configured for. Empty for a shared calendar. The resolution order picks an organisation's calendar when the timer names none.": "Organizacijos, kuriai šis kalendorius nustatytas, UUID. Tuščia bendram kalendoriui. Jei laikmatis nenurodo jokio, sprendimo tvarka parenka organizacijos kalendorių.",
+ "UUID of the organisation this ladder is the default for. Empty for the shared default.": "Organizacijos, kuriai šios kopėčios yra numatytosios, UUID. Tuščia bendram numatytajam.",
+ "When weekday": "Jei išpuola",
+ "Whether reaching this rung opens an incident.": "Ar šios pakopos pasiekimas atidaro incidentą.",
+ "Why the day is closed.": "Kodėl ta diena uždaryta.",
+ "Working calendar": "Darbo kalendorius",
+ "Working hours in one working day. Makes hours and businessDays commensurable.": "Darbo valandos vienoje darbo dienoje. Padaro valandas ir darbo dienas palyginamas.",
+ "Working weekdays": "Savaitės darbo dienos",
+ "fixed: a month/day; easter: an offset in days from Easter Sunday; observedShift: a month/day with a required observed shift.": "fixed: mėnuo ir diena; easter: poslinkis dienomis nuo Velykų sekmadienio; observedShift: mėnuo ir diena su privalomu perkėlimu.",
+ "preBreach fires before the deadline, slaBreached at or after it.": "preBreach suveikia prieš terminą, slaBreached terminą pasiekus arba po jo.",
+ "No such task": "Tokios užduoties nėra",
+ "The task does not exist, or it is not yours to see.": "Užduotis neegzistuoja arba neturite teisės jos matyti.",
+ "Details": "Išsami informacija",
+ "Due": "Terminas",
+ "Assignee": "Vykdytojas",
+ "Requested by": "Užklausė",
+ "Outcome": "Rezultatas",
+ "Ready to claim": "Paruošta perimti",
+ "In progress": "Vykdoma",
+ "Terminated": "Nutraukta",
+ "Normal": "Įprastas",
+ "Urgent": "Skubu",
+ "Overdue by 1 day": "Vėluoja 1 dieną",
+ "Overdue by {days} days": "Vėluoja {days} dienas",
+ "Due today": "Terminas šiandien",
+ "Due tomorrow": "Terminas rytoj",
+ "Due in {days} days": "Terminas po {days} dienų",
+ "Tasks": "Užduotys",
+ "Task": "Užduotis",
+ "Unassigned, open for claiming": "Nepriskirta, galima perimti",
+ "Claim": "Perimti",
+ "Complete": "Užbaigti",
+ "Complete: {outcome}": "Užbaigti: {outcome}",
+ "Could not load the task": "Nepavyko įkelti užduoties",
+ "The task refused that action": "Užduotis atmetė šį veiksmą"
},
"pluralForm": "nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && (n%100<10 || n%100>=20) ? 1 : 2);",
"plurals": {
diff --git a/l10n/lv.js b/l10n/lv.js
index c4a0b4d4d4..c4c76b56f2 100644
--- a/l10n/lv.js
+++ b/l10n/lv.js
@@ -3,11 +3,21 @@ OC.L10N.register(
{
"3": "3",
"30": "30",
+ "from amount {amount}": "no summas {amount}",
+ "Gated transition: {transition}": "Uzraudzīta pāreja: {transition}",
+ "Each declared chain provisions an ordered task sequence when its transition is attempted. Approvers decide in their task inbox, not here.": "Katra deklarētā ķēde atver sakārtotu uzdevumu secību, kad pāreja tiek mēģināta. Apstiprinātāji lemj savā uzdevumu iesūtnē, nevis šeit.",
+ "Declare x-openregister-approval-chains on this schema to gate a lifecycle transition on approval.": "Deklarējiet x-openregister-approval-chains šajā shēmā, lai dzīves cikla pāreja prasītu apstiprinājumu.",
+ "Approval sequences": "Apstiprināšanas secības",
"%n entries have no hash yet": "%n ierakstiem vēl nav jaucējkoda",
"%n entry has no hash yet": "%n ierakstam vēl nav jaucējkoda",
"(Dolphin required)": "(nepieciešams Dolphin)",
+ "No approval chains declared": "Nav deklarētu apstiprināšanas ķēžu",
"(no subject)": "(nav temata)",
"(no title)": "(nav nosaukuma)",
+ "Role {role}": "Loma {role}",
+ "The transition is applied automatically once every step approves.": "Pāreja tiek piemērota automātiski, tiklīdz katrs solis ir apstiprināts.",
+ "The requester may not decide their own approval.": "Pieprasītājs nedrīkst lemt par savu apstiprinājumu.",
+ "Tier routing on field: {field}": "Pakāpju maršrutēšana pēc lauka: {field}",
"(unnamed)": "(bez nosaukuma)",
"(untitled card)": "(kartīte bez nosaukuma)",
"({count} selected)": "({count} atlasīti)",
@@ -2738,7 +2748,84 @@ OC.L10N.register(
"_Object successfully deleted_::_Objects successfully deleted_": ["Objekts veiksmīgi dzēsts","Objekti veiksmīgi dzēsti","Objekti veiksmīgi dzēsti"],
"_Purge {count} object from database_::_Purge {count} objects from database_": ["Iztīrīt {count} objektu no datubāzes","Iztīrīt {count} objektus no datubāzes","Iztīrīt {count} objektu no datubāzes"],
"_Restore {count} object_::_Restore {count} objects_": ["Atjaunot {count} objektu","Atjaunot {count} objektus","Atjaunot {count} objektu"],
- "_Successfully restored {count} object_::_Successfully restored {count} objects_": ["Veiksmīgi atjaunots {count} objekts","Veiksmīgi atjaunoti {count} objekti","Veiksmīgi atjaunoti {count} objekti"]
+ "_Successfully restored {count} object_::_Successfully restored {count} objects_": ["Veiksmīgi atjaunots {count} objekts","Veiksmīgi atjaunoti {count} objekti","Veiksmīgi atjaunoti {count} objekti"],
+ "A message identity the notification subsystem resolves.": "Ziņojuma identitāte, ko atrisina paziņojumu sistēma.",
+ "Computed non-working-date rules. kind fixed: {month, day, name, observedShift?: {whenWeekday, days}}. kind easter: {offset, name}, offset in days from Easter Sunday. kind observedShift: a fixed date with a required shift.": "Aprēķinātie brīvdienu noteikumi. Veids fixed: {month, day, name, observedShift?: {whenWeekday, days}}. Veids easter: {offset, name}, nobīde dienās no Lieldienu svētdienas. Veids observedShift: fiksēts datums ar obligātu pārcelšanu.",
+ "Date": "Datums",
+ "Day": "Diena",
+ "Day of a fixed or observedShift rule; ignored by an easter rule.": "Noteikuma fixed vai observedShift diena; noteikums easter to ignorē.",
+ "Days": "Dienas",
+ "Days from Easter Sunday for an easter rule; ignored by the other kinds.": "Dienas no Lieldienu svētdienas noteikumam easter; pārējie veidi tās ignorē.",
+ "Distance from the deadline, in the offset unit.": "Attālums līdz termiņam nobīdes vienībā.",
+ "Enumerated one-off closures as {date, name}. Allowed alongside rules; refused as the whole calendar.": "Atsevišķas slēgšanas, uzskaitītas kā {date, name}. Atļautas līdzās noteikumiem; noraidītas kā viss kalendārs.",
+ "Escalate to roles": "Eskalācijas lomas",
+ "Escalation ladder": "Eskalācijas kāpnes",
+ "Exception dates": "Izņēmuma datumi",
+ "Hours per working day": "Stundas darba dienā",
+ "How many days the observed date shifts, e.g. -1 for the Saturday before.": "Par cik dienām svinamais datums tiek pārcelts, piem. -1 iepriekšējai sestdienai.",
+ "Human-readable title.": "Salasāms virsraksts.",
+ "ISO weekdays (1 = Monday, 7 = Sunday) that are working days.": "ISO nedēļas dienas (1 = pirmdiena, 7 = svētdiena), kas ir darba dienas.",
+ "Kind": "Veids",
+ "Message": "Ziņojums",
+ "Month": "Mēnesis",
+ "Month of a fixed or observedShift rule; ignored by an easter rule.": "Noteikuma fixed vai observedShift mēnesis; noteikums easter to ignorē.",
+ "Non-working-date rules": "Brīvdienu noteikumi",
+ "Notify roles": "Informējamās lomas",
+ "Observed shift": "Svētku pārcelšana",
+ "Offset": "Nobīde",
+ "Offset unit": "Nobīdes vienība",
+ "Open incident": "Atvērt incidentu",
+ "Optional map from a role name to a concrete recipient descriptor, e.g. {\"teamleader\": \"group:teamleaders\"}. Roles without a binding travel unresolved as role:.": "Neobligāta karte no lomas nosaukuma uz konkrētu saņēmēju, piem. {\"teamleader\": \"group:teamleaders\"}. Lomas bez sasaistes ceļo neatrisinātas kā role:.",
+ "Optional on a fixed rule, required on observedShift: {whenWeekday: weekday name or ISO 1..7, days: integer}.": "Neobligāts noteikumam fixed, obligāts observedShift: {whenWeekday: dienas nosaukums vai ISO 1..7, days: vesels skaitlis}.",
+ "Ordered rungs: {key, trigger (preBreach|slaBreached), offset, offsetUnit (hours|businessDays|calendarDays), notifyRole[], escalateToRole[], priority, message, openIncident}.": "Sakārtoti pakāpieni: {key, trigger (preBreach|slaBreached), offset, offsetUnit (hours|businessDays|calendarDays), notifyRole[], escalateToRole[], priority, message, openIncident}.",
+ "Priority": "Prioritāte",
+ "Role bindings": "Lomu sasaistes",
+ "Roles the matter is escalated to at this rung.": "Lomas, kurām lieta šajā pakāpienā tiek eskalēta.",
+ "Roles told at this rung; handler is the subject's own performer.": "Šajā pakāpienā informētās lomas; handler ir lietas kārtotājs.",
+ "Rungs": "Pakāpieni",
+ "Stable rung identity, e.g. preBreach:14:calendarDays; derived from trigger, offset and unit when absent.": "Pakāpiena pastāvīgā identitāte, piem. preBreach:14:calendarDays; ja tās nav, to atvasina no trigera, nobīdes un vienības.",
+ "The calendar's stable name, referenced by a timer's calendar_slug.": "Kalendāra pastāvīgais nosaukums, uz kuru taimeris atsaucas ar calendar_slug.",
+ "The closed date, Y-m-d.": "Slēgšanas datums, Y-m-d.",
+ "The holiday's name.": "Svētku nosaukums.",
+ "The ladder's stable name, referenced by a timer's ladder_slug.": "Kāpņu pastāvīgais nosaukums, uz kuru taimeris atsaucas ar ladder_slug.",
+ "The unit of the offset: the same set the SLA accepts.": "Nobīdes vienība: tā pati kopa, ko pieņem SLA.",
+ "The urgency the raised transition carries.": "Steidzamība, ko nes izraisītā pāreja.",
+ "The weekday (name) on which the date shifts, e.g. sunday for Koningsdag.": "Nedēļas diena (nosaukums), kurā datums tiek pārcelts, piem. sunday Koningsdag gadījumā.",
+ "UUID of the organisation this calendar is configured for. Empty for a shared calendar. The resolution order picks an organisation's calendar when the timer names none.": "Organizācijas UUID, kurai šis kalendārs ir iestatīts. Tukšs koplietotam kalendāram. Ja taimeris nevienu nenosauc, atrisināšanas secība izvēlas organizācijas kalendāru.",
+ "UUID of the organisation this ladder is the default for. Empty for the shared default.": "Organizācijas UUID, kurai šīs kāpnes ir noklusējums. Tukšs koplietotajam noklusējumam.",
+ "When weekday": "Ja iekrīt",
+ "Whether reaching this rung opens an incident.": "Vai šī pakāpiena sasniegšana atver incidentu.",
+ "Why the day is closed.": "Kāpēc šī diena ir slēgta.",
+ "Working calendar": "Darba kalendārs",
+ "Working hours in one working day. Makes hours and businessDays commensurable.": "Darba stundas vienā darba dienā. Padara stundas un darba dienas salīdzināmas.",
+ "Working weekdays": "Nedēļas darba dienas",
+ "fixed: a month/day; easter: an offset in days from Easter Sunday; observedShift: a month/day with a required observed shift.": "fixed: mēnesis un diena; easter: nobīde dienās no Lieldienu svētdienas; observedShift: mēnesis un diena ar obligātu pārcelšanu.",
+ "preBreach fires before the deadline, slaBreached at or after it.": "preBreach nostrādā pirms termiņa, slaBreached termiņā vai pēc tā.",
+ "No such task": "Nav šāda uzdevuma",
+ "The task does not exist, or it is not yours to see.": "Uzdevums nepastāv, vai jums nav tiesību to redzēt.",
+ "Details": "Detaļas",
+ "Due": "Termiņš",
+ "Assignee": "Atbildīgais",
+ "Requested by": "Pieprasīja",
+ "Outcome": "Iznākums",
+ "Ready to claim": "Gatavs pārņemšanai",
+ "In progress": "Procesā",
+ "Terminated": "Pārtraukts",
+ "Normal": "Parasts",
+ "Urgent": "Steidzams",
+ "Overdue by 1 day": "Nokavēts par 1 dienu",
+ "Overdue by {days} days": "Nokavēts par {days} dienām",
+ "Due today": "Termiņš šodien",
+ "Due tomorrow": "Termiņš rīt",
+ "Due in {days} days": "Termiņš pēc {days} dienām",
+ "Tasks": "Uzdevumi",
+ "Task": "Uzdevums",
+ "Unassigned, open for claiming": "Nepiešķirts, atvērts pārņemšanai",
+ "Claim": "Pārņemt",
+ "Complete": "Pabeigt",
+ "Complete: {outcome}": "Pabeigt: {outcome}",
+ "Could not load the task": "Neizdevās ielādēt uzdevumu",
+ "The task refused that action": "Uzdevums noraidīja šo darbību"
},
"nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n != 0 ? 1 : 2);"
)
diff --git a/l10n/lv.json b/l10n/lv.json
index e3d69d4336..424eae5ddb 100644
--- a/l10n/lv.json
+++ b/l10n/lv.json
@@ -1,10 +1,20 @@
{
"translations": {
+ "from amount {amount}": "no summas {amount}",
+ "Gated transition: {transition}": "Uzraudzīta pāreja: {transition}",
+ "Each declared chain provisions an ordered task sequence when its transition is attempted. Approvers decide in their task inbox, not here.": "Katra deklarētā ķēde atver sakārtotu uzdevumu secību, kad pāreja tiek mēģināta. Apstiprinātāji lemj savā uzdevumu iesūtnē, nevis šeit.",
+ "Declare x-openregister-approval-chains on this schema to gate a lifecycle transition on approval.": "Deklarējiet x-openregister-approval-chains šajā shēmā, lai dzīves cikla pāreja prasītu apstiprinājumu.",
+ "Approval sequences": "Apstiprināšanas secības",
"%n entries have no hash yet": "%n ierakstiem vēl nav jaucējkoda",
"%n entry has no hash yet": "%n ierakstam vēl nav jaucējkoda",
"(Dolphin required)": "(nepieciešams Dolphin)",
+ "No approval chains declared": "Nav deklarētu apstiprināšanas ķēžu",
"(no subject)": "(nav temata)",
"(no title)": "(nav nosaukuma)",
+ "Role {role}": "Loma {role}",
+ "The transition is applied automatically once every step approves.": "Pāreja tiek piemērota automātiski, tiklīdz katrs solis ir apstiprināts.",
+ "The requester may not decide their own approval.": "Pieprasītājs nedrīkst lemt par savu apstiprinājumu.",
+ "Tier routing on field: {field}": "Pakāpju maršrutēšana pēc lauka: {field}",
"(unnamed)": "(bez nosaukuma)",
"(untitled card)": "(kartīte bez nosaukuma)",
"({count} selected)": "({count} atlasīti)",
@@ -2801,7 +2811,84 @@
"Veiksmīgi atjaunots {count} objekts",
"Veiksmīgi atjaunoti {count} objekti",
"Veiksmīgi atjaunoti {count} objekti"
- ]
+ ],
+ "A message identity the notification subsystem resolves.": "Ziņojuma identitāte, ko atrisina paziņojumu sistēma.",
+ "Computed non-working-date rules. kind fixed: {month, day, name, observedShift?: {whenWeekday, days}}. kind easter: {offset, name}, offset in days from Easter Sunday. kind observedShift: a fixed date with a required shift.": "Aprēķinātie brīvdienu noteikumi. Veids fixed: {month, day, name, observedShift?: {whenWeekday, days}}. Veids easter: {offset, name}, nobīde dienās no Lieldienu svētdienas. Veids observedShift: fiksēts datums ar obligātu pārcelšanu.",
+ "Date": "Datums",
+ "Day": "Diena",
+ "Day of a fixed or observedShift rule; ignored by an easter rule.": "Noteikuma fixed vai observedShift diena; noteikums easter to ignorē.",
+ "Days": "Dienas",
+ "Days from Easter Sunday for an easter rule; ignored by the other kinds.": "Dienas no Lieldienu svētdienas noteikumam easter; pārējie veidi tās ignorē.",
+ "Distance from the deadline, in the offset unit.": "Attālums līdz termiņam nobīdes vienībā.",
+ "Enumerated one-off closures as {date, name}. Allowed alongside rules; refused as the whole calendar.": "Atsevišķas slēgšanas, uzskaitītas kā {date, name}. Atļautas līdzās noteikumiem; noraidītas kā viss kalendārs.",
+ "Escalate to roles": "Eskalācijas lomas",
+ "Escalation ladder": "Eskalācijas kāpnes",
+ "Exception dates": "Izņēmuma datumi",
+ "Hours per working day": "Stundas darba dienā",
+ "How many days the observed date shifts, e.g. -1 for the Saturday before.": "Par cik dienām svinamais datums tiek pārcelts, piem. -1 iepriekšējai sestdienai.",
+ "Human-readable title.": "Salasāms virsraksts.",
+ "ISO weekdays (1 = Monday, 7 = Sunday) that are working days.": "ISO nedēļas dienas (1 = pirmdiena, 7 = svētdiena), kas ir darba dienas.",
+ "Kind": "Veids",
+ "Message": "Ziņojums",
+ "Month": "Mēnesis",
+ "Month of a fixed or observedShift rule; ignored by an easter rule.": "Noteikuma fixed vai observedShift mēnesis; noteikums easter to ignorē.",
+ "Non-working-date rules": "Brīvdienu noteikumi",
+ "Notify roles": "Informējamās lomas",
+ "Observed shift": "Svētku pārcelšana",
+ "Offset": "Nobīde",
+ "Offset unit": "Nobīdes vienība",
+ "Open incident": "Atvērt incidentu",
+ "Optional map from a role name to a concrete recipient descriptor, e.g. {\"teamleader\": \"group:teamleaders\"}. Roles without a binding travel unresolved as role:.": "Neobligāta karte no lomas nosaukuma uz konkrētu saņēmēju, piem. {\"teamleader\": \"group:teamleaders\"}. Lomas bez sasaistes ceļo neatrisinātas kā role:.",
+ "Optional on a fixed rule, required on observedShift: {whenWeekday: weekday name or ISO 1..7, days: integer}.": "Neobligāts noteikumam fixed, obligāts observedShift: {whenWeekday: dienas nosaukums vai ISO 1..7, days: vesels skaitlis}.",
+ "Ordered rungs: {key, trigger (preBreach|slaBreached), offset, offsetUnit (hours|businessDays|calendarDays), notifyRole[], escalateToRole[], priority, message, openIncident}.": "Sakārtoti pakāpieni: {key, trigger (preBreach|slaBreached), offset, offsetUnit (hours|businessDays|calendarDays), notifyRole[], escalateToRole[], priority, message, openIncident}.",
+ "Priority": "Prioritāte",
+ "Role bindings": "Lomu sasaistes",
+ "Roles the matter is escalated to at this rung.": "Lomas, kurām lieta šajā pakāpienā tiek eskalēta.",
+ "Roles told at this rung; handler is the subject's own performer.": "Šajā pakāpienā informētās lomas; handler ir lietas kārtotājs.",
+ "Rungs": "Pakāpieni",
+ "Stable rung identity, e.g. preBreach:14:calendarDays; derived from trigger, offset and unit when absent.": "Pakāpiena pastāvīgā identitāte, piem. preBreach:14:calendarDays; ja tās nav, to atvasina no trigera, nobīdes un vienības.",
+ "The calendar's stable name, referenced by a timer's calendar_slug.": "Kalendāra pastāvīgais nosaukums, uz kuru taimeris atsaucas ar calendar_slug.",
+ "The closed date, Y-m-d.": "Slēgšanas datums, Y-m-d.",
+ "The holiday's name.": "Svētku nosaukums.",
+ "The ladder's stable name, referenced by a timer's ladder_slug.": "Kāpņu pastāvīgais nosaukums, uz kuru taimeris atsaucas ar ladder_slug.",
+ "The unit of the offset: the same set the SLA accepts.": "Nobīdes vienība: tā pati kopa, ko pieņem SLA.",
+ "The urgency the raised transition carries.": "Steidzamība, ko nes izraisītā pāreja.",
+ "The weekday (name) on which the date shifts, e.g. sunday for Koningsdag.": "Nedēļas diena (nosaukums), kurā datums tiek pārcelts, piem. sunday Koningsdag gadījumā.",
+ "UUID of the organisation this calendar is configured for. Empty for a shared calendar. The resolution order picks an organisation's calendar when the timer names none.": "Organizācijas UUID, kurai šis kalendārs ir iestatīts. Tukšs koplietotam kalendāram. Ja taimeris nevienu nenosauc, atrisināšanas secība izvēlas organizācijas kalendāru.",
+ "UUID of the organisation this ladder is the default for. Empty for the shared default.": "Organizācijas UUID, kurai šīs kāpnes ir noklusējums. Tukšs koplietotajam noklusējumam.",
+ "When weekday": "Ja iekrīt",
+ "Whether reaching this rung opens an incident.": "Vai šī pakāpiena sasniegšana atver incidentu.",
+ "Why the day is closed.": "Kāpēc šī diena ir slēgta.",
+ "Working calendar": "Darba kalendārs",
+ "Working hours in one working day. Makes hours and businessDays commensurable.": "Darba stundas vienā darba dienā. Padara stundas un darba dienas salīdzināmas.",
+ "Working weekdays": "Nedēļas darba dienas",
+ "fixed: a month/day; easter: an offset in days from Easter Sunday; observedShift: a month/day with a required observed shift.": "fixed: mēnesis un diena; easter: nobīde dienās no Lieldienu svētdienas; observedShift: mēnesis un diena ar obligātu pārcelšanu.",
+ "preBreach fires before the deadline, slaBreached at or after it.": "preBreach nostrādā pirms termiņa, slaBreached termiņā vai pēc tā.",
+ "No such task": "Nav šāda uzdevuma",
+ "The task does not exist, or it is not yours to see.": "Uzdevums nepastāv, vai jums nav tiesību to redzēt.",
+ "Details": "Detaļas",
+ "Due": "Termiņš",
+ "Assignee": "Atbildīgais",
+ "Requested by": "Pieprasīja",
+ "Outcome": "Iznākums",
+ "Ready to claim": "Gatavs pārņemšanai",
+ "In progress": "Procesā",
+ "Terminated": "Pārtraukts",
+ "Normal": "Parasts",
+ "Urgent": "Steidzams",
+ "Overdue by 1 day": "Nokavēts par 1 dienu",
+ "Overdue by {days} days": "Nokavēts par {days} dienām",
+ "Due today": "Termiņš šodien",
+ "Due tomorrow": "Termiņš rīt",
+ "Due in {days} days": "Termiņš pēc {days} dienām",
+ "Tasks": "Uzdevumi",
+ "Task": "Uzdevums",
+ "Unassigned, open for claiming": "Nepiešķirts, atvērts pārņemšanai",
+ "Claim": "Pārņemt",
+ "Complete": "Pabeigt",
+ "Complete: {outcome}": "Pabeigt: {outcome}",
+ "Could not load the task": "Neizdevās ielādēt uzdevumu",
+ "The task refused that action": "Uzdevums noraidīja šo darbību"
},
"pluralForm": "nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n != 0 ? 1 : 2);",
"plurals": {
diff --git a/l10n/mk.js b/l10n/mk.js
index 0d4620d45d..933300fe9a 100644
--- a/l10n/mk.js
+++ b/l10n/mk.js
@@ -3,11 +3,21 @@ OC.L10N.register(
{
"3": "3",
"30": "30",
+ "from amount {amount}": "од износ {amount}",
+ "Gated transition: {transition}": "Надгледуван премин: {transition}",
+ "Each declared chain provisions an ordered task sequence when its transition is attempted. Approvers decide in their task inbox, not here.": "Секој деклариран синџир отвора подредена низа задачи кога преминот ќе се обиде. Одобрувачите одлучуваат во своето сандаче со задачи, не овде.",
+ "Declare x-openregister-approval-chains on this schema to gate a lifecycle transition on approval.": "Декларирајте x-openregister-approval-chains на оваа шема за преминот од животниот циклус да бара одобрение.",
+ "Approval sequences": "Низи на одобрување",
"%n entries have no hash yet": "%n записи сè уште немаат хеш",
"%n entry has no hash yet": "%n запис сè уште нема хеш",
"(Dolphin required)": "(Потребен Dolphin)",
+ "No approval chains declared": "Нема декларирани синџири за одобрување",
"(no subject)": "(без предмет)",
"(no title)": "(без наслов)",
+ "Role {role}": "Улога {role}",
+ "The transition is applied automatically once every step approves.": "Преминот се применува автоматски штом секој чекор е одобрен.",
+ "The requester may not decide their own approval.": "Барателот не може да одлучува за сопственото одобрение.",
+ "Tier routing on field: {field}": "Скалесто насочување по полето: {field}",
"(unnamed)": "(без име)",
"(untitled card)": "(картичка без наслов)",
"({count} selected)": "({count} избрани)",
@@ -2738,7 +2748,84 @@ OC.L10N.register(
"_Object successfully deleted_::_Objects successfully deleted_": ["Објектот е успешно избришан","Објектите се успешно избришани"],
"_Purge {count} object from database_::_Purge {count} objects from database_": ["Исчисти {count} објект од базата на податоци","Исчисти {count} објекти од базата на податоци"],
"_Restore {count} object_::_Restore {count} objects_": ["Врати {count} објект","Врати {count} објекти"],
- "_Successfully restored {count} object_::_Successfully restored {count} objects_": ["Успешно вратен {count} објект","Успешно вратени {count} објекти"]
+ "_Successfully restored {count} object_::_Successfully restored {count} objects_": ["Успешно вратен {count} објект","Успешно вратени {count} објекти"],
+ "A message identity the notification subsystem resolves.": "Идентитет на порака што го разрешува системот за известувања.",
+ "Computed non-working-date rules. kind fixed: {month, day, name, observedShift?: {whenWeekday, days}}. kind easter: {offset, name}, offset in days from Easter Sunday. kind observedShift: a fixed date with a required shift.": "Пресметани правила за неработните денови. Вид fixed: {month, day, name, observedShift?: {whenWeekday, days}}. Вид easter: {offset, name}, поместување во денови од Велигденската недела. Вид observedShift: фиксен датум со задолжително преместување.",
+ "Date": "Датум",
+ "Day": "Ден",
+ "Day of a fixed or observedShift rule; ignored by an easter rule.": "Ден на правило fixed или observedShift; правилото easter го игнорира.",
+ "Days": "Денови",
+ "Days from Easter Sunday for an easter rule; ignored by the other kinds.": "Денови од Велигденската недела за правило easter; другите видови ги игнорираат.",
+ "Distance from the deadline, in the offset unit.": "Растојание до рокот, во единицата на поместувањето.",
+ "Enumerated one-off closures as {date, name}. Allowed alongside rules; refused as the whole calendar.": "Поединечни затворања наброени како {date, name}. Дозволени покрај правила; одбиени како цел календар.",
+ "Escalate to roles": "Улоги за ескалација",
+ "Escalation ladder": "Скала на ескалација",
+ "Exception dates": "Исклучителни датуми",
+ "Hours per working day": "Часови по работен ден",
+ "How many days the observed date shifts, e.g. -1 for the Saturday before.": "За колку денови се преместува празнуваниот датум, на пр. -1 за претходната сабота.",
+ "Human-readable title.": "Читлив наслов.",
+ "ISO weekdays (1 = Monday, 7 = Sunday) that are working days.": "ISO денови во неделата (1 = понеделник, 7 = недела) што се работни.",
+ "Kind": "Вид",
+ "Message": "Порака",
+ "Month": "Месец",
+ "Month of a fixed or observedShift rule; ignored by an easter rule.": "Месец на правило fixed или observedShift; правилото easter го игнорира.",
+ "Non-working-date rules": "Правила за неработните денови",
+ "Notify roles": "Улоги за известување",
+ "Observed shift": "Преместување на празникот",
+ "Offset": "Поместување",
+ "Offset unit": "Единица на поместувањето",
+ "Open incident": "Отвори инцидент",
+ "Optional map from a role name to a concrete recipient descriptor, e.g. {\"teamleader\": \"group:teamleaders\"}. Roles without a binding travel unresolved as role:.": "Незадолжителна мапа од име на улога кон конкретен примач, на пр. {\"teamleader\": \"group:teamleaders\"}. Улогите без врзување патуваат неразрешени како role:.",
+ "Optional on a fixed rule, required on observedShift: {whenWeekday: weekday name or ISO 1..7, days: integer}.": "Незадолжително кај правило fixed, задолжително кај observedShift: {whenWeekday: име на ден или ISO 1..7, days: цел број}.",
+ "Ordered rungs: {key, trigger (preBreach|slaBreached), offset, offsetUnit (hours|businessDays|calendarDays), notifyRole[], escalateToRole[], priority, message, openIncident}.": "Подредени скалила: {key, trigger (preBreach|slaBreached), offset, offsetUnit (hours|businessDays|calendarDays), notifyRole[], escalateToRole[], priority, message, openIncident}.",
+ "Priority": "Приоритет",
+ "Role bindings": "Врзувања на улоги",
+ "Roles the matter is escalated to at this rung.": "Улоги кон кои предметот се ескалира на ова скалило.",
+ "Roles told at this rung; handler is the subject's own performer.": "Улоги известени на ова скалило; handler е лицето што го обработува предметот.",
+ "Rungs": "Скалила",
+ "Stable rung identity, e.g. preBreach:14:calendarDays; derived from trigger, offset and unit when absent.": "Постојан идентитет на скалилото, на пр. preBreach:14:calendarDays; ако недостига, се изведува од активаторот, поместувањето и единицата.",
+ "The calendar's stable name, referenced by a timer's calendar_slug.": "Постојаното име на календарот, посочено преку calendar_slug на тајмерот.",
+ "The closed date, Y-m-d.": "Датумот на затворање, Y-m-d.",
+ "The holiday's name.": "Името на празникот.",
+ "The ladder's stable name, referenced by a timer's ladder_slug.": "Постојаното име на скалата, посочено преку ladder_slug на тајмерот.",
+ "The unit of the offset: the same set the SLA accepts.": "Единицата на поместувањето: истото множество што го прифаќа SLA.",
+ "The urgency the raised transition carries.": "Итноста што ја носи активираниот премин.",
+ "The weekday (name) on which the date shifts, e.g. sunday for Koningsdag.": "Денот од неделата (име) на кој датумот се преместува, на пр. sunday за Koningsdag.",
+ "UUID of the organisation this calendar is configured for. Empty for a shared calendar. The resolution order picks an organisation's calendar when the timer names none.": "UUID на организацијата за која е поставен овој календар. Празно за споделен календар. Ако тајмерот не именува ниеден, редоследот на разрешување го избира календарот на организацијата.",
+ "UUID of the organisation this ladder is the default for. Empty for the shared default.": "UUID на организацијата за која оваа скала е стандардна. Празно за споделената стандардна.",
+ "When weekday": "Ако падне во",
+ "Whether reaching this rung opens an incident.": "Дали достигнувањето на ова скалило отвора инцидент.",
+ "Why the day is closed.": "Зошто денот е затворен.",
+ "Working calendar": "Работен календар",
+ "Working hours in one working day. Makes hours and businessDays commensurable.": "Работни часови во еден работен ден. Ги прави часовите и работните денови споредливи.",
+ "Working weekdays": "Работни денови во неделата",
+ "fixed: a month/day; easter: an offset in days from Easter Sunday; observedShift: a month/day with a required observed shift.": "fixed: месец и ден; easter: поместување во денови од Велигденската недела; observedShift: месец и ден со задолжително преместување.",
+ "preBreach fires before the deadline, slaBreached at or after it.": "preBreach се активира пред рокот, slaBreached на рокот или потоа.",
+ "No such task": "Нема таква задача",
+ "The task does not exist, or it is not yours to see.": "Задачата не постои или немате право да ја видите.",
+ "Details": "Детали",
+ "Due": "Рок",
+ "Assignee": "Доделено",
+ "Requested by": "Побарано од",
+ "Outcome": "Исход",
+ "Ready to claim": "Подготвено за преземање",
+ "In progress": "Во тек",
+ "Terminated": "Прекинато",
+ "Normal": "Нормално",
+ "Urgent": "Итно",
+ "Overdue by 1 day": "Доцни 1 ден",
+ "Overdue by {days} days": "Доцни {days} дена",
+ "Due today": "Рок денес",
+ "Due tomorrow": "Рок утре",
+ "Due in {days} days": "Рок за {days} дена",
+ "Tasks": "Задачи",
+ "Task": "Задача",
+ "Unassigned, open for claiming": "Недоделено, отворено за преземање",
+ "Claim": "Преземи",
+ "Complete": "Заврши",
+ "Complete: {outcome}": "Заврши: {outcome}",
+ "Could not load the task": "Задачата не може да се вчита",
+ "The task refused that action": "Задачата го одби тоа дејство"
},
"nplurals=2; plural=(n != 1);"
)
diff --git a/l10n/mk.json b/l10n/mk.json
index 484cc82bd3..da2beb46eb 100644
--- a/l10n/mk.json
+++ b/l10n/mk.json
@@ -1,10 +1,20 @@
{
"translations": {
+ "from amount {amount}": "од износ {amount}",
+ "Gated transition: {transition}": "Надгледуван премин: {transition}",
+ "Each declared chain provisions an ordered task sequence when its transition is attempted. Approvers decide in their task inbox, not here.": "Секој деклариран синџир отвора подредена низа задачи кога преминот ќе се обиде. Одобрувачите одлучуваат во своето сандаче со задачи, не овде.",
+ "Declare x-openregister-approval-chains on this schema to gate a lifecycle transition on approval.": "Декларирајте x-openregister-approval-chains на оваа шема за преминот од животниот циклус да бара одобрение.",
+ "Approval sequences": "Низи на одобрување",
"%n entries have no hash yet": "%n записи сè уште немаат хеш",
"%n entry has no hash yet": "%n запис сè уште нема хеш",
"(Dolphin required)": "(Потребен Dolphin)",
+ "No approval chains declared": "Нема декларирани синџири за одобрување",
"(no subject)": "(без предмет)",
"(no title)": "(без наслов)",
+ "Role {role}": "Улога {role}",
+ "The transition is applied automatically once every step approves.": "Преминот се применува автоматски штом секој чекор е одобрен.",
+ "The requester may not decide their own approval.": "Барателот не може да одлучува за сопственото одобрение.",
+ "Tier routing on field: {field}": "Скалесто насочување по полето: {field}",
"(unnamed)": "(без име)",
"(untitled card)": "(картичка без наслов)",
"({count} selected)": "({count} избрани)",
@@ -2785,7 +2795,84 @@
"_Successfully restored {count} object_::_Successfully restored {count} objects_": [
"Успешно вратен {count} објект",
"Успешно вратени {count} објекти"
- ]
+ ],
+ "A message identity the notification subsystem resolves.": "Идентитет на порака што го разрешува системот за известувања.",
+ "Computed non-working-date rules. kind fixed: {month, day, name, observedShift?: {whenWeekday, days}}. kind easter: {offset, name}, offset in days from Easter Sunday. kind observedShift: a fixed date with a required shift.": "Пресметани правила за неработните денови. Вид fixed: {month, day, name, observedShift?: {whenWeekday, days}}. Вид easter: {offset, name}, поместување во денови од Велигденската недела. Вид observedShift: фиксен датум со задолжително преместување.",
+ "Date": "Датум",
+ "Day": "Ден",
+ "Day of a fixed or observedShift rule; ignored by an easter rule.": "Ден на правило fixed или observedShift; правилото easter го игнорира.",
+ "Days": "Денови",
+ "Days from Easter Sunday for an easter rule; ignored by the other kinds.": "Денови од Велигденската недела за правило easter; другите видови ги игнорираат.",
+ "Distance from the deadline, in the offset unit.": "Растојание до рокот, во единицата на поместувањето.",
+ "Enumerated one-off closures as {date, name}. Allowed alongside rules; refused as the whole calendar.": "Поединечни затворања наброени како {date, name}. Дозволени покрај правила; одбиени како цел календар.",
+ "Escalate to roles": "Улоги за ескалација",
+ "Escalation ladder": "Скала на ескалација",
+ "Exception dates": "Исклучителни датуми",
+ "Hours per working day": "Часови по работен ден",
+ "How many days the observed date shifts, e.g. -1 for the Saturday before.": "За колку денови се преместува празнуваниот датум, на пр. -1 за претходната сабота.",
+ "Human-readable title.": "Читлив наслов.",
+ "ISO weekdays (1 = Monday, 7 = Sunday) that are working days.": "ISO денови во неделата (1 = понеделник, 7 = недела) што се работни.",
+ "Kind": "Вид",
+ "Message": "Порака",
+ "Month": "Месец",
+ "Month of a fixed or observedShift rule; ignored by an easter rule.": "Месец на правило fixed или observedShift; правилото easter го игнорира.",
+ "Non-working-date rules": "Правила за неработните денови",
+ "Notify roles": "Улоги за известување",
+ "Observed shift": "Преместување на празникот",
+ "Offset": "Поместување",
+ "Offset unit": "Единица на поместувањето",
+ "Open incident": "Отвори инцидент",
+ "Optional map from a role name to a concrete recipient descriptor, e.g. {\"teamleader\": \"group:teamleaders\"}. Roles without a binding travel unresolved as role:.": "Незадолжителна мапа од име на улога кон конкретен примач, на пр. {\"teamleader\": \"group:teamleaders\"}. Улогите без врзување патуваат неразрешени како role:.",
+ "Optional on a fixed rule, required on observedShift: {whenWeekday: weekday name or ISO 1..7, days: integer}.": "Незадолжително кај правило fixed, задолжително кај observedShift: {whenWeekday: име на ден или ISO 1..7, days: цел број}.",
+ "Ordered rungs: {key, trigger (preBreach|slaBreached), offset, offsetUnit (hours|businessDays|calendarDays), notifyRole[], escalateToRole[], priority, message, openIncident}.": "Подредени скалила: {key, trigger (preBreach|slaBreached), offset, offsetUnit (hours|businessDays|calendarDays), notifyRole[], escalateToRole[], priority, message, openIncident}.",
+ "Priority": "Приоритет",
+ "Role bindings": "Врзувања на улоги",
+ "Roles the matter is escalated to at this rung.": "Улоги кон кои предметот се ескалира на ова скалило.",
+ "Roles told at this rung; handler is the subject's own performer.": "Улоги известени на ова скалило; handler е лицето што го обработува предметот.",
+ "Rungs": "Скалила",
+ "Stable rung identity, e.g. preBreach:14:calendarDays; derived from trigger, offset and unit when absent.": "Постојан идентитет на скалилото, на пр. preBreach:14:calendarDays; ако недостига, се изведува од активаторот, поместувањето и единицата.",
+ "The calendar's stable name, referenced by a timer's calendar_slug.": "Постојаното име на календарот, посочено преку calendar_slug на тајмерот.",
+ "The closed date, Y-m-d.": "Датумот на затворање, Y-m-d.",
+ "The holiday's name.": "Името на празникот.",
+ "The ladder's stable name, referenced by a timer's ladder_slug.": "Постојаното име на скалата, посочено преку ladder_slug на тајмерот.",
+ "The unit of the offset: the same set the SLA accepts.": "Единицата на поместувањето: истото множество што го прифаќа SLA.",
+ "The urgency the raised transition carries.": "Итноста што ја носи активираниот премин.",
+ "The weekday (name) on which the date shifts, e.g. sunday for Koningsdag.": "Денот од неделата (име) на кој датумот се преместува, на пр. sunday за Koningsdag.",
+ "UUID of the organisation this calendar is configured for. Empty for a shared calendar. The resolution order picks an organisation's calendar when the timer names none.": "UUID на организацијата за која е поставен овој календар. Празно за споделен календар. Ако тајмерот не именува ниеден, редоследот на разрешување го избира календарот на организацијата.",
+ "UUID of the organisation this ladder is the default for. Empty for the shared default.": "UUID на организацијата за која оваа скала е стандардна. Празно за споделената стандардна.",
+ "When weekday": "Ако падне во",
+ "Whether reaching this rung opens an incident.": "Дали достигнувањето на ова скалило отвора инцидент.",
+ "Why the day is closed.": "Зошто денот е затворен.",
+ "Working calendar": "Работен календар",
+ "Working hours in one working day. Makes hours and businessDays commensurable.": "Работни часови во еден работен ден. Ги прави часовите и работните денови споредливи.",
+ "Working weekdays": "Работни денови во неделата",
+ "fixed: a month/day; easter: an offset in days from Easter Sunday; observedShift: a month/day with a required observed shift.": "fixed: месец и ден; easter: поместување во денови од Велигденската недела; observedShift: месец и ден со задолжително преместување.",
+ "preBreach fires before the deadline, slaBreached at or after it.": "preBreach се активира пред рокот, slaBreached на рокот или потоа.",
+ "No such task": "Нема таква задача",
+ "The task does not exist, or it is not yours to see.": "Задачата не постои или немате право да ја видите.",
+ "Details": "Детали",
+ "Due": "Рок",
+ "Assignee": "Доделено",
+ "Requested by": "Побарано од",
+ "Outcome": "Исход",
+ "Ready to claim": "Подготвено за преземање",
+ "In progress": "Во тек",
+ "Terminated": "Прекинато",
+ "Normal": "Нормално",
+ "Urgent": "Итно",
+ "Overdue by 1 day": "Доцни 1 ден",
+ "Overdue by {days} days": "Доцни {days} дена",
+ "Due today": "Рок денес",
+ "Due tomorrow": "Рок утре",
+ "Due in {days} days": "Рок за {days} дена",
+ "Tasks": "Задачи",
+ "Task": "Задача",
+ "Unassigned, open for claiming": "Недоделено, отворено за преземање",
+ "Claim": "Преземи",
+ "Complete": "Заврши",
+ "Complete: {outcome}": "Заврши: {outcome}",
+ "Could not load the task": "Задачата не може да се вчита",
+ "The task refused that action": "Задачата го одби тоа дејство"
},
"pluralForm": "nplurals=2; plural=(n != 1);",
"plurals": {
diff --git a/l10n/mt.js b/l10n/mt.js
index bafeacfbbc..57b25f55d3 100644
--- a/l10n/mt.js
+++ b/l10n/mt.js
@@ -3,11 +3,21 @@ OC.L10N.register(
{
"3": "3",
"30": "30",
+ "from amount {amount}": "minn ammont {amount}",
+ "Gated transition: {transition}": "Tranżizzjoni mgħassa: {transition}",
+ "Each declared chain provisions an ordered task sequence when its transition is attempted. Approvers decide in their task inbox, not here.": "Kull katina ddikjarata tiftaħ sekwenza ordnata ta' kompiti meta t-tranżizzjoni tiġi ppruvata. L-approvaturi jiddeċiedu fl-inbox tal-kompiti tagħhom, mhux hawn.",
+ "Declare x-openregister-approval-chains on this schema to gate a lifecycle transition on approval.": "Iddikjara x-openregister-approval-chains fuq din l-iskema biex tranżizzjoni taċ-ċiklu tal-ħajja tkun teħtieġ approvazzjoni.",
+ "Approval sequences": "Sekwenzi ta' approvazzjoni",
"%n entries have no hash yet": "%n entrati għadhom m'għandhomx hash",
"%n entry has no hash yet": "%n entrata għadha m'għandhiex hash",
"(Dolphin required)": "(Dolphin meħtieġ)",
+ "No approval chains declared": "Ebda katina ta' approvazzjoni ddikjarata",
"(no subject)": "(l-ebda suġġett)",
"(no title)": "(l-ebda titlu)",
+ "Role {role}": "Rwol {role}",
+ "The transition is applied automatically once every step approves.": "It-tranżizzjoni tiġi applikata awtomatikament malli kull pass ikun approvat.",
+ "The requester may not decide their own approval.": "Min jitlob ma jistax jiddeċiedi dwar l-approvazzjoni tiegħu stess.",
+ "Tier routing on field: {field}": "Rotot skont il-livell fuq il-qasam: {field}",
"(unnamed)": "(bla isem)",
"(untitled card)": "(karta bla titlu)",
"({count} selected)": "({count} magħżula)",
@@ -2738,7 +2748,84 @@ OC.L10N.register(
"_Object successfully deleted_::_Objects successfully deleted_": ["L-oġġett tħassar b'suċċess","L-oġġetti tħassru b'suċċess","L-oġġetti tħassru b'suċċess","L-oġġetti tħassru b'suċċess"],
"_Purge {count} object from database_::_Purge {count} objects from database_": ["Neħħi {count} oġġett mid-database","Neħħi {count} oġġetti mid-database","Neħħi {count} oġġett mid-database","Neħħi {count} oġġett mid-database"],
"_Restore {count} object_::_Restore {count} objects_": ["Irrestawra {count} oġġett","Irrestawra {count} oġġetti","Irrestawra {count} oġġett","Irrestawra {count} oġġett"],
- "_Successfully restored {count} object_::_Successfully restored {count} objects_": ["{count} oġġett ġie rrestawrat b'suċċess","{count} oġġetti ġew irrestawrati b'suċċess","{count} oġġett ġie rrestawrat b'suċċess","{count} oġġett ġie rrestawrat b'suċċess"]
+ "_Successfully restored {count} object_::_Successfully restored {count} objects_": ["{count} oġġett ġie rrestawrat b'suċċess","{count} oġġetti ġew irrestawrati b'suċċess","{count} oġġett ġie rrestawrat b'suċċess","{count} oġġett ġie rrestawrat b'suċċess"],
+ "A message identity the notification subsystem resolves.": "Identità ta' messaġġ li s-sottosistema tan-notifiki tirrisolvi.",
+ "Computed non-working-date rules. kind fixed: {month, day, name, observedShift?: {whenWeekday, days}}. kind easter: {offset, name}, offset in days from Easter Sunday. kind observedShift: a fixed date with a required shift.": "Regoli kkalkulati tal-ġranet mhux tax-xogħol. Tip fixed: {month, day, name, observedShift?: {whenWeekday, days}}. Tip easter: {offset, name}, spostament f'ġranet minn Ħadd il-Għid. Tip observedShift: data fissa bi trasferiment obbligatorju.",
+ "Date": "Data",
+ "Day": "Jum",
+ "Day of a fixed or observedShift rule; ignored by an easter rule.": "Il-jum ta' regola fixed jew observedShift; regola easter tinjorah.",
+ "Days": "Ġranet",
+ "Days from Easter Sunday for an easter rule; ignored by the other kinds.": "Ġranet minn Ħadd il-Għid għal regola easter; it-tipi l-oħra jinjorawhom.",
+ "Distance from the deadline, in the offset unit.": "Id-distanza mill-iskadenza, fl-unità tal-ispostament.",
+ "Enumerated one-off closures as {date, name}. Allowed alongside rules; refused as the whole calendar.": "Għeluq ta' darba elenkati bħala {date, name}. Permessi ħdejn ir-regoli; miċħuda bħala l-kalendarju kollu.",
+ "Escalate to roles": "Rwoli tal-eskalazzjoni",
+ "Escalation ladder": "Sellum tal-eskalazzjoni",
+ "Exception dates": "Dati ta' eċċezzjoni",
+ "Hours per working day": "Sigħat għal kull jum tax-xogħol",
+ "How many days the observed date shifts, e.g. -1 for the Saturday before.": "Kemm-il jum tiġi trasferita d-data ċċelebrata, eż. -1 għas-Sibt ta' qabel.",
+ "Human-readable title.": "Titlu li jinqara.",
+ "ISO weekdays (1 = Monday, 7 = Sunday) that are working days.": "Il-ġranet ISO tal-ġimgħa (1 = it-Tnejn, 7 = il-Ħadd) li huma ġranet tax-xogħol.",
+ "Kind": "Tip",
+ "Message": "Messaġġ",
+ "Month": "Xahar",
+ "Month of a fixed or observedShift rule; ignored by an easter rule.": "Ix-xahar ta' regola fixed jew observedShift; regola easter tinjorah.",
+ "Non-working-date rules": "Regoli tal-ġranet mhux tax-xogħol",
+ "Notify roles": "Rwoli x'jiġu notifikati",
+ "Observed shift": "Trasferiment tal-festa",
+ "Offset": "Spostament",
+ "Offset unit": "Unità tal-ispostament",
+ "Open incident": "Iftaħ inċident",
+ "Optional map from a role name to a concrete recipient descriptor, e.g. {\"teamleader\": \"group:teamleaders\"}. Roles without a binding travel unresolved as role:.": "Mappa fakultattiva minn isem ta' rwol għal riċevitur konkret, eż. {\"teamleader\": \"group:teamleaders\"}. Rwoli mingħajr rabta jivvjaġġaw mhux riżolti bħala role:.",
+ "Optional on a fixed rule, required on observedShift: {whenWeekday: weekday name or ISO 1..7, days: integer}.": "Fakultattiv fuq regola fixed, obbligatorju fuq observedShift: {whenWeekday: isem il-jum jew ISO 1..7, days: numru sħiħ}.",
+ "Ordered rungs: {key, trigger (preBreach|slaBreached), offset, offsetUnit (hours|businessDays|calendarDays), notifyRole[], escalateToRole[], priority, message, openIncident}.": "Tarġiet ordnati: {key, trigger (preBreach|slaBreached), offset, offsetUnit (hours|businessDays|calendarDays), notifyRole[], escalateToRole[], priority, message, openIncident}.",
+ "Priority": "Prijorità",
+ "Role bindings": "Rabtiet tar-rwoli",
+ "Roles the matter is escalated to at this rung.": "Ir-rwoli li lilhom il-każ jiġi eskalat f'din it-tarġa.",
+ "Roles told at this rung; handler is the subject's own performer.": "Ir-rwoli notifikati f'din it-tarġa; handler huwa l-persuna li tieħu ħsieb il-każ.",
+ "Rungs": "Tarġiet",
+ "Stable rung identity, e.g. preBreach:14:calendarDays; derived from trigger, offset and unit when absent.": "Identità stabbli tat-tarġa, eż. preBreach:14:calendarDays; meta tkun nieqsa, tiġi derivata mill-grillu, mill-ispostament u mill-unità.",
+ "The calendar's stable name, referenced by a timer's calendar_slug.": "L-isem stabbli tal-kalendarju, li timer jirreferi għalih permezz ta' calendar_slug.",
+ "The closed date, Y-m-d.": "Id-data tal-għeluq, Y-m-d.",
+ "The holiday's name.": "L-isem tal-festa.",
+ "The ladder's stable name, referenced by a timer's ladder_slug.": "L-isem stabbli tas-sellum, li timer jirreferi għalih permezz ta' ladder_slug.",
+ "The unit of the offset: the same set the SLA accepts.": "L-unità tal-ispostament: l-istess sett li jaċċetta l-SLA.",
+ "The urgency the raised transition carries.": "L-urġenza li ġġorr it-tranżizzjoni skattata.",
+ "The weekday (name) on which the date shifts, e.g. sunday for Koningsdag.": "Il-jum tal-ġimgħa (isem) li fih id-data tiġi trasferita, eż. sunday għal Koningsdag.",
+ "UUID of the organisation this calendar is configured for. Empty for a shared calendar. The resolution order picks an organisation's calendar when the timer names none.": "UUID tal-organizzazzjoni li għaliha huwa kkonfigurat dan il-kalendarju. Vojt għal kalendarju kondiviż. Jekk it-timer ma jsemmi xejn, l-ordni tar-riżoluzzjoni tagħżel il-kalendarju tal-organizzazzjoni.",
+ "UUID of the organisation this ladder is the default for. Empty for the shared default.": "UUID tal-organizzazzjoni li għaliha dan is-sellum huwa l-predefinit. Vojt għall-predefinit kondiviż.",
+ "When weekday": "Jekk taħbat",
+ "Whether reaching this rung opens an incident.": "Jekk il-wasla f'din it-tarġa tiftaħx inċident.",
+ "Why the day is closed.": "Għaliex dak il-jum huwa magħluq.",
+ "Working calendar": "Kalendarju tax-xogħol",
+ "Working hours in one working day. Makes hours and businessDays commensurable.": "Is-sigħat tax-xogħol f'jum tax-xogħol wieħed. Jagħmel is-sigħat u l-ġranet tax-xogħol komparabbli.",
+ "Working weekdays": "Il-ġranet tax-xogħol tal-ġimgħa",
+ "fixed: a month/day; easter: an offset in days from Easter Sunday; observedShift: a month/day with a required observed shift.": "fixed: xahar u jum; easter: spostament f'ġranet minn Ħadd il-Għid; observedShift: xahar u jum bi trasferiment obbligatorju.",
+ "preBreach fires before the deadline, slaBreached at or after it.": "preBreach jiskatta qabel l-iskadenza, slaBreached fl-iskadenza jew warajha.",
+ "No such task": "M'hemm l-ebda kompitu bħal dan",
+ "The task does not exist, or it is not yours to see.": "Il-kompitu ma jeżistix, jew m'għandekx permess tarah.",
+ "Details": "Dettalji",
+ "Due": "Skadenza",
+ "Assignee": "Assenjat lil",
+ "Requested by": "Mitlub minn",
+ "Outcome": "Riżultat",
+ "Ready to claim": "Lest biex jittieħed",
+ "In progress": "Għaddej",
+ "Terminated": "Itterminat",
+ "Normal": "Normali",
+ "Urgent": "Urġenti",
+ "Overdue by 1 day": "Skadut b'jum 1",
+ "Overdue by {days} days": "Skadut b'{days} ijiem",
+ "Due today": "Skadenza llum",
+ "Due tomorrow": "Skadenza għada",
+ "Due in {days} days": "Skadenza fi {days} ijiem",
+ "Tasks": "Kompiti",
+ "Task": "Kompitu",
+ "Unassigned, open for claiming": "Mhux assenjat, miftuħ biex jittieħed",
+ "Claim": "Ħu",
+ "Complete": "Lesti",
+ "Complete: {outcome}": "Lesti: {outcome}",
+ "Could not load the task": "Ma setax jitgħabba l-kompitu",
+ "The task refused that action": "Il-kompitu rrifjuta dik l-azzjoni"
},
"nplurals=4; plural=(n==1 ? 0 : n==0 || ( n%100>1 && n%100<11) ? 1 : (n%100>10 && n%100<20 ) ? 2 : 3);"
)
diff --git a/l10n/mt.json b/l10n/mt.json
index 2f4bd7ba12..1f8ae476ac 100644
--- a/l10n/mt.json
+++ b/l10n/mt.json
@@ -1,10 +1,20 @@
{
"translations": {
+ "from amount {amount}": "minn ammont {amount}",
+ "Gated transition: {transition}": "Tranżizzjoni mgħassa: {transition}",
+ "Each declared chain provisions an ordered task sequence when its transition is attempted. Approvers decide in their task inbox, not here.": "Kull katina ddikjarata tiftaħ sekwenza ordnata ta' kompiti meta t-tranżizzjoni tiġi ppruvata. L-approvaturi jiddeċiedu fl-inbox tal-kompiti tagħhom, mhux hawn.",
+ "Declare x-openregister-approval-chains on this schema to gate a lifecycle transition on approval.": "Iddikjara x-openregister-approval-chains fuq din l-iskema biex tranżizzjoni taċ-ċiklu tal-ħajja tkun teħtieġ approvazzjoni.",
+ "Approval sequences": "Sekwenzi ta' approvazzjoni",
"%n entries have no hash yet": "%n entrati għadhom m'għandhomx hash",
"%n entry has no hash yet": "%n entrata għadha m'għandhiex hash",
"(Dolphin required)": "(Dolphin meħtieġ)",
+ "No approval chains declared": "Ebda katina ta' approvazzjoni ddikjarata",
"(no subject)": "(l-ebda suġġett)",
"(no title)": "(l-ebda titlu)",
+ "Role {role}": "Rwol {role}",
+ "The transition is applied automatically once every step approves.": "It-tranżizzjoni tiġi applikata awtomatikament malli kull pass ikun approvat.",
+ "The requester may not decide their own approval.": "Min jitlob ma jistax jiddeċiedi dwar l-approvazzjoni tiegħu stess.",
+ "Tier routing on field: {field}": "Rotot skont il-livell fuq il-qasam: {field}",
"(unnamed)": "(bla isem)",
"(untitled card)": "(karta bla titlu)",
"({count} selected)": "({count} magħżula)",
@@ -2817,7 +2827,84 @@
"{count} oġġetti ġew irrestawrati b'suċċess",
"{count} oġġett ġie rrestawrat b'suċċess",
"{count} oġġett ġie rrestawrat b'suċċess"
- ]
+ ],
+ "A message identity the notification subsystem resolves.": "Identità ta' messaġġ li s-sottosistema tan-notifiki tirrisolvi.",
+ "Computed non-working-date rules. kind fixed: {month, day, name, observedShift?: {whenWeekday, days}}. kind easter: {offset, name}, offset in days from Easter Sunday. kind observedShift: a fixed date with a required shift.": "Regoli kkalkulati tal-ġranet mhux tax-xogħol. Tip fixed: {month, day, name, observedShift?: {whenWeekday, days}}. Tip easter: {offset, name}, spostament f'ġranet minn Ħadd il-Għid. Tip observedShift: data fissa bi trasferiment obbligatorju.",
+ "Date": "Data",
+ "Day": "Jum",
+ "Day of a fixed or observedShift rule; ignored by an easter rule.": "Il-jum ta' regola fixed jew observedShift; regola easter tinjorah.",
+ "Days": "Ġranet",
+ "Days from Easter Sunday for an easter rule; ignored by the other kinds.": "Ġranet minn Ħadd il-Għid għal regola easter; it-tipi l-oħra jinjorawhom.",
+ "Distance from the deadline, in the offset unit.": "Id-distanza mill-iskadenza, fl-unità tal-ispostament.",
+ "Enumerated one-off closures as {date, name}. Allowed alongside rules; refused as the whole calendar.": "Għeluq ta' darba elenkati bħala {date, name}. Permessi ħdejn ir-regoli; miċħuda bħala l-kalendarju kollu.",
+ "Escalate to roles": "Rwoli tal-eskalazzjoni",
+ "Escalation ladder": "Sellum tal-eskalazzjoni",
+ "Exception dates": "Dati ta' eċċezzjoni",
+ "Hours per working day": "Sigħat għal kull jum tax-xogħol",
+ "How many days the observed date shifts, e.g. -1 for the Saturday before.": "Kemm-il jum tiġi trasferita d-data ċċelebrata, eż. -1 għas-Sibt ta' qabel.",
+ "Human-readable title.": "Titlu li jinqara.",
+ "ISO weekdays (1 = Monday, 7 = Sunday) that are working days.": "Il-ġranet ISO tal-ġimgħa (1 = it-Tnejn, 7 = il-Ħadd) li huma ġranet tax-xogħol.",
+ "Kind": "Tip",
+ "Message": "Messaġġ",
+ "Month": "Xahar",
+ "Month of a fixed or observedShift rule; ignored by an easter rule.": "Ix-xahar ta' regola fixed jew observedShift; regola easter tinjorah.",
+ "Non-working-date rules": "Regoli tal-ġranet mhux tax-xogħol",
+ "Notify roles": "Rwoli x'jiġu notifikati",
+ "Observed shift": "Trasferiment tal-festa",
+ "Offset": "Spostament",
+ "Offset unit": "Unità tal-ispostament",
+ "Open incident": "Iftaħ inċident",
+ "Optional map from a role name to a concrete recipient descriptor, e.g. {\"teamleader\": \"group:teamleaders\"}. Roles without a binding travel unresolved as role:.": "Mappa fakultattiva minn isem ta' rwol għal riċevitur konkret, eż. {\"teamleader\": \"group:teamleaders\"}. Rwoli mingħajr rabta jivvjaġġaw mhux riżolti bħala role:.",
+ "Optional on a fixed rule, required on observedShift: {whenWeekday: weekday name or ISO 1..7, days: integer}.": "Fakultattiv fuq regola fixed, obbligatorju fuq observedShift: {whenWeekday: isem il-jum jew ISO 1..7, days: numru sħiħ}.",
+ "Ordered rungs: {key, trigger (preBreach|slaBreached), offset, offsetUnit (hours|businessDays|calendarDays), notifyRole[], escalateToRole[], priority, message, openIncident}.": "Tarġiet ordnati: {key, trigger (preBreach|slaBreached), offset, offsetUnit (hours|businessDays|calendarDays), notifyRole[], escalateToRole[], priority, message, openIncident}.",
+ "Priority": "Prijorità",
+ "Role bindings": "Rabtiet tar-rwoli",
+ "Roles the matter is escalated to at this rung.": "Ir-rwoli li lilhom il-każ jiġi eskalat f'din it-tarġa.",
+ "Roles told at this rung; handler is the subject's own performer.": "Ir-rwoli notifikati f'din it-tarġa; handler huwa l-persuna li tieħu ħsieb il-każ.",
+ "Rungs": "Tarġiet",
+ "Stable rung identity, e.g. preBreach:14:calendarDays; derived from trigger, offset and unit when absent.": "Identità stabbli tat-tarġa, eż. preBreach:14:calendarDays; meta tkun nieqsa, tiġi derivata mill-grillu, mill-ispostament u mill-unità.",
+ "The calendar's stable name, referenced by a timer's calendar_slug.": "L-isem stabbli tal-kalendarju, li timer jirreferi għalih permezz ta' calendar_slug.",
+ "The closed date, Y-m-d.": "Id-data tal-għeluq, Y-m-d.",
+ "The holiday's name.": "L-isem tal-festa.",
+ "The ladder's stable name, referenced by a timer's ladder_slug.": "L-isem stabbli tas-sellum, li timer jirreferi għalih permezz ta' ladder_slug.",
+ "The unit of the offset: the same set the SLA accepts.": "L-unità tal-ispostament: l-istess sett li jaċċetta l-SLA.",
+ "The urgency the raised transition carries.": "L-urġenza li ġġorr it-tranżizzjoni skattata.",
+ "The weekday (name) on which the date shifts, e.g. sunday for Koningsdag.": "Il-jum tal-ġimgħa (isem) li fih id-data tiġi trasferita, eż. sunday għal Koningsdag.",
+ "UUID of the organisation this calendar is configured for. Empty for a shared calendar. The resolution order picks an organisation's calendar when the timer names none.": "UUID tal-organizzazzjoni li għaliha huwa kkonfigurat dan il-kalendarju. Vojt għal kalendarju kondiviż. Jekk it-timer ma jsemmi xejn, l-ordni tar-riżoluzzjoni tagħżel il-kalendarju tal-organizzazzjoni.",
+ "UUID of the organisation this ladder is the default for. Empty for the shared default.": "UUID tal-organizzazzjoni li għaliha dan is-sellum huwa l-predefinit. Vojt għall-predefinit kondiviż.",
+ "When weekday": "Jekk taħbat",
+ "Whether reaching this rung opens an incident.": "Jekk il-wasla f'din it-tarġa tiftaħx inċident.",
+ "Why the day is closed.": "Għaliex dak il-jum huwa magħluq.",
+ "Working calendar": "Kalendarju tax-xogħol",
+ "Working hours in one working day. Makes hours and businessDays commensurable.": "Is-sigħat tax-xogħol f'jum tax-xogħol wieħed. Jagħmel is-sigħat u l-ġranet tax-xogħol komparabbli.",
+ "Working weekdays": "Il-ġranet tax-xogħol tal-ġimgħa",
+ "fixed: a month/day; easter: an offset in days from Easter Sunday; observedShift: a month/day with a required observed shift.": "fixed: xahar u jum; easter: spostament f'ġranet minn Ħadd il-Għid; observedShift: xahar u jum bi trasferiment obbligatorju.",
+ "preBreach fires before the deadline, slaBreached at or after it.": "preBreach jiskatta qabel l-iskadenza, slaBreached fl-iskadenza jew warajha.",
+ "No such task": "M'hemm l-ebda kompitu bħal dan",
+ "The task does not exist, or it is not yours to see.": "Il-kompitu ma jeżistix, jew m'għandekx permess tarah.",
+ "Details": "Dettalji",
+ "Due": "Skadenza",
+ "Assignee": "Assenjat lil",
+ "Requested by": "Mitlub minn",
+ "Outcome": "Riżultat",
+ "Ready to claim": "Lest biex jittieħed",
+ "In progress": "Għaddej",
+ "Terminated": "Itterminat",
+ "Normal": "Normali",
+ "Urgent": "Urġenti",
+ "Overdue by 1 day": "Skadut b'jum 1",
+ "Overdue by {days} days": "Skadut b'{days} ijiem",
+ "Due today": "Skadenza llum",
+ "Due tomorrow": "Skadenza għada",
+ "Due in {days} days": "Skadenza fi {days} ijiem",
+ "Tasks": "Kompiti",
+ "Task": "Kompitu",
+ "Unassigned, open for claiming": "Mhux assenjat, miftuħ biex jittieħed",
+ "Claim": "Ħu",
+ "Complete": "Lesti",
+ "Complete: {outcome}": "Lesti: {outcome}",
+ "Could not load the task": "Ma setax jitgħabba l-kompitu",
+ "The task refused that action": "Il-kompitu rrifjuta dik l-azzjoni"
},
"pluralForm": "nplurals=4; plural=(n==1 ? 0 : n==0 || ( n%100>1 && n%100<11) ? 1 : (n%100>10 && n%100<20 ) ? 2 : 3);",
"plurals": {
diff --git a/l10n/nb.js b/l10n/nb.js
index c000aef543..c862ef2027 100644
--- a/l10n/nb.js
+++ b/l10n/nb.js
@@ -3,11 +3,21 @@ OC.L10N.register(
{
"3": "3",
"30": "30",
+ "from amount {amount}": "fra beløp {amount}",
+ "Gated transition: {transition}": "Overvåket overgang: {transition}",
+ "Each declared chain provisions an ordered task sequence when its transition is attempted. Approvers decide in their task inbox, not here.": "Hver deklarerte kjede åpner en ordnet oppgavesekvens når overgangen forsøkes. Godkjennere beslutter i oppgaveinnboksen sin, ikke her.",
+ "Declare x-openregister-approval-chains on this schema to gate a lifecycle transition on approval.": "Deklarer x-openregister-approval-chains på dette skjemaet for å kreve godkjenning før en livssyklusovergang.",
+ "Approval sequences": "Godkjenningssekvenser",
"%n entries have no hash yet": "%n oppføringer har ennå ingen hash",
"%n entry has no hash yet": "%n oppføring har ennå ingen hash",
"(Dolphin required)": "(Dolphin kreves)",
+ "No approval chains declared": "Ingen godkjenningskjeder deklarert",
"(no subject)": "(ingen emne)",
"(no title)": "(ingen tittel)",
+ "Role {role}": "Rolle {role}",
+ "The transition is applied automatically once every step approves.": "Overgangen tas i bruk automatisk når hvert trinn er godkjent.",
+ "The requester may not decide their own approval.": "Innsenderen kan ikke avgjøre sin egen godkjenning.",
+ "Tier routing on field: {field}": "Trinnvis ruting på feltet: {field}",
"(unnamed)": "(uten navn)",
"(untitled card)": "(kort uten tittel)",
"({count} selected)": "({count} valgt)",
@@ -2738,7 +2748,84 @@ OC.L10N.register(
"_Object successfully deleted_::_Objects successfully deleted_": ["Objekt vellykket slettet","Objekter vellykket slettet"],
"_Purge {count} object from database_::_Purge {count} objects from database_": ["Tøm {count} objekt fra database","Tøm {count} objekter fra database"],
"_Restore {count} object_::_Restore {count} objects_": ["Gjenopprett {count} objekt","Gjenopprett {count} objekter"],
- "_Successfully restored {count} object_::_Successfully restored {count} objects_": ["Vellykket gjenopprettet {count} objekt","Vellykket gjenopprettet {count} objekter"]
+ "_Successfully restored {count} object_::_Successfully restored {count} objects_": ["Vellykket gjenopprettet {count} objekt","Vellykket gjenopprettet {count} objekter"],
+ "A message identity the notification subsystem resolves.": "A message identity the notification subsystem resolves.",
+ "Computed non-working-date rules. kind fixed: {month, day, name, observedShift?: {whenWeekday, days}}. kind easter: {offset, name}, offset in days from Easter Sunday. kind observedShift: a fixed date with a required shift.": "Computed non-working-date rules. kind fixed: {month, day, name, observedShift?: {whenWeekday, days}}. kind easter: {offset, name}, offset in days from Easter Sunday. kind observedShift: a fixed date with a required shift.",
+ "Date": "Date",
+ "Day": "Day",
+ "Day of a fixed or observedShift rule; ignored by an easter rule.": "Day of a fixed or observedShift rule; ignored by an easter rule.",
+ "Days": "Days",
+ "Days from Easter Sunday for an easter rule; ignored by the other kinds.": "Days from Easter Sunday for an easter rule; ignored by the other kinds.",
+ "Distance from the deadline, in the offset unit.": "Distance from the deadline, in the offset unit.",
+ "Enumerated one-off closures as {date, name}. Allowed alongside rules; refused as the whole calendar.": "Enumerated one-off closures as {date, name}. Allowed alongside rules; refused as the whole calendar.",
+ "Escalate to roles": "Escalate to roles",
+ "Escalation ladder": "Escalation ladder",
+ "Exception dates": "Exception dates",
+ "Hours per working day": "Hours per working day",
+ "How many days the observed date shifts, e.g. -1 for the Saturday before.": "How many days the observed date shifts, e.g. -1 for the Saturday before.",
+ "Human-readable title.": "Human-readable title.",
+ "ISO weekdays (1 = Monday, 7 = Sunday) that are working days.": "ISO weekdays (1 = Monday, 7 = Sunday) that are working days.",
+ "Kind": "Kind",
+ "Message": "Message",
+ "Month": "Month",
+ "Month of a fixed or observedShift rule; ignored by an easter rule.": "Month of a fixed or observedShift rule; ignored by an easter rule.",
+ "Non-working-date rules": "Non-working-date rules",
+ "Notify roles": "Notify roles",
+ "Observed shift": "Observed shift",
+ "Offset": "Offset",
+ "Offset unit": "Offset unit",
+ "Open incident": "Open incident",
+ "Optional map from a role name to a concrete recipient descriptor, e.g. {\"teamleader\": \"group:teamleaders\"}. Roles without a binding travel unresolved as role:.": "Optional map from a role name to a concrete recipient descriptor, e.g. {\"teamleader\": \"group:teamleaders\"}. Roles without a binding travel unresolved as role:.",
+ "Optional on a fixed rule, required on observedShift: {whenWeekday: weekday name or ISO 1..7, days: integer}.": "Optional on a fixed rule, required on observedShift: {whenWeekday: weekday name or ISO 1..7, days: integer}.",
+ "Ordered rungs: {key, trigger (preBreach|slaBreached), offset, offsetUnit (hours|businessDays|calendarDays), notifyRole[], escalateToRole[], priority, message, openIncident}.": "Ordered rungs: {key, trigger (preBreach|slaBreached), offset, offsetUnit (hours|businessDays|calendarDays), notifyRole[], escalateToRole[], priority, message, openIncident}.",
+ "Priority": "Priority",
+ "Role bindings": "Role bindings",
+ "Roles the matter is escalated to at this rung.": "Roles the matter is escalated to at this rung.",
+ "Roles told at this rung; handler is the subject's own performer.": "Roles told at this rung; handler is the subject's own performer.",
+ "Rungs": "Rungs",
+ "Stable rung identity, e.g. preBreach:14:calendarDays; derived from trigger, offset and unit when absent.": "Stable rung identity, e.g. preBreach:14:calendarDays; derived from trigger, offset and unit when absent.",
+ "The calendar's stable name, referenced by a timer's calendar_slug.": "The calendar's stable name, referenced by a timer's calendar_slug.",
+ "The closed date, Y-m-d.": "The closed date, Y-m-d.",
+ "The holiday's name.": "The holiday's name.",
+ "The ladder's stable name, referenced by a timer's ladder_slug.": "The ladder's stable name, referenced by a timer's ladder_slug.",
+ "The unit of the offset: the same set the SLA accepts.": "The unit of the offset: the same set the SLA accepts.",
+ "The urgency the raised transition carries.": "The urgency the raised transition carries.",
+ "The weekday (name) on which the date shifts, e.g. sunday for Koningsdag.": "The weekday (name) on which the date shifts, e.g. sunday for Koningsdag.",
+ "UUID of the organisation this calendar is configured for. Empty for a shared calendar. The resolution order picks an organisation's calendar when the timer names none.": "UUID of the organisation this calendar is configured for. Empty for a shared calendar. The resolution order picks an organisation's calendar when the timer names none.",
+ "UUID of the organisation this ladder is the default for. Empty for the shared default.": "UUID of the organisation this ladder is the default for. Empty for the shared default.",
+ "When weekday": "When weekday",
+ "Whether reaching this rung opens an incident.": "Whether reaching this rung opens an incident.",
+ "Why the day is closed.": "Why the day is closed.",
+ "Working calendar": "Working calendar",
+ "Working hours in one working day. Makes hours and businessDays commensurable.": "Working hours in one working day. Makes hours and businessDays commensurable.",
+ "Working weekdays": "Working weekdays",
+ "fixed: a month/day; easter: an offset in days from Easter Sunday; observedShift: a month/day with a required observed shift.": "fixed: a month/day; easter: an offset in days from Easter Sunday; observedShift: a month/day with a required observed shift.",
+ "preBreach fires before the deadline, slaBreached at or after it.": "preBreach fires before the deadline, slaBreached at or after it.",
+ "No such task": "Ingen slik oppgave",
+ "The task does not exist, or it is not yours to see.": "Oppgaven finnes ikke, eller du har ikke tilgang til å se den.",
+ "Details": "Detaljer",
+ "Due": "Frist",
+ "Assignee": "Tildelt",
+ "Requested by": "Forespurt av",
+ "Outcome": "Utfall",
+ "Ready to claim": "Klar til å ta",
+ "In progress": "Pågår",
+ "Terminated": "Avsluttet",
+ "Normal": "Normal",
+ "Urgent": "Haster",
+ "Overdue by 1 day": "1 dag over fristen",
+ "Overdue by {days} days": "{days} dager over fristen",
+ "Due today": "Frist i dag",
+ "Due tomorrow": "Frist i morgen",
+ "Due in {days} days": "Frist om {days} dager",
+ "Tasks": "Oppgaver",
+ "Task": "Oppgave",
+ "Unassigned, open for claiming": "Ikke tildelt, åpen for å ta",
+ "Claim": "Ta",
+ "Complete": "Fullfør",
+ "Complete: {outcome}": "Fullfør: {outcome}",
+ "Could not load the task": "Kunne ikke laste oppgaven",
+ "The task refused that action": "Oppgaven avviste den handlingen"
},
"nplurals=2; plural=(n != 1);"
)
diff --git a/l10n/nb.json b/l10n/nb.json
index 9183612726..add96a63fc 100644
--- a/l10n/nb.json
+++ b/l10n/nb.json
@@ -1,10 +1,20 @@
{
"translations": {
+ "from amount {amount}": "fra beløp {amount}",
+ "Gated transition: {transition}": "Overvåket overgang: {transition}",
+ "Each declared chain provisions an ordered task sequence when its transition is attempted. Approvers decide in their task inbox, not here.": "Hver deklarerte kjede åpner en ordnet oppgavesekvens når overgangen forsøkes. Godkjennere beslutter i oppgaveinnboksen sin, ikke her.",
+ "Declare x-openregister-approval-chains on this schema to gate a lifecycle transition on approval.": "Deklarer x-openregister-approval-chains på dette skjemaet for å kreve godkjenning før en livssyklusovergang.",
+ "Approval sequences": "Godkjenningssekvenser",
"%n entries have no hash yet": "%n oppføringer har ennå ingen hash",
"%n entry has no hash yet": "%n oppføring har ennå ingen hash",
"(Dolphin required)": "(Dolphin kreves)",
+ "No approval chains declared": "Ingen godkjenningskjeder deklarert",
"(no subject)": "(ingen emne)",
"(no title)": "(ingen tittel)",
+ "Role {role}": "Rolle {role}",
+ "The transition is applied automatically once every step approves.": "Overgangen tas i bruk automatisk når hvert trinn er godkjent.",
+ "The requester may not decide their own approval.": "Innsenderen kan ikke avgjøre sin egen godkjenning.",
+ "Tier routing on field: {field}": "Trinnvis ruting på feltet: {field}",
"(unnamed)": "(uten navn)",
"(untitled card)": "(kort uten tittel)",
"({count} selected)": "({count} valgt)",
@@ -2785,7 +2795,84 @@
"_Successfully restored {count} object_::_Successfully restored {count} objects_": [
"Vellykket gjenopprettet {count} objekt",
"Vellykket gjenopprettet {count} objekter"
- ]
+ ],
+ "A message identity the notification subsystem resolves.": "A message identity the notification subsystem resolves.",
+ "Computed non-working-date rules. kind fixed: {month, day, name, observedShift?: {whenWeekday, days}}. kind easter: {offset, name}, offset in days from Easter Sunday. kind observedShift: a fixed date with a required shift.": "Computed non-working-date rules. kind fixed: {month, day, name, observedShift?: {whenWeekday, days}}. kind easter: {offset, name}, offset in days from Easter Sunday. kind observedShift: a fixed date with a required shift.",
+ "Date": "Date",
+ "Day": "Day",
+ "Day of a fixed or observedShift rule; ignored by an easter rule.": "Day of a fixed or observedShift rule; ignored by an easter rule.",
+ "Days": "Days",
+ "Days from Easter Sunday for an easter rule; ignored by the other kinds.": "Days from Easter Sunday for an easter rule; ignored by the other kinds.",
+ "Distance from the deadline, in the offset unit.": "Distance from the deadline, in the offset unit.",
+ "Enumerated one-off closures as {date, name}. Allowed alongside rules; refused as the whole calendar.": "Enumerated one-off closures as {date, name}. Allowed alongside rules; refused as the whole calendar.",
+ "Escalate to roles": "Escalate to roles",
+ "Escalation ladder": "Escalation ladder",
+ "Exception dates": "Exception dates",
+ "Hours per working day": "Hours per working day",
+ "How many days the observed date shifts, e.g. -1 for the Saturday before.": "How many days the observed date shifts, e.g. -1 for the Saturday before.",
+ "Human-readable title.": "Human-readable title.",
+ "ISO weekdays (1 = Monday, 7 = Sunday) that are working days.": "ISO weekdays (1 = Monday, 7 = Sunday) that are working days.",
+ "Kind": "Kind",
+ "Message": "Message",
+ "Month": "Month",
+ "Month of a fixed or observedShift rule; ignored by an easter rule.": "Month of a fixed or observedShift rule; ignored by an easter rule.",
+ "Non-working-date rules": "Non-working-date rules",
+ "Notify roles": "Notify roles",
+ "Observed shift": "Observed shift",
+ "Offset": "Offset",
+ "Offset unit": "Offset unit",
+ "Open incident": "Open incident",
+ "Optional map from a role name to a concrete recipient descriptor, e.g. {\"teamleader\": \"group:teamleaders\"}. Roles without a binding travel unresolved as role:.": "Optional map from a role name to a concrete recipient descriptor, e.g. {\"teamleader\": \"group:teamleaders\"}. Roles without a binding travel unresolved as role:.",
+ "Optional on a fixed rule, required on observedShift: {whenWeekday: weekday name or ISO 1..7, days: integer}.": "Optional on a fixed rule, required on observedShift: {whenWeekday: weekday name or ISO 1..7, days: integer}.",
+ "Ordered rungs: {key, trigger (preBreach|slaBreached), offset, offsetUnit (hours|businessDays|calendarDays), notifyRole[], escalateToRole[], priority, message, openIncident}.": "Ordered rungs: {key, trigger (preBreach|slaBreached), offset, offsetUnit (hours|businessDays|calendarDays), notifyRole[], escalateToRole[], priority, message, openIncident}.",
+ "Priority": "Priority",
+ "Role bindings": "Role bindings",
+ "Roles the matter is escalated to at this rung.": "Roles the matter is escalated to at this rung.",
+ "Roles told at this rung; handler is the subject's own performer.": "Roles told at this rung; handler is the subject's own performer.",
+ "Rungs": "Rungs",
+ "Stable rung identity, e.g. preBreach:14:calendarDays; derived from trigger, offset and unit when absent.": "Stable rung identity, e.g. preBreach:14:calendarDays; derived from trigger, offset and unit when absent.",
+ "The calendar's stable name, referenced by a timer's calendar_slug.": "The calendar's stable name, referenced by a timer's calendar_slug.",
+ "The closed date, Y-m-d.": "The closed date, Y-m-d.",
+ "The holiday's name.": "The holiday's name.",
+ "The ladder's stable name, referenced by a timer's ladder_slug.": "The ladder's stable name, referenced by a timer's ladder_slug.",
+ "The unit of the offset: the same set the SLA accepts.": "The unit of the offset: the same set the SLA accepts.",
+ "The urgency the raised transition carries.": "The urgency the raised transition carries.",
+ "The weekday (name) on which the date shifts, e.g. sunday for Koningsdag.": "The weekday (name) on which the date shifts, e.g. sunday for Koningsdag.",
+ "UUID of the organisation this calendar is configured for. Empty for a shared calendar. The resolution order picks an organisation's calendar when the timer names none.": "UUID of the organisation this calendar is configured for. Empty for a shared calendar. The resolution order picks an organisation's calendar when the timer names none.",
+ "UUID of the organisation this ladder is the default for. Empty for the shared default.": "UUID of the organisation this ladder is the default for. Empty for the shared default.",
+ "When weekday": "When weekday",
+ "Whether reaching this rung opens an incident.": "Whether reaching this rung opens an incident.",
+ "Why the day is closed.": "Why the day is closed.",
+ "Working calendar": "Working calendar",
+ "Working hours in one working day. Makes hours and businessDays commensurable.": "Working hours in one working day. Makes hours and businessDays commensurable.",
+ "Working weekdays": "Working weekdays",
+ "fixed: a month/day; easter: an offset in days from Easter Sunday; observedShift: a month/day with a required observed shift.": "fixed: a month/day; easter: an offset in days from Easter Sunday; observedShift: a month/day with a required observed shift.",
+ "preBreach fires before the deadline, slaBreached at or after it.": "preBreach fires before the deadline, slaBreached at or after it.",
+ "No such task": "Ingen slik oppgave",
+ "The task does not exist, or it is not yours to see.": "Oppgaven finnes ikke, eller du har ikke tilgang til å se den.",
+ "Details": "Detaljer",
+ "Due": "Frist",
+ "Assignee": "Tildelt",
+ "Requested by": "Forespurt av",
+ "Outcome": "Utfall",
+ "Ready to claim": "Klar til å ta",
+ "In progress": "Pågår",
+ "Terminated": "Avsluttet",
+ "Normal": "Normal",
+ "Urgent": "Haster",
+ "Overdue by 1 day": "1 dag over fristen",
+ "Overdue by {days} days": "{days} dager over fristen",
+ "Due today": "Frist i dag",
+ "Due tomorrow": "Frist i morgen",
+ "Due in {days} days": "Frist om {days} dager",
+ "Tasks": "Oppgaver",
+ "Task": "Oppgave",
+ "Unassigned, open for claiming": "Ikke tildelt, åpen for å ta",
+ "Claim": "Ta",
+ "Complete": "Fullfør",
+ "Complete: {outcome}": "Fullfør: {outcome}",
+ "Could not load the task": "Kunne ikke laste oppgaven",
+ "The task refused that action": "Oppgaven avviste den handlingen"
},
"pluralForm": "nplurals=2; plural=(n != 1);",
"plurals": {
diff --git a/l10n/nl.js b/l10n/nl.js
index 8b30f307d0..19de98b4d5 100644
--- a/l10n/nl.js
+++ b/l10n/nl.js
@@ -3,6 +3,16 @@ OC.L10N.register(
{
"3": "3",
"30": "30",
+ "from amount {amount}": "vanaf bedrag {amount}",
+ "Role {role}": "Rol {role}",
+ "The transition is applied automatically once every step approves.": "De overgang wordt automatisch toegepast zodra elke stap is goedgekeurd.",
+ "The requester may not decide their own approval.": "De aanvrager mag niet over de eigen goedkeuring beslissen.",
+ "Tier routing on field: {field}": "Trapsgewijze routering op veld: {field}",
+ "Gated transition: {transition}": "Bewaakte overgang: {transition}",
+ "Each declared chain provisions an ordered task sequence when its transition is attempted. Approvers decide in their task inbox, not here.": "Elke gedeclareerde keten opent een geordende taakreeks zodra de overgang wordt geprobeerd. Goedkeurders beslissen in hun takeninbox, niet hier.",
+ "Declare x-openregister-approval-chains on this schema to gate a lifecycle transition on approval.": "Declareer x-openregister-approval-chains op dit schema om een levenscyclusovergang achter goedkeuring te zetten.",
+ "No approval chains declared": "Geen goedkeuringsketens gedeclareerd",
+ "Approval sequences": "Goedkeuringsreeksen",
"Welcome": "Welkom",
"A short setup to get this app ready. Nothing here is required; you can close it and come back later.": "Een korte installatie om deze app klaar te zetten. Niets hiervan is verplicht; je kunt dit sluiten en later terugkomen.",
"Demo data (optional)": "Demovoorbeelddata (optioneel)",
@@ -2795,7 +2805,84 @@ OC.L10N.register(
"_Object successfully deleted_::_Objects successfully deleted_": ["Object succesvol verwijderd","Objecten succesvol verwijderd"],
"_Purge {count} object from database_::_Purge {count} objects from database_": ["{count} object uit de database wissen","{count} objecten uit de database wissen"],
"_Restore {count} object_::_Restore {count} objects_": ["{count} object herstellen","{count} objecten herstellen"],
- "_Successfully restored {count} object_::_Successfully restored {count} objects_": ["{count} object succesvol hersteld","{count} objecten succesvol hersteld"]
+ "_Successfully restored {count} object_::_Successfully restored {count} objects_": ["{count} object succesvol hersteld","{count} objecten succesvol hersteld"],
+ "Working calendar": "Werkkalender",
+ "Escalation ladder": "Escalatieladder",
+ "Working weekdays": "Werkdagen",
+ "Hours per working day": "Uren per werkdag",
+ "Non-working-date rules": "Regels voor niet-werkdagen",
+ "Exception dates": "Uitzonderingsdagen",
+ "Rungs": "Tredes",
+ "Role bindings": "Rolkoppelingen",
+ "Kind": "Soort",
+ "Month": "Maand",
+ "Day": "Dag",
+ "Offset": "Afstand",
+ "Observed shift": "Verschoven viering",
+ "When weekday": "Bij weekdag",
+ "Days": "Dagen",
+ "Date": "Datum",
+ "Offset unit": "Eenheid van de afstand",
+ "Notify roles": "Te informeren rollen",
+ "Escalate to roles": "Escaleren naar rollen",
+ "Priority": "Prioriteit",
+ "Message": "Bericht",
+ "Open incident": "Incident openen",
+ "The calendar's stable name, referenced by a timer's calendar_slug.": "De vaste naam van de kalender, waarnaar een timer verwijst via calendar_slug.",
+ "Human-readable title.": "Leesbare titel.",
+ "UUID of the organisation this calendar is configured for. Empty for a shared calendar. The resolution order picks an organisation's calendar when the timer names none.": "UUID van de organisatie waarvoor deze kalender is ingesteld. Leeg voor een gedeelde kalender. Noemt de timer geen kalender, dan kiest de resolutievolgorde de kalender van de organisatie.",
+ "ISO weekdays (1 = Monday, 7 = Sunday) that are working days.": "ISO-weekdagen (1 = maandag, 7 = zondag) die werkdagen zijn.",
+ "Working hours in one working day. Makes hours and businessDays commensurable.": "Werkuren in een werkdag. Maakt uren en werkdagen vergelijkbaar.",
+ "Computed non-working-date rules. kind fixed: {month, day, name, observedShift?: {whenWeekday, days}}. kind easter: {offset, name}, offset in days from Easter Sunday. kind observedShift: a fixed date with a required shift.": "Berekende regels voor niet-werkdagen. Soort fixed: {month, day, name, observedShift?: {whenWeekday, days}}. Soort easter: {offset, name}, afstand in dagen vanaf eerste paasdag. Soort observedShift: een vaste datum met een verplichte verschuiving.",
+ "fixed: a month/day; easter: an offset in days from Easter Sunday; observedShift: a month/day with a required observed shift.": "fixed: een maand en dag; easter: een afstand in dagen vanaf eerste paasdag; observedShift: een maand en dag met een verplichte verschuiving.",
+ "The holiday's name.": "De naam van de feestdag.",
+ "Month of a fixed or observedShift rule; ignored by an easter rule.": "Maand van een fixed- of observedShift-regel; een easter-regel negeert dit.",
+ "Day of a fixed or observedShift rule; ignored by an easter rule.": "Dag van een fixed- of observedShift-regel; een easter-regel negeert dit.",
+ "Days from Easter Sunday for an easter rule; ignored by the other kinds.": "Dagen vanaf eerste paasdag voor een easter-regel; de andere soorten negeren dit.",
+ "Optional on a fixed rule, required on observedShift: {whenWeekday: weekday name or ISO 1..7, days: integer}.": "Optioneel bij een fixed-regel, verplicht bij observedShift: {whenWeekday: naam van de weekdag of ISO 1..7, days: geheel getal}.",
+ "The weekday (name) on which the date shifts, e.g. sunday for Koningsdag.": "De weekdag (naam) waarop de datum verschuift, bijvoorbeeld sunday voor Koningsdag.",
+ "How many days the observed date shifts, e.g. -1 for the Saturday before.": "Hoeveel dagen de gevierde datum verschuift, bijvoorbeeld -1 voor de zaterdag ervoor.",
+ "Enumerated one-off closures as {date, name}. Allowed alongside rules; refused as the whole calendar.": "Losse sluitingsdagen als {date, name}. Toegestaan naast regels; geweigerd als de hele kalender.",
+ "The closed date, Y-m-d.": "De gesloten datum, Y-m-d.",
+ "Why the day is closed.": "Waarom deze dag gesloten is.",
+ "The ladder's stable name, referenced by a timer's ladder_slug.": "De vaste naam van de ladder, waarnaar een timer verwijst via ladder_slug.",
+ "UUID of the organisation this ladder is the default for. Empty for the shared default.": "UUID van de organisatie waarvoor deze ladder de standaard is. Leeg voor de gedeelde standaard.",
+ "Ordered rungs: {key, trigger (preBreach|slaBreached), offset, offsetUnit (hours|businessDays|calendarDays), notifyRole[], escalateToRole[], priority, message, openIncident}.": "Geordende tredes: {key, trigger (preBreach|slaBreached), offset, offsetUnit (hours|businessDays|calendarDays), notifyRole[], escalateToRole[], priority, message, openIncident}.",
+ "Stable rung identity, e.g. preBreach:14:calendarDays; derived from trigger, offset and unit when absent.": "Vaste identiteit van de trede, bijvoorbeeld preBreach:14:calendarDays; afgeleid uit aanleiding, afstand en eenheid als die ontbreekt.",
+ "preBreach fires before the deadline, slaBreached at or after it.": "preBreach gaat af voor de termijn verstrijkt, slaBreached op of na dat moment.",
+ "Distance from the deadline, in the offset unit.": "Afstand tot de deadline, in de gekozen eenheid.",
+ "The unit of the offset: the same set the SLA accepts.": "De eenheid van de afstand: dezelfde set die de SLA accepteert.",
+ "Roles told at this rung; handler is the subject's own performer.": "Rollen die bij deze trede worden geinformeerd; handler is de behandelaar van het onderwerp zelf.",
+ "Roles the matter is escalated to at this rung.": "Rollen waarnaar de zaak bij deze trede wordt geescaleerd.",
+ "The urgency the raised transition carries.": "De urgentie die de afgegeven overgang meekrijgt.",
+ "A message identity the notification subsystem resolves.": "Een berichtidentiteit die het notificatiesysteem vertaalt.",
+ "Whether reaching this rung opens an incident.": "Of het bereiken van deze trede een incident opent.",
+ "Optional map from a role name to a concrete recipient descriptor, e.g. {\"teamleader\": \"group:teamleaders\"}. Roles without a binding travel unresolved as role:.": "Optionele koppeling van een rolnaam naar een concrete ontvanger, bijvoorbeeld {\"teamleader\": \"group:teamleaders\"}. Rollen zonder koppeling reizen onvertaald mee als role:.",
+ "No such task": "Geen taak gevonden",
+ "The task does not exist, or it is not yours to see.": "De taak bestaat niet, of u mag deze niet zien.",
+ "Details": "Details",
+ "Due": "Deadline",
+ "Assignee": "Toegewezen aan",
+ "Requested by": "Aangevraagd door",
+ "Outcome": "Uitkomst",
+ "Ready to claim": "Klaar om te claimen",
+ "In progress": "In behandeling",
+ "Terminated": "Beëindigd",
+ "Normal": "Normaal",
+ "Urgent": "Urgent",
+ "Overdue by 1 day": "1 dag te laat",
+ "Overdue by {days} days": "{days} dagen te laat",
+ "Due today": "Vandaag af te ronden",
+ "Due tomorrow": "Morgen af te ronden",
+ "Due in {days} days": "Nog {days} dagen",
+ "Tasks": "Taken",
+ "Task": "Taak",
+ "Unassigned, open for claiming": "Niet toegewezen, open om te claimen",
+ "Claim": "Claimen",
+ "Complete": "Afronden",
+ "Complete: {outcome}": "Afronden: {outcome}",
+ "Could not load the task": "Kon de taak niet laden",
+ "The task refused that action": "De taak weigerde die actie"
},
"nplurals=2; plural=(n != 1);"
)
diff --git a/l10n/nl.json b/l10n/nl.json
index 376401b669..a08c7820c6 100644
--- a/l10n/nl.json
+++ b/l10n/nl.json
@@ -1,5 +1,15 @@
{
"translations": {
+ "from amount {amount}": "vanaf bedrag {amount}",
+ "Role {role}": "Rol {role}",
+ "The transition is applied automatically once every step approves.": "De overgang wordt automatisch toegepast zodra elke stap is goedgekeurd.",
+ "The requester may not decide their own approval.": "De aanvrager mag niet over de eigen goedkeuring beslissen.",
+ "Tier routing on field: {field}": "Trapsgewijze routering op veld: {field}",
+ "Gated transition: {transition}": "Bewaakte overgang: {transition}",
+ "Each declared chain provisions an ordered task sequence when its transition is attempted. Approvers decide in their task inbox, not here.": "Elke gedeclareerde keten opent een geordende taakreeks zodra de overgang wordt geprobeerd. Goedkeurders beslissen in hun takeninbox, niet hier.",
+ "Declare x-openregister-approval-chains on this schema to gate a lifecycle transition on approval.": "Declareer x-openregister-approval-chains op dit schema om een levenscyclusovergang achter goedkeuring te zetten.",
+ "No approval chains declared": "Geen goedkeuringsketens gedeclareerd",
+ "Approval sequences": "Goedkeuringsreeksen",
"Welcome": "Welkom",
"A short setup to get this app ready. Nothing here is required; you can close it and come back later.": "Een korte installatie om deze app klaar te zetten. Niets hiervan is verplicht; je kunt dit sluiten en later terugkomen.",
"Demo data (optional)": "Demovoorbeelddata (optioneel)",
@@ -2842,7 +2852,84 @@
"_Successfully restored {count} object_::_Successfully restored {count} objects_": [
"{count} object succesvol hersteld",
"{count} objecten succesvol hersteld"
- ]
+ ],
+ "Working calendar": "Werkkalender",
+ "Escalation ladder": "Escalatieladder",
+ "Working weekdays": "Werkdagen",
+ "Hours per working day": "Uren per werkdag",
+ "Non-working-date rules": "Regels voor niet-werkdagen",
+ "Exception dates": "Uitzonderingsdagen",
+ "Rungs": "Tredes",
+ "Role bindings": "Rolkoppelingen",
+ "Kind": "Soort",
+ "Month": "Maand",
+ "Day": "Dag",
+ "Offset": "Afstand",
+ "Observed shift": "Verschoven viering",
+ "When weekday": "Bij weekdag",
+ "Days": "Dagen",
+ "Date": "Datum",
+ "Offset unit": "Eenheid van de afstand",
+ "Notify roles": "Te informeren rollen",
+ "Escalate to roles": "Escaleren naar rollen",
+ "Priority": "Prioriteit",
+ "Message": "Bericht",
+ "Open incident": "Incident openen",
+ "The calendar's stable name, referenced by a timer's calendar_slug.": "De vaste naam van de kalender, waarnaar een timer verwijst via calendar_slug.",
+ "Human-readable title.": "Leesbare titel.",
+ "UUID of the organisation this calendar is configured for. Empty for a shared calendar. The resolution order picks an organisation's calendar when the timer names none.": "UUID van de organisatie waarvoor deze kalender is ingesteld. Leeg voor een gedeelde kalender. Noemt de timer geen kalender, dan kiest de resolutievolgorde de kalender van de organisatie.",
+ "ISO weekdays (1 = Monday, 7 = Sunday) that are working days.": "ISO-weekdagen (1 = maandag, 7 = zondag) die werkdagen zijn.",
+ "Working hours in one working day. Makes hours and businessDays commensurable.": "Werkuren in een werkdag. Maakt uren en werkdagen vergelijkbaar.",
+ "Computed non-working-date rules. kind fixed: {month, day, name, observedShift?: {whenWeekday, days}}. kind easter: {offset, name}, offset in days from Easter Sunday. kind observedShift: a fixed date with a required shift.": "Berekende regels voor niet-werkdagen. Soort fixed: {month, day, name, observedShift?: {whenWeekday, days}}. Soort easter: {offset, name}, afstand in dagen vanaf eerste paasdag. Soort observedShift: een vaste datum met een verplichte verschuiving.",
+ "fixed: a month/day; easter: an offset in days from Easter Sunday; observedShift: a month/day with a required observed shift.": "fixed: een maand en dag; easter: een afstand in dagen vanaf eerste paasdag; observedShift: een maand en dag met een verplichte verschuiving.",
+ "The holiday's name.": "De naam van de feestdag.",
+ "Month of a fixed or observedShift rule; ignored by an easter rule.": "Maand van een fixed- of observedShift-regel; een easter-regel negeert dit.",
+ "Day of a fixed or observedShift rule; ignored by an easter rule.": "Dag van een fixed- of observedShift-regel; een easter-regel negeert dit.",
+ "Days from Easter Sunday for an easter rule; ignored by the other kinds.": "Dagen vanaf eerste paasdag voor een easter-regel; de andere soorten negeren dit.",
+ "Optional on a fixed rule, required on observedShift: {whenWeekday: weekday name or ISO 1..7, days: integer}.": "Optioneel bij een fixed-regel, verplicht bij observedShift: {whenWeekday: naam van de weekdag of ISO 1..7, days: geheel getal}.",
+ "The weekday (name) on which the date shifts, e.g. sunday for Koningsdag.": "De weekdag (naam) waarop de datum verschuift, bijvoorbeeld sunday voor Koningsdag.",
+ "How many days the observed date shifts, e.g. -1 for the Saturday before.": "Hoeveel dagen de gevierde datum verschuift, bijvoorbeeld -1 voor de zaterdag ervoor.",
+ "Enumerated one-off closures as {date, name}. Allowed alongside rules; refused as the whole calendar.": "Losse sluitingsdagen als {date, name}. Toegestaan naast regels; geweigerd als de hele kalender.",
+ "The closed date, Y-m-d.": "De gesloten datum, Y-m-d.",
+ "Why the day is closed.": "Waarom deze dag gesloten is.",
+ "The ladder's stable name, referenced by a timer's ladder_slug.": "De vaste naam van de ladder, waarnaar een timer verwijst via ladder_slug.",
+ "UUID of the organisation this ladder is the default for. Empty for the shared default.": "UUID van de organisatie waarvoor deze ladder de standaard is. Leeg voor de gedeelde standaard.",
+ "Ordered rungs: {key, trigger (preBreach|slaBreached), offset, offsetUnit (hours|businessDays|calendarDays), notifyRole[], escalateToRole[], priority, message, openIncident}.": "Geordende tredes: {key, trigger (preBreach|slaBreached), offset, offsetUnit (hours|businessDays|calendarDays), notifyRole[], escalateToRole[], priority, message, openIncident}.",
+ "Stable rung identity, e.g. preBreach:14:calendarDays; derived from trigger, offset and unit when absent.": "Vaste identiteit van de trede, bijvoorbeeld preBreach:14:calendarDays; afgeleid uit aanleiding, afstand en eenheid als die ontbreekt.",
+ "preBreach fires before the deadline, slaBreached at or after it.": "preBreach gaat af voor de termijn verstrijkt, slaBreached op of na dat moment.",
+ "Distance from the deadline, in the offset unit.": "Afstand tot de deadline, in de gekozen eenheid.",
+ "The unit of the offset: the same set the SLA accepts.": "De eenheid van de afstand: dezelfde set die de SLA accepteert.",
+ "Roles told at this rung; handler is the subject's own performer.": "Rollen die bij deze trede worden geinformeerd; handler is de behandelaar van het onderwerp zelf.",
+ "Roles the matter is escalated to at this rung.": "Rollen waarnaar de zaak bij deze trede wordt geescaleerd.",
+ "The urgency the raised transition carries.": "De urgentie die de afgegeven overgang meekrijgt.",
+ "A message identity the notification subsystem resolves.": "Een berichtidentiteit die het notificatiesysteem vertaalt.",
+ "Whether reaching this rung opens an incident.": "Of het bereiken van deze trede een incident opent.",
+ "Optional map from a role name to a concrete recipient descriptor, e.g. {\"teamleader\": \"group:teamleaders\"}. Roles without a binding travel unresolved as role:.": "Optionele koppeling van een rolnaam naar een concrete ontvanger, bijvoorbeeld {\"teamleader\": \"group:teamleaders\"}. Rollen zonder koppeling reizen onvertaald mee als role:.",
+ "No such task": "Geen taak gevonden",
+ "The task does not exist, or it is not yours to see.": "De taak bestaat niet, of u mag deze niet zien.",
+ "Details": "Details",
+ "Due": "Deadline",
+ "Assignee": "Toegewezen aan",
+ "Requested by": "Aangevraagd door",
+ "Outcome": "Uitkomst",
+ "Ready to claim": "Klaar om te claimen",
+ "In progress": "In behandeling",
+ "Terminated": "Beëindigd",
+ "Normal": "Normaal",
+ "Urgent": "Urgent",
+ "Overdue by 1 day": "1 dag te laat",
+ "Overdue by {days} days": "{days} dagen te laat",
+ "Due today": "Vandaag af te ronden",
+ "Due tomorrow": "Morgen af te ronden",
+ "Due in {days} days": "Nog {days} dagen",
+ "Tasks": "Taken",
+ "Task": "Taak",
+ "Unassigned, open for claiming": "Niet toegewezen, open om te claimen",
+ "Claim": "Claimen",
+ "Complete": "Afronden",
+ "Complete: {outcome}": "Afronden: {outcome}",
+ "Could not load the task": "Kon de taak niet laden",
+ "The task refused that action": "De taak weigerde die actie"
},
"pluralForm": "nplurals=2; plural=(n != 1);",
"plurals": {
diff --git a/l10n/pl.js b/l10n/pl.js
index 712ff4b855..18d49a4cec 100644
--- a/l10n/pl.js
+++ b/l10n/pl.js
@@ -3,11 +3,21 @@ OC.L10N.register(
{
"3": "3",
"30": "30",
+ "from amount {amount}": "od kwoty {amount}",
+ "Gated transition: {transition}": "Nadzorowane przejście: {transition}",
+ "Each declared chain provisions an ordered task sequence when its transition is attempted. Approvers decide in their task inbox, not here.": "Każdy zadeklarowany łańcuch otwiera uporządkowaną sekwencję zadań przy próbie przejścia. Zatwierdzający decydują w swojej skrzynce zadań, nie tutaj.",
+ "Declare x-openregister-approval-chains on this schema to gate a lifecycle transition on approval.": "Zadeklaruj x-openregister-approval-chains w tym schemacie, aby przejście cyklu życia wymagało zatwierdzenia.",
+ "Approval sequences": "Sekwencje zatwierdzeń",
"%n entries have no hash yet": "%n wpisów nie ma jeszcze skrótu",
"%n entry has no hash yet": "%n wpis nie ma jeszcze skrótu",
"(Dolphin required)": "(Wymagany Dolphin)",
+ "No approval chains declared": "Nie zadeklarowano łańcuchów zatwierdzeń",
"(no subject)": "(brak tematu)",
"(no title)": "(brak tytułu)",
+ "Role {role}": "Rola {role}",
+ "The transition is applied automatically once every step approves.": "Przejście jest stosowane automatycznie, gdy każdy krok zostanie zatwierdzony.",
+ "The requester may not decide their own approval.": "Wnioskujący nie może decydować o własnym zatwierdzeniu.",
+ "Tier routing on field: {field}": "Routing progowy według pola: {field}",
"(unnamed)": "(bez nazwy)",
"(untitled card)": "(karta bez tytułu)",
"({count} selected)": "(wybrano: {count})",
@@ -2738,7 +2748,84 @@ OC.L10N.register(
"_Object successfully deleted_::_Objects successfully deleted_": ["Obiekt został pomyślnie usunięty","Obiekty zostały pomyślnie usunięte","Obiekty zostały pomyślnie usunięte","Obiekty zostały pomyślnie usunięte"],
"_Purge {count} object from database_::_Purge {count} objects from database_": ["Wyczyść {count} obiekt z bazy danych","Wyczyść {count} obiekty z bazy danych","Wyczyść {count} obiektów z bazy danych","Wyczyść {count} obiektu z bazy danych"],
"_Restore {count} object_::_Restore {count} objects_": ["Przywróć {count} obiekt","Przywróć {count} obiekty","Przywróć {count} obiektów","Przywróć {count} obiektu"],
- "_Successfully restored {count} object_::_Successfully restored {count} objects_": ["Pomyślnie przywrócono {count} obiekt","Pomyślnie przywrócono {count} obiekty","Pomyślnie przywrócono {count} obiektów","Pomyślnie przywrócono {count} obiektu"]
+ "_Successfully restored {count} object_::_Successfully restored {count} objects_": ["Pomyślnie przywrócono {count} obiekt","Pomyślnie przywrócono {count} obiekty","Pomyślnie przywrócono {count} obiektów","Pomyślnie przywrócono {count} obiektu"],
+ "A message identity the notification subsystem resolves.": "A message identity the notification subsystem resolves.",
+ "Computed non-working-date rules. kind fixed: {month, day, name, observedShift?: {whenWeekday, days}}. kind easter: {offset, name}, offset in days from Easter Sunday. kind observedShift: a fixed date with a required shift.": "Computed non-working-date rules. kind fixed: {month, day, name, observedShift?: {whenWeekday, days}}. kind easter: {offset, name}, offset in days from Easter Sunday. kind observedShift: a fixed date with a required shift.",
+ "Date": "Date",
+ "Day": "Day",
+ "Day of a fixed or observedShift rule; ignored by an easter rule.": "Day of a fixed or observedShift rule; ignored by an easter rule.",
+ "Days": "Days",
+ "Days from Easter Sunday for an easter rule; ignored by the other kinds.": "Days from Easter Sunday for an easter rule; ignored by the other kinds.",
+ "Distance from the deadline, in the offset unit.": "Distance from the deadline, in the offset unit.",
+ "Enumerated one-off closures as {date, name}. Allowed alongside rules; refused as the whole calendar.": "Enumerated one-off closures as {date, name}. Allowed alongside rules; refused as the whole calendar.",
+ "Escalate to roles": "Escalate to roles",
+ "Escalation ladder": "Escalation ladder",
+ "Exception dates": "Exception dates",
+ "Hours per working day": "Hours per working day",
+ "How many days the observed date shifts, e.g. -1 for the Saturday before.": "How many days the observed date shifts, e.g. -1 for the Saturday before.",
+ "Human-readable title.": "Human-readable title.",
+ "ISO weekdays (1 = Monday, 7 = Sunday) that are working days.": "ISO weekdays (1 = Monday, 7 = Sunday) that are working days.",
+ "Kind": "Kind",
+ "Message": "Message",
+ "Month": "Month",
+ "Month of a fixed or observedShift rule; ignored by an easter rule.": "Month of a fixed or observedShift rule; ignored by an easter rule.",
+ "Non-working-date rules": "Non-working-date rules",
+ "Notify roles": "Notify roles",
+ "Observed shift": "Observed shift",
+ "Offset": "Offset",
+ "Offset unit": "Offset unit",
+ "Open incident": "Open incident",
+ "Optional map from a role name to a concrete recipient descriptor, e.g. {\"teamleader\": \"group:teamleaders\"}. Roles without a binding travel unresolved as role:.": "Optional map from a role name to a concrete recipient descriptor, e.g. {\"teamleader\": \"group:teamleaders\"}. Roles without a binding travel unresolved as role:.",
+ "Optional on a fixed rule, required on observedShift: {whenWeekday: weekday name or ISO 1..7, days: integer}.": "Optional on a fixed rule, required on observedShift: {whenWeekday: weekday name or ISO 1..7, days: integer}.",
+ "Ordered rungs: {key, trigger (preBreach|slaBreached), offset, offsetUnit (hours|businessDays|calendarDays), notifyRole[], escalateToRole[], priority, message, openIncident}.": "Ordered rungs: {key, trigger (preBreach|slaBreached), offset, offsetUnit (hours|businessDays|calendarDays), notifyRole[], escalateToRole[], priority, message, openIncident}.",
+ "Priority": "Priority",
+ "Role bindings": "Role bindings",
+ "Roles the matter is escalated to at this rung.": "Roles the matter is escalated to at this rung.",
+ "Roles told at this rung; handler is the subject's own performer.": "Roles told at this rung; handler is the subject's own performer.",
+ "Rungs": "Rungs",
+ "Stable rung identity, e.g. preBreach:14:calendarDays; derived from trigger, offset and unit when absent.": "Stable rung identity, e.g. preBreach:14:calendarDays; derived from trigger, offset and unit when absent.",
+ "The calendar's stable name, referenced by a timer's calendar_slug.": "The calendar's stable name, referenced by a timer's calendar_slug.",
+ "The closed date, Y-m-d.": "The closed date, Y-m-d.",
+ "The holiday's name.": "The holiday's name.",
+ "The ladder's stable name, referenced by a timer's ladder_slug.": "The ladder's stable name, referenced by a timer's ladder_slug.",
+ "The unit of the offset: the same set the SLA accepts.": "The unit of the offset: the same set the SLA accepts.",
+ "The urgency the raised transition carries.": "The urgency the raised transition carries.",
+ "The weekday (name) on which the date shifts, e.g. sunday for Koningsdag.": "The weekday (name) on which the date shifts, e.g. sunday for Koningsdag.",
+ "UUID of the organisation this calendar is configured for. Empty for a shared calendar. The resolution order picks an organisation's calendar when the timer names none.": "UUID of the organisation this calendar is configured for. Empty for a shared calendar. The resolution order picks an organisation's calendar when the timer names none.",
+ "UUID of the organisation this ladder is the default for. Empty for the shared default.": "UUID of the organisation this ladder is the default for. Empty for the shared default.",
+ "When weekday": "When weekday",
+ "Whether reaching this rung opens an incident.": "Whether reaching this rung opens an incident.",
+ "Why the day is closed.": "Why the day is closed.",
+ "Working calendar": "Working calendar",
+ "Working hours in one working day. Makes hours and businessDays commensurable.": "Working hours in one working day. Makes hours and businessDays commensurable.",
+ "Working weekdays": "Working weekdays",
+ "fixed: a month/day; easter: an offset in days from Easter Sunday; observedShift: a month/day with a required observed shift.": "fixed: a month/day; easter: an offset in days from Easter Sunday; observedShift: a month/day with a required observed shift.",
+ "preBreach fires before the deadline, slaBreached at or after it.": "preBreach fires before the deadline, slaBreached at or after it.",
+ "No such task": "Nie ma takiego zadania",
+ "The task does not exist, or it is not yours to see.": "Zadanie nie istnieje lub nie masz do niego wglądu.",
+ "Details": "Szczegóły",
+ "Due": "Termin",
+ "Assignee": "Przypisane do",
+ "Requested by": "Zgłoszone przez",
+ "Outcome": "Wynik",
+ "Ready to claim": "Gotowe do przejęcia",
+ "In progress": "W toku",
+ "Terminated": "Zakończone",
+ "Normal": "Normalny",
+ "Urgent": "Pilny",
+ "Overdue by 1 day": "1 dzień po terminie",
+ "Overdue by {days} days": "{days} dni po terminie",
+ "Due today": "Termin dziś",
+ "Due tomorrow": "Termin jutro",
+ "Due in {days} days": "Termin za {days} dni",
+ "Tasks": "Zadania",
+ "Task": "Zadanie",
+ "Unassigned, open for claiming": "Nieprzypisane, można przejąć",
+ "Claim": "Przejmij",
+ "Complete": "Zakończ",
+ "Complete: {outcome}": "Zakończ: {outcome}",
+ "Could not load the task": "Nie można wczytać zadania",
+ "The task refused that action": "Zadanie odrzuciło tę akcję"
},
"nplurals=4; plural=(n==1 ? 0 : (n%10>=2 && n%10<=4) && (n%100<12 || n%100>14) ? 1 : n!=1 && (n%10>=0 && n%10<=1) || (n%10>=5 && n%10<=9) || (n%100>=12 && n%100<=14) ? 2 : 3);"
)
diff --git a/l10n/pl.json b/l10n/pl.json
index e16d8a644b..4f19a079a1 100644
--- a/l10n/pl.json
+++ b/l10n/pl.json
@@ -1,10 +1,20 @@
{
"translations": {
+ "from amount {amount}": "od kwoty {amount}",
+ "Gated transition: {transition}": "Nadzorowane przejście: {transition}",
+ "Each declared chain provisions an ordered task sequence when its transition is attempted. Approvers decide in their task inbox, not here.": "Każdy zadeklarowany łańcuch otwiera uporządkowaną sekwencję zadań przy próbie przejścia. Zatwierdzający decydują w swojej skrzynce zadań, nie tutaj.",
+ "Declare x-openregister-approval-chains on this schema to gate a lifecycle transition on approval.": "Zadeklaruj x-openregister-approval-chains w tym schemacie, aby przejście cyklu życia wymagało zatwierdzenia.",
+ "Approval sequences": "Sekwencje zatwierdzeń",
"%n entries have no hash yet": "%n wpisów nie ma jeszcze skrótu",
"%n entry has no hash yet": "%n wpis nie ma jeszcze skrótu",
"(Dolphin required)": "(Wymagany Dolphin)",
+ "No approval chains declared": "Nie zadeklarowano łańcuchów zatwierdzeń",
"(no subject)": "(brak tematu)",
"(no title)": "(brak tytułu)",
+ "Role {role}": "Rola {role}",
+ "The transition is applied automatically once every step approves.": "Przejście jest stosowane automatycznie, gdy każdy krok zostanie zatwierdzony.",
+ "The requester may not decide their own approval.": "Wnioskujący nie może decydować o własnym zatwierdzeniu.",
+ "Tier routing on field: {field}": "Routing progowy według pola: {field}",
"(unnamed)": "(bez nazwy)",
"(untitled card)": "(karta bez tytułu)",
"({count} selected)": "(wybrano: {count})",
@@ -2817,7 +2827,84 @@
"Pomyślnie przywrócono {count} obiekty",
"Pomyślnie przywrócono {count} obiektów",
"Pomyślnie przywrócono {count} obiektu"
- ]
+ ],
+ "A message identity the notification subsystem resolves.": "A message identity the notification subsystem resolves.",
+ "Computed non-working-date rules. kind fixed: {month, day, name, observedShift?: {whenWeekday, days}}. kind easter: {offset, name}, offset in days from Easter Sunday. kind observedShift: a fixed date with a required shift.": "Computed non-working-date rules. kind fixed: {month, day, name, observedShift?: {whenWeekday, days}}. kind easter: {offset, name}, offset in days from Easter Sunday. kind observedShift: a fixed date with a required shift.",
+ "Date": "Date",
+ "Day": "Day",
+ "Day of a fixed or observedShift rule; ignored by an easter rule.": "Day of a fixed or observedShift rule; ignored by an easter rule.",
+ "Days": "Days",
+ "Days from Easter Sunday for an easter rule; ignored by the other kinds.": "Days from Easter Sunday for an easter rule; ignored by the other kinds.",
+ "Distance from the deadline, in the offset unit.": "Distance from the deadline, in the offset unit.",
+ "Enumerated one-off closures as {date, name}. Allowed alongside rules; refused as the whole calendar.": "Enumerated one-off closures as {date, name}. Allowed alongside rules; refused as the whole calendar.",
+ "Escalate to roles": "Escalate to roles",
+ "Escalation ladder": "Escalation ladder",
+ "Exception dates": "Exception dates",
+ "Hours per working day": "Hours per working day",
+ "How many days the observed date shifts, e.g. -1 for the Saturday before.": "How many days the observed date shifts, e.g. -1 for the Saturday before.",
+ "Human-readable title.": "Human-readable title.",
+ "ISO weekdays (1 = Monday, 7 = Sunday) that are working days.": "ISO weekdays (1 = Monday, 7 = Sunday) that are working days.",
+ "Kind": "Kind",
+ "Message": "Message",
+ "Month": "Month",
+ "Month of a fixed or observedShift rule; ignored by an easter rule.": "Month of a fixed or observedShift rule; ignored by an easter rule.",
+ "Non-working-date rules": "Non-working-date rules",
+ "Notify roles": "Notify roles",
+ "Observed shift": "Observed shift",
+ "Offset": "Offset",
+ "Offset unit": "Offset unit",
+ "Open incident": "Open incident",
+ "Optional map from a role name to a concrete recipient descriptor, e.g. {\"teamleader\": \"group:teamleaders\"}. Roles without a binding travel unresolved as role:.": "Optional map from a role name to a concrete recipient descriptor, e.g. {\"teamleader\": \"group:teamleaders\"}. Roles without a binding travel unresolved as role:.",
+ "Optional on a fixed rule, required on observedShift: {whenWeekday: weekday name or ISO 1..7, days: integer}.": "Optional on a fixed rule, required on observedShift: {whenWeekday: weekday name or ISO 1..7, days: integer}.",
+ "Ordered rungs: {key, trigger (preBreach|slaBreached), offset, offsetUnit (hours|businessDays|calendarDays), notifyRole[], escalateToRole[], priority, message, openIncident}.": "Ordered rungs: {key, trigger (preBreach|slaBreached), offset, offsetUnit (hours|businessDays|calendarDays), notifyRole[], escalateToRole[], priority, message, openIncident}.",
+ "Priority": "Priority",
+ "Role bindings": "Role bindings",
+ "Roles the matter is escalated to at this rung.": "Roles the matter is escalated to at this rung.",
+ "Roles told at this rung; handler is the subject's own performer.": "Roles told at this rung; handler is the subject's own performer.",
+ "Rungs": "Rungs",
+ "Stable rung identity, e.g. preBreach:14:calendarDays; derived from trigger, offset and unit when absent.": "Stable rung identity, e.g. preBreach:14:calendarDays; derived from trigger, offset and unit when absent.",
+ "The calendar's stable name, referenced by a timer's calendar_slug.": "The calendar's stable name, referenced by a timer's calendar_slug.",
+ "The closed date, Y-m-d.": "The closed date, Y-m-d.",
+ "The holiday's name.": "The holiday's name.",
+ "The ladder's stable name, referenced by a timer's ladder_slug.": "The ladder's stable name, referenced by a timer's ladder_slug.",
+ "The unit of the offset: the same set the SLA accepts.": "The unit of the offset: the same set the SLA accepts.",
+ "The urgency the raised transition carries.": "The urgency the raised transition carries.",
+ "The weekday (name) on which the date shifts, e.g. sunday for Koningsdag.": "The weekday (name) on which the date shifts, e.g. sunday for Koningsdag.",
+ "UUID of the organisation this calendar is configured for. Empty for a shared calendar. The resolution order picks an organisation's calendar when the timer names none.": "UUID of the organisation this calendar is configured for. Empty for a shared calendar. The resolution order picks an organisation's calendar when the timer names none.",
+ "UUID of the organisation this ladder is the default for. Empty for the shared default.": "UUID of the organisation this ladder is the default for. Empty for the shared default.",
+ "When weekday": "When weekday",
+ "Whether reaching this rung opens an incident.": "Whether reaching this rung opens an incident.",
+ "Why the day is closed.": "Why the day is closed.",
+ "Working calendar": "Working calendar",
+ "Working hours in one working day. Makes hours and businessDays commensurable.": "Working hours in one working day. Makes hours and businessDays commensurable.",
+ "Working weekdays": "Working weekdays",
+ "fixed: a month/day; easter: an offset in days from Easter Sunday; observedShift: a month/day with a required observed shift.": "fixed: a month/day; easter: an offset in days from Easter Sunday; observedShift: a month/day with a required observed shift.",
+ "preBreach fires before the deadline, slaBreached at or after it.": "preBreach fires before the deadline, slaBreached at or after it.",
+ "No such task": "Nie ma takiego zadania",
+ "The task does not exist, or it is not yours to see.": "Zadanie nie istnieje lub nie masz do niego wglądu.",
+ "Details": "Szczegóły",
+ "Due": "Termin",
+ "Assignee": "Przypisane do",
+ "Requested by": "Zgłoszone przez",
+ "Outcome": "Wynik",
+ "Ready to claim": "Gotowe do przejęcia",
+ "In progress": "W toku",
+ "Terminated": "Zakończone",
+ "Normal": "Normalny",
+ "Urgent": "Pilny",
+ "Overdue by 1 day": "1 dzień po terminie",
+ "Overdue by {days} days": "{days} dni po terminie",
+ "Due today": "Termin dziś",
+ "Due tomorrow": "Termin jutro",
+ "Due in {days} days": "Termin za {days} dni",
+ "Tasks": "Zadania",
+ "Task": "Zadanie",
+ "Unassigned, open for claiming": "Nieprzypisane, można przejąć",
+ "Claim": "Przejmij",
+ "Complete": "Zakończ",
+ "Complete: {outcome}": "Zakończ: {outcome}",
+ "Could not load the task": "Nie można wczytać zadania",
+ "The task refused that action": "Zadanie odrzuciło tę akcję"
},
"pluralForm": "nplurals=4; plural=(n==1 ? 0 : (n%10>=2 && n%10<=4) && (n%100<12 || n%100>14) ? 1 : n!=1 && (n%10>=0 && n%10<=1) || (n%10>=5 && n%10<=9) || (n%100>=12 && n%100<=14) ? 2 : 3);",
"plurals": {
diff --git a/l10n/pt.js b/l10n/pt.js
index 6c9ece4def..aa04c9d465 100644
--- a/l10n/pt.js
+++ b/l10n/pt.js
@@ -3,11 +3,21 @@ OC.L10N.register(
{
"3": "3",
"30": "30",
+ "from amount {amount}": "a partir do montante {amount}",
+ "Gated transition: {transition}": "Transição vigiada: {transition}",
+ "Each declared chain provisions an ordered task sequence when its transition is attempted. Approvers decide in their task inbox, not here.": "Cada cadeia declarada abre uma sequência ordenada de tarefas quando a transição é tentada. Os aprovadores decidem na sua caixa de tarefas, não aqui.",
+ "Declare x-openregister-approval-chains on this schema to gate a lifecycle transition on approval.": "Declare x-openregister-approval-chains neste esquema para condicionar uma transição do ciclo de vida a uma aprovação.",
+ "Approval sequences": "Sequências de aprovação",
"%n entries have no hash yet": "%n entradas ainda não têm hash",
"%n entry has no hash yet": "%n entrada ainda não tem hash",
"(Dolphin required)": "(Dolphin necessário)",
+ "No approval chains declared": "Nenhuma cadeia de aprovação declarada",
"(no subject)": "(sem assunto)",
"(no title)": "(sem título)",
+ "Role {role}": "Função {role}",
+ "The transition is applied automatically once every step approves.": "A transição é aplicada automaticamente assim que cada passo for aprovado.",
+ "The requester may not decide their own approval.": "O requerente não pode decidir sobre a sua própria aprovação.",
+ "Tier routing on field: {field}": "Encaminhamento por escalões no campo: {field}",
"(unnamed)": "(sem nome)",
"(untitled card)": "(cartão sem título)",
"({count} selected)": "({count} selecionados)",
@@ -2738,7 +2748,84 @@ OC.L10N.register(
"_Object successfully deleted_::_Objects successfully deleted_": ["Objeto eliminado com sucesso","Objetos eliminados com sucesso"],
"_Purge {count} object from database_::_Purge {count} objects from database_": ["Expurgar {count} objeto da base de dados","Expurgar {count} objetos da base de dados"],
"_Restore {count} object_::_Restore {count} objects_": ["Restaurar {count} objeto","Restaurar {count} objetos"],
- "_Successfully restored {count} object_::_Successfully restored {count} objects_": ["{count} objeto restaurado com sucesso","{count} objetos restaurados com sucesso"]
+ "_Successfully restored {count} object_::_Successfully restored {count} objects_": ["{count} objeto restaurado com sucesso","{count} objetos restaurados com sucesso"],
+ "A message identity the notification subsystem resolves.": "Uma identidade de mensagem que o sistema de notificações resolve.",
+ "Computed non-working-date rules. kind fixed: {month, day, name, observedShift?: {whenWeekday, days}}. kind easter: {offset, name}, offset in days from Easter Sunday. kind observedShift: a fixed date with a required shift.": "Regras calculadas de dias não úteis. Tipo fixed: {month, day, name, observedShift?: {whenWeekday, days}}. Tipo easter: {offset, name}, deslocamento em dias a partir do Domingo de Páscoa. Tipo observedShift: uma data fixa com transferência obrigatória.",
+ "Date": "Data",
+ "Day": "Dia",
+ "Day of a fixed or observedShift rule; ignored by an easter rule.": "Dia de uma regra fixed ou observedShift; uma regra easter ignora-o.",
+ "Days": "Dias",
+ "Days from Easter Sunday for an easter rule; ignored by the other kinds.": "Dias a partir do Domingo de Páscoa para uma regra easter; os outros tipos ignoram-nos.",
+ "Distance from the deadline, in the offset unit.": "Distância ao prazo, na unidade do deslocamento.",
+ "Enumerated one-off closures as {date, name}. Allowed alongside rules; refused as the whole calendar.": "Encerramentos pontuais enumerados como {date, name}. Permitidos ao lado de regras; recusados como calendário inteiro.",
+ "Escalate to roles": "Papéis de escalonamento",
+ "Escalation ladder": "Escada de escalonamento",
+ "Exception dates": "Datas de exceção",
+ "Hours per working day": "Horas por dia útil",
+ "How many days the observed date shifts, e.g. -1 for the Saturday before.": "Quantos dias a data observada é transferida, p. ex. -1 para o sábado anterior.",
+ "Human-readable title.": "Título legível.",
+ "ISO weekdays (1 = Monday, 7 = Sunday) that are working days.": "Dias ISO da semana (1 = segunda-feira, 7 = domingo) que são úteis.",
+ "Kind": "Tipo",
+ "Message": "Mensagem",
+ "Month": "Mês",
+ "Month of a fixed or observedShift rule; ignored by an easter rule.": "Mês de uma regra fixed ou observedShift; uma regra easter ignora-o.",
+ "Non-working-date rules": "Regras de dias não úteis",
+ "Notify roles": "Papéis a notificar",
+ "Observed shift": "Transferência do feriado",
+ "Offset": "Deslocamento",
+ "Offset unit": "Unidade do deslocamento",
+ "Open incident": "Abrir incidente",
+ "Optional map from a role name to a concrete recipient descriptor, e.g. {\"teamleader\": \"group:teamleaders\"}. Roles without a binding travel unresolved as role:.": "Mapa opcional de um nome de papel para um destinatário concreto, p. ex. {\"teamleader\": \"group:teamleaders\"}. Papéis sem associação seguem por resolver como role:.",
+ "Optional on a fixed rule, required on observedShift: {whenWeekday: weekday name or ISO 1..7, days: integer}.": "Opcional numa regra fixed, obrigatório em observedShift: {whenWeekday: nome do dia ou ISO 1..7, days: inteiro}.",
+ "Ordered rungs: {key, trigger (preBreach|slaBreached), offset, offsetUnit (hours|businessDays|calendarDays), notifyRole[], escalateToRole[], priority, message, openIncident}.": "Degraus ordenados: {key, trigger (preBreach|slaBreached), offset, offsetUnit (hours|businessDays|calendarDays), notifyRole[], escalateToRole[], priority, message, openIncident}.",
+ "Priority": "Prioridade",
+ "Role bindings": "Associações de papéis",
+ "Roles the matter is escalated to at this rung.": "Papéis para os quais o assunto é escalonado neste degrau.",
+ "Roles told at this rung; handler is the subject's own performer.": "Papéis avisados neste degrau; handler é a pessoa responsável pelo assunto.",
+ "Rungs": "Degraus",
+ "Stable rung identity, e.g. preBreach:14:calendarDays; derived from trigger, offset and unit when absent.": "Identidade estável do degrau, p. ex. preBreach:14:calendarDays; quando ausente, deriva do gatilho, do deslocamento e da unidade.",
+ "The calendar's stable name, referenced by a timer's calendar_slug.": "O nome estável do calendário, referenciado pelo calendar_slug de um temporizador.",
+ "The closed date, Y-m-d.": "A data de encerramento, Y-m-d.",
+ "The holiday's name.": "O nome do feriado.",
+ "The ladder's stable name, referenced by a timer's ladder_slug.": "O nome estável da escada, referenciado pelo ladder_slug de um temporizador.",
+ "The unit of the offset: the same set the SLA accepts.": "A unidade do deslocamento: o mesmo conjunto que o SLA aceita.",
+ "The urgency the raised transition carries.": "A urgência transportada pela transição disparada.",
+ "The weekday (name) on which the date shifts, e.g. sunday for Koningsdag.": "O dia da semana (nome) em que a data é transferida, p. ex. sunday para Koningsdag.",
+ "UUID of the organisation this calendar is configured for. Empty for a shared calendar. The resolution order picks an organisation's calendar when the timer names none.": "UUID da organização para a qual este calendário está configurado. Vazio para um calendário partilhado. Se o temporizador não nomear nenhum, a ordem de resolução escolhe o calendário da organização.",
+ "UUID of the organisation this ladder is the default for. Empty for the shared default.": "UUID da organização para a qual esta escada é a predefinida. Vazio para a predefinição partilhada.",
+ "When weekday": "Se calhar a",
+ "Whether reaching this rung opens an incident.": "Se alcançar este degrau abre um incidente.",
+ "Why the day is closed.": "Porque é que o dia está encerrado.",
+ "Working calendar": "Calendário de trabalho",
+ "Working hours in one working day. Makes hours and businessDays commensurable.": "Horas trabalhadas num dia útil. Torna comparáveis horas e dias úteis.",
+ "Working weekdays": "Dias úteis da semana",
+ "fixed: a month/day; easter: an offset in days from Easter Sunday; observedShift: a month/day with a required observed shift.": "fixed: mês e dia; easter: um deslocamento em dias a partir do Domingo de Páscoa; observedShift: mês e dia com transferência obrigatória.",
+ "preBreach fires before the deadline, slaBreached at or after it.": "preBreach dispara antes do prazo, slaBreached no prazo ou depois.",
+ "No such task": "Tarefa não encontrada",
+ "The task does not exist, or it is not yours to see.": "A tarefa não existe ou não tem permissão para a ver.",
+ "Details": "Detalhes",
+ "Due": "Prazo",
+ "Assignee": "Atribuído a",
+ "Requested by": "Solicitado por",
+ "Outcome": "Resultado",
+ "Ready to claim": "Pronto a reclamar",
+ "In progress": "Em curso",
+ "Terminated": "Terminada",
+ "Normal": "Normal",
+ "Urgent": "Urgente",
+ "Overdue by 1 day": "Atrasada 1 dia",
+ "Overdue by {days} days": "Atrasada {days} dias",
+ "Due today": "Prazo hoje",
+ "Due tomorrow": "Prazo amanhã",
+ "Due in {days} days": "Prazo em {days} dias",
+ "Tasks": "Tarefas",
+ "Task": "Tarefa",
+ "Unassigned, open for claiming": "Não atribuída, aberta a reclamação",
+ "Claim": "Reclamar",
+ "Complete": "Concluir",
+ "Complete: {outcome}": "Concluir: {outcome}",
+ "Could not load the task": "Não foi possível carregar a tarefa",
+ "The task refused that action": "A tarefa recusou essa ação"
},
"nplurals=2; plural=(n != 1);"
)
diff --git a/l10n/pt.json b/l10n/pt.json
index 46ef40223a..6a1af21675 100644
--- a/l10n/pt.json
+++ b/l10n/pt.json
@@ -1,10 +1,20 @@
{
"translations": {
+ "from amount {amount}": "a partir do montante {amount}",
+ "Gated transition: {transition}": "Transição vigiada: {transition}",
+ "Each declared chain provisions an ordered task sequence when its transition is attempted. Approvers decide in their task inbox, not here.": "Cada cadeia declarada abre uma sequência ordenada de tarefas quando a transição é tentada. Os aprovadores decidem na sua caixa de tarefas, não aqui.",
+ "Declare x-openregister-approval-chains on this schema to gate a lifecycle transition on approval.": "Declare x-openregister-approval-chains neste esquema para condicionar uma transição do ciclo de vida a uma aprovação.",
+ "Approval sequences": "Sequências de aprovação",
"%n entries have no hash yet": "%n entradas ainda não têm hash",
"%n entry has no hash yet": "%n entrada ainda não tem hash",
"(Dolphin required)": "(Dolphin necessário)",
+ "No approval chains declared": "Nenhuma cadeia de aprovação declarada",
"(no subject)": "(sem assunto)",
"(no title)": "(sem título)",
+ "Role {role}": "Função {role}",
+ "The transition is applied automatically once every step approves.": "A transição é aplicada automaticamente assim que cada passo for aprovado.",
+ "The requester may not decide their own approval.": "O requerente não pode decidir sobre a sua própria aprovação.",
+ "Tier routing on field: {field}": "Encaminhamento por escalões no campo: {field}",
"(unnamed)": "(sem nome)",
"(untitled card)": "(cartão sem título)",
"({count} selected)": "({count} selecionados)",
@@ -2785,7 +2795,84 @@
"_Successfully restored {count} object_::_Successfully restored {count} objects_": [
"{count} objeto restaurado com sucesso",
"{count} objetos restaurados com sucesso"
- ]
+ ],
+ "A message identity the notification subsystem resolves.": "Uma identidade de mensagem que o sistema de notificações resolve.",
+ "Computed non-working-date rules. kind fixed: {month, day, name, observedShift?: {whenWeekday, days}}. kind easter: {offset, name}, offset in days from Easter Sunday. kind observedShift: a fixed date with a required shift.": "Regras calculadas de dias não úteis. Tipo fixed: {month, day, name, observedShift?: {whenWeekday, days}}. Tipo easter: {offset, name}, deslocamento em dias a partir do Domingo de Páscoa. Tipo observedShift: uma data fixa com transferência obrigatória.",
+ "Date": "Data",
+ "Day": "Dia",
+ "Day of a fixed or observedShift rule; ignored by an easter rule.": "Dia de uma regra fixed ou observedShift; uma regra easter ignora-o.",
+ "Days": "Dias",
+ "Days from Easter Sunday for an easter rule; ignored by the other kinds.": "Dias a partir do Domingo de Páscoa para uma regra easter; os outros tipos ignoram-nos.",
+ "Distance from the deadline, in the offset unit.": "Distância ao prazo, na unidade do deslocamento.",
+ "Enumerated one-off closures as {date, name}. Allowed alongside rules; refused as the whole calendar.": "Encerramentos pontuais enumerados como {date, name}. Permitidos ao lado de regras; recusados como calendário inteiro.",
+ "Escalate to roles": "Papéis de escalonamento",
+ "Escalation ladder": "Escada de escalonamento",
+ "Exception dates": "Datas de exceção",
+ "Hours per working day": "Horas por dia útil",
+ "How many days the observed date shifts, e.g. -1 for the Saturday before.": "Quantos dias a data observada é transferida, p. ex. -1 para o sábado anterior.",
+ "Human-readable title.": "Título legível.",
+ "ISO weekdays (1 = Monday, 7 = Sunday) that are working days.": "Dias ISO da semana (1 = segunda-feira, 7 = domingo) que são úteis.",
+ "Kind": "Tipo",
+ "Message": "Mensagem",
+ "Month": "Mês",
+ "Month of a fixed or observedShift rule; ignored by an easter rule.": "Mês de uma regra fixed ou observedShift; uma regra easter ignora-o.",
+ "Non-working-date rules": "Regras de dias não úteis",
+ "Notify roles": "Papéis a notificar",
+ "Observed shift": "Transferência do feriado",
+ "Offset": "Deslocamento",
+ "Offset unit": "Unidade do deslocamento",
+ "Open incident": "Abrir incidente",
+ "Optional map from a role name to a concrete recipient descriptor, e.g. {\"teamleader\": \"group:teamleaders\"}. Roles without a binding travel unresolved as role:.": "Mapa opcional de um nome de papel para um destinatário concreto, p. ex. {\"teamleader\": \"group:teamleaders\"}. Papéis sem associação seguem por resolver como role:.",
+ "Optional on a fixed rule, required on observedShift: {whenWeekday: weekday name or ISO 1..7, days: integer}.": "Opcional numa regra fixed, obrigatório em observedShift: {whenWeekday: nome do dia ou ISO 1..7, days: inteiro}.",
+ "Ordered rungs: {key, trigger (preBreach|slaBreached), offset, offsetUnit (hours|businessDays|calendarDays), notifyRole[], escalateToRole[], priority, message, openIncident}.": "Degraus ordenados: {key, trigger (preBreach|slaBreached), offset, offsetUnit (hours|businessDays|calendarDays), notifyRole[], escalateToRole[], priority, message, openIncident}.",
+ "Priority": "Prioridade",
+ "Role bindings": "Associações de papéis",
+ "Roles the matter is escalated to at this rung.": "Papéis para os quais o assunto é escalonado neste degrau.",
+ "Roles told at this rung; handler is the subject's own performer.": "Papéis avisados neste degrau; handler é a pessoa responsável pelo assunto.",
+ "Rungs": "Degraus",
+ "Stable rung identity, e.g. preBreach:14:calendarDays; derived from trigger, offset and unit when absent.": "Identidade estável do degrau, p. ex. preBreach:14:calendarDays; quando ausente, deriva do gatilho, do deslocamento e da unidade.",
+ "The calendar's stable name, referenced by a timer's calendar_slug.": "O nome estável do calendário, referenciado pelo calendar_slug de um temporizador.",
+ "The closed date, Y-m-d.": "A data de encerramento, Y-m-d.",
+ "The holiday's name.": "O nome do feriado.",
+ "The ladder's stable name, referenced by a timer's ladder_slug.": "O nome estável da escada, referenciado pelo ladder_slug de um temporizador.",
+ "The unit of the offset: the same set the SLA accepts.": "A unidade do deslocamento: o mesmo conjunto que o SLA aceita.",
+ "The urgency the raised transition carries.": "A urgência transportada pela transição disparada.",
+ "The weekday (name) on which the date shifts, e.g. sunday for Koningsdag.": "O dia da semana (nome) em que a data é transferida, p. ex. sunday para Koningsdag.",
+ "UUID of the organisation this calendar is configured for. Empty for a shared calendar. The resolution order picks an organisation's calendar when the timer names none.": "UUID da organização para a qual este calendário está configurado. Vazio para um calendário partilhado. Se o temporizador não nomear nenhum, a ordem de resolução escolhe o calendário da organização.",
+ "UUID of the organisation this ladder is the default for. Empty for the shared default.": "UUID da organização para a qual esta escada é a predefinida. Vazio para a predefinição partilhada.",
+ "When weekday": "Se calhar a",
+ "Whether reaching this rung opens an incident.": "Se alcançar este degrau abre um incidente.",
+ "Why the day is closed.": "Porque é que o dia está encerrado.",
+ "Working calendar": "Calendário de trabalho",
+ "Working hours in one working day. Makes hours and businessDays commensurable.": "Horas trabalhadas num dia útil. Torna comparáveis horas e dias úteis.",
+ "Working weekdays": "Dias úteis da semana",
+ "fixed: a month/day; easter: an offset in days from Easter Sunday; observedShift: a month/day with a required observed shift.": "fixed: mês e dia; easter: um deslocamento em dias a partir do Domingo de Páscoa; observedShift: mês e dia com transferência obrigatória.",
+ "preBreach fires before the deadline, slaBreached at or after it.": "preBreach dispara antes do prazo, slaBreached no prazo ou depois.",
+ "No such task": "Tarefa não encontrada",
+ "The task does not exist, or it is not yours to see.": "A tarefa não existe ou não tem permissão para a ver.",
+ "Details": "Detalhes",
+ "Due": "Prazo",
+ "Assignee": "Atribuído a",
+ "Requested by": "Solicitado por",
+ "Outcome": "Resultado",
+ "Ready to claim": "Pronto a reclamar",
+ "In progress": "Em curso",
+ "Terminated": "Terminada",
+ "Normal": "Normal",
+ "Urgent": "Urgente",
+ "Overdue by 1 day": "Atrasada 1 dia",
+ "Overdue by {days} days": "Atrasada {days} dias",
+ "Due today": "Prazo hoje",
+ "Due tomorrow": "Prazo amanhã",
+ "Due in {days} days": "Prazo em {days} dias",
+ "Tasks": "Tarefas",
+ "Task": "Tarefa",
+ "Unassigned, open for claiming": "Não atribuída, aberta a reclamação",
+ "Claim": "Reclamar",
+ "Complete": "Concluir",
+ "Complete: {outcome}": "Concluir: {outcome}",
+ "Could not load the task": "Não foi possível carregar a tarefa",
+ "The task refused that action": "A tarefa recusou essa ação"
},
"pluralForm": "nplurals=2; plural=(n != 1);",
"plurals": {
diff --git a/l10n/rm.js b/l10n/rm.js
index 4cb1605430..d4a2e9283d 100644
--- a/l10n/rm.js
+++ b/l10n/rm.js
@@ -3,11 +3,21 @@ OC.L10N.register(
{
"3": "3",
"30": "30",
+ "from amount {amount}": "a partir da l'import {amount}",
+ "Gated transition: {transition}": "Transiziun surveglianta: {transition}",
+ "Each declared chain provisions an ordered task sequence when its transition is attempted. Approvers decide in their task inbox, not here.": "Mintga chadaina deklarada avra ina sequenza ordinada da incumbensas cur che la transiziun vegn empruvada. Ils approvaders decidan en lur chascha d'incumbensas, betg qua.",
+ "Declare x-openregister-approval-chains on this schema to gate a lifecycle transition on approval.": "Deklerai x-openregister-approval-chains sin questa schema per che ina transiziun dal ciclus da vita dovria in'approvaziun.",
+ "Approval sequences": "Sequenzas d'approvaziun",
"%n entries have no hash yet": "%n endataziuns n'han anc nagin hash",
"%n entry has no hash yet": "%n endataziun n'ha anc nagin hash",
"(Dolphin required)": "(Dolphin necessário)",
+ "No approval chains declared": "Naginas chadainas d'approvaziun deklaradas",
"(no subject)": "(nagin object)",
"(no title)": "(nagin titel)",
+ "Role {role}": "Rolla {role}",
+ "The transition is applied automatically once every step approves.": "La transiziun vegn applitgada automaticamain uschespert che mintga pass è approvà.",
+ "The requester may not decide their own approval.": "Il petent na dastga betg decider davart sia atgna approvaziun.",
+ "Tier routing on field: {field}": "Rutar a stgalims tenor il champ: {field}",
"(unnamed)": "(nundenominà)",
"(untitled card)": "(charta senza titel)",
"({count} selected)": "({count} selecionados)",
@@ -2738,7 +2748,84 @@ OC.L10N.register(
"_Object successfully deleted_::_Objects successfully deleted_": ["Objeto eliminado com sucesso","Objetos eliminados com sucesso"],
"_Purge {count} object from database_::_Purge {count} objects from database_": ["Expurgar {count} objeto da base de dados","Expurgar {count} objetos da base de dados"],
"_Restore {count} object_::_Restore {count} objects_": ["Restaurar {count} objeto","Restaurar {count} objetos"],
- "_Successfully restored {count} object_::_Successfully restored {count} objects_": ["{count} objeto restaurado com sucesso","{count} objetos restaurados com sucesso"]
+ "_Successfully restored {count} object_::_Successfully restored {count} objects_": ["{count} objeto restaurado com sucesso","{count} objetos restaurados com sucesso"],
+ "A message identity the notification subsystem resolves.": "In'identitad da messadi che il sistem da notificaziuns resolva.",
+ "Computed non-working-date rules. kind fixed: {month, day, name, observedShift?: {whenWeekday, days}}. kind easter: {offset, name}, offset in days from Easter Sunday. kind observedShift: a fixed date with a required shift.": "Reglas calculadas dals dis betg da lavur. Gener fixed: {month, day, name, observedShift?: {whenWeekday, days}}. Gener easter: {offset, name}, spostament en dis a partir da la dumengia da Pasca. Gener observedShift: ina data fixa cun spostament obligatoric.",
+ "Date": "Data",
+ "Day": "Di",
+ "Day of a fixed or observedShift rule; ignored by an easter rule.": "Il di d'ina regla fixed u observedShift; ina regla easter al ignorescha.",
+ "Days": "Dis",
+ "Days from Easter Sunday for an easter rule; ignored by the other kinds.": "Dis a partir da la dumengia da Pasca per ina regla easter; ils auters geners als ignoreschan.",
+ "Distance from the deadline, in the offset unit.": "Distanza dal termin, en l'unitad dal spostament.",
+ "Enumerated one-off closures as {date, name}. Allowed alongside rules; refused as the whole calendar.": "Serradas singulas enumeradas sco {date, name}. Lubidas sper las reglas; refusadas sco l'entir chalender.",
+ "Escalate to roles": "Rollas d'escalaziun",
+ "Escalation ladder": "S-chala d'escalaziun",
+ "Exception dates": "Datas d'excepziun",
+ "Hours per working day": "Uras per di da lavur",
+ "How many days the observed date shifts, e.g. -1 for the Saturday before.": "Quants dis che la data festivada vegn spustada, p.ex. -1 per la sonda avant.",
+ "Human-readable title.": "Titel legibel.",
+ "ISO weekdays (1 = Monday, 7 = Sunday) that are working days.": "Dis ISO da l'emna (1 = glindesdi, 7 = dumengia) che èn dis da lavur.",
+ "Kind": "Gener",
+ "Message": "Messadi",
+ "Month": "Mais",
+ "Month of a fixed or observedShift rule; ignored by an easter rule.": "Il mais d'ina regla fixed u observedShift; ina regla easter al ignorescha.",
+ "Non-working-date rules": "Reglas dals dis betg da lavur",
+ "Notify roles": "Rollas d'infurmar",
+ "Observed shift": "Spostament da la festa",
+ "Offset": "Spostament",
+ "Offset unit": "Unitad dal spostament",
+ "Open incident": "Avrir in incident",
+ "Optional map from a role name to a concrete recipient descriptor, e.g. {\"teamleader\": \"group:teamleaders\"}. Roles without a binding travel unresolved as role:.": "Charta facultativa d'in num da rolla ad in retschavider concret, p.ex. {\"teamleader\": \"group:teamleaders\"}. Rollas senza colliaziun viageschan betg resolvidas sco role:.",
+ "Optional on a fixed rule, required on observedShift: {whenWeekday: weekday name or ISO 1..7, days: integer}.": "Facultativ tar ina regla fixed, obligatoric tar observedShift: {whenWeekday: num dal di u ISO 1..7, days: dumber entir}.",
+ "Ordered rungs: {key, trigger (preBreach|slaBreached), offset, offsetUnit (hours|businessDays|calendarDays), notifyRole[], escalateToRole[], priority, message, openIncident}.": "S-chalims ordinads: {key, trigger (preBreach|slaBreached), offset, offsetUnit (hours|businessDays|calendarDays), notifyRole[], escalateToRole[], priority, message, openIncident}.",
+ "Priority": "Prioritad",
+ "Role bindings": "Colliaziuns da rollas",
+ "Roles the matter is escalated to at this rung.": "Rollas a las qualas il cas vegn escalà sin quest s-chalim.",
+ "Roles told at this rung; handler is the subject's own performer.": "Rollas infurmadas sin quest s-chalim; handler è la persuna che tracta il cas.",
+ "Rungs": "S-chalims",
+ "Stable rung identity, e.g. preBreach:14:calendarDays; derived from trigger, offset and unit when absent.": "Identitad stabila dal s-chalim, p.ex. preBreach:14:calendarDays; sche ella manca, vegn ella derivada da l'impuls, dal spostament e da l'unitad.",
+ "The calendar's stable name, referenced by a timer's calendar_slug.": "Il num stabil dal chalender, al qual in timer sa referescha cun calendar_slug.",
+ "The closed date, Y-m-d.": "La data da la serrada, Y-m-d.",
+ "The holiday's name.": "Il num da la festa.",
+ "The ladder's stable name, referenced by a timer's ladder_slug.": "Il num stabil da la s-chala, a la quala in timer sa referescha cun ladder_slug.",
+ "The unit of the offset: the same set the SLA accepts.": "L'unitad dal spostament: il medem set che il SLA accepta.",
+ "The urgency the raised transition carries.": "L'urgenza che la transiziun activada porta.",
+ "The weekday (name) on which the date shifts, e.g. sunday for Koningsdag.": "Il di da l'emna (num) cura che la data vegn spustada, p.ex. sunday per Koningsdag.",
+ "UUID of the organisation this calendar is configured for. Empty for a shared calendar. The resolution order picks an organisation's calendar when the timer names none.": "UUID da l'organisaziun per la quala quest chalender è configurà. Vid per in chalender cundivis. Sch'il timer na numna nagin, tscherna l'urden da resoluziun il chalender da l'organisaziun.",
+ "UUID of the organisation this ladder is the default for. Empty for the shared default.": "UUID da l'organisaziun per la quala questa s-chala è il standard. Vid per il standard cundivis.",
+ "When weekday": "Sche la data croda sin",
+ "Whether reaching this rung opens an incident.": "Sche cuntanscher quest s-chalim avra in incident.",
+ "Why the day is closed.": "Pertge che quest di è serrà.",
+ "Working calendar": "Chalender da lavur",
+ "Working hours in one working day. Makes hours and businessDays commensurable.": "Uras da lavur en in di da lavur. Renda uras e dis da lavur cumparegliabels.",
+ "Working weekdays": "Dis da lavur da l'emna",
+ "fixed: a month/day; easter: an offset in days from Easter Sunday; observedShift: a month/day with a required observed shift.": "fixed: mais e di; easter: in spostament en dis a partir da la dumengia da Pasca; observedShift: mais e di cun spostament obligatoric.",
+ "preBreach fires before the deadline, slaBreached at or after it.": "preBreach vegn activà avant il termin, slaBreached al termin u suenter.",
+ "No such task": "Nagina tala incumbensa",
+ "The task does not exist, or it is not yours to see.": "L'incumbensa n'exista betg, u Vus na dastgais betg la vesair.",
+ "Details": "Detagls",
+ "Due": "Termin",
+ "Assignee": "Attribuì a",
+ "Requested by": "Dumandà da",
+ "Outcome": "Resultat",
+ "Ready to claim": "Pront per surpigliar",
+ "In progress": "En lavur",
+ "Terminated": "Terminà",
+ "Normal": "Normal",
+ "Urgent": "Urgent",
+ "Overdue by 1 day": "1 di en retard",
+ "Overdue by {days} days": "{days} dis en retard",
+ "Due today": "Termin oz",
+ "Due tomorrow": "Termin damaun",
+ "Due in {days} days": "Termin en {days} dis",
+ "Tasks": "Incumbensas",
+ "Task": "Incumbensa",
+ "Unassigned, open for claiming": "Betg attribuì, avert per surpigliar",
+ "Claim": "Surpigliar",
+ "Complete": "Terminar",
+ "Complete: {outcome}": "Terminar: {outcome}",
+ "Could not load the task": "L'incumbensa n'ha betg pudì vegnir chargiada",
+ "The task refused that action": "L'incumbensa ha refusà questa acziun"
},
"nplurals=2; plural=(n != 1);"
)
diff --git a/l10n/rm.json b/l10n/rm.json
index 7179c58875..c709d862e3 100644
--- a/l10n/rm.json
+++ b/l10n/rm.json
@@ -1,10 +1,20 @@
{
"translations": {
+ "from amount {amount}": "a partir da l'import {amount}",
+ "Gated transition: {transition}": "Transiziun surveglianta: {transition}",
+ "Each declared chain provisions an ordered task sequence when its transition is attempted. Approvers decide in their task inbox, not here.": "Mintga chadaina deklarada avra ina sequenza ordinada da incumbensas cur che la transiziun vegn empruvada. Ils approvaders decidan en lur chascha d'incumbensas, betg qua.",
+ "Declare x-openregister-approval-chains on this schema to gate a lifecycle transition on approval.": "Deklerai x-openregister-approval-chains sin questa schema per che ina transiziun dal ciclus da vita dovria in'approvaziun.",
+ "Approval sequences": "Sequenzas d'approvaziun",
"%n entries have no hash yet": "%n endataziuns n'han anc nagin hash",
"%n entry has no hash yet": "%n endataziun n'ha anc nagin hash",
"(Dolphin required)": "(Dolphin necessário)",
+ "No approval chains declared": "Naginas chadainas d'approvaziun deklaradas",
"(no subject)": "(nagin object)",
"(no title)": "(nagin titel)",
+ "Role {role}": "Rolla {role}",
+ "The transition is applied automatically once every step approves.": "La transiziun vegn applitgada automaticamain uschespert che mintga pass è approvà.",
+ "The requester may not decide their own approval.": "Il petent na dastga betg decider davart sia atgna approvaziun.",
+ "Tier routing on field: {field}": "Rutar a stgalims tenor il champ: {field}",
"(unnamed)": "(nundenominà)",
"(untitled card)": "(charta senza titel)",
"({count} selected)": "({count} selecionados)",
@@ -2785,7 +2795,84 @@
"_Successfully restored {count} object_::_Successfully restored {count} objects_": [
"{count} objeto restaurado com sucesso",
"{count} objetos restaurados com sucesso"
- ]
+ ],
+ "A message identity the notification subsystem resolves.": "In'identitad da messadi che il sistem da notificaziuns resolva.",
+ "Computed non-working-date rules. kind fixed: {month, day, name, observedShift?: {whenWeekday, days}}. kind easter: {offset, name}, offset in days from Easter Sunday. kind observedShift: a fixed date with a required shift.": "Reglas calculadas dals dis betg da lavur. Gener fixed: {month, day, name, observedShift?: {whenWeekday, days}}. Gener easter: {offset, name}, spostament en dis a partir da la dumengia da Pasca. Gener observedShift: ina data fixa cun spostament obligatoric.",
+ "Date": "Data",
+ "Day": "Di",
+ "Day of a fixed or observedShift rule; ignored by an easter rule.": "Il di d'ina regla fixed u observedShift; ina regla easter al ignorescha.",
+ "Days": "Dis",
+ "Days from Easter Sunday for an easter rule; ignored by the other kinds.": "Dis a partir da la dumengia da Pasca per ina regla easter; ils auters geners als ignoreschan.",
+ "Distance from the deadline, in the offset unit.": "Distanza dal termin, en l'unitad dal spostament.",
+ "Enumerated one-off closures as {date, name}. Allowed alongside rules; refused as the whole calendar.": "Serradas singulas enumeradas sco {date, name}. Lubidas sper las reglas; refusadas sco l'entir chalender.",
+ "Escalate to roles": "Rollas d'escalaziun",
+ "Escalation ladder": "S-chala d'escalaziun",
+ "Exception dates": "Datas d'excepziun",
+ "Hours per working day": "Uras per di da lavur",
+ "How many days the observed date shifts, e.g. -1 for the Saturday before.": "Quants dis che la data festivada vegn spustada, p.ex. -1 per la sonda avant.",
+ "Human-readable title.": "Titel legibel.",
+ "ISO weekdays (1 = Monday, 7 = Sunday) that are working days.": "Dis ISO da l'emna (1 = glindesdi, 7 = dumengia) che èn dis da lavur.",
+ "Kind": "Gener",
+ "Message": "Messadi",
+ "Month": "Mais",
+ "Month of a fixed or observedShift rule; ignored by an easter rule.": "Il mais d'ina regla fixed u observedShift; ina regla easter al ignorescha.",
+ "Non-working-date rules": "Reglas dals dis betg da lavur",
+ "Notify roles": "Rollas d'infurmar",
+ "Observed shift": "Spostament da la festa",
+ "Offset": "Spostament",
+ "Offset unit": "Unitad dal spostament",
+ "Open incident": "Avrir in incident",
+ "Optional map from a role name to a concrete recipient descriptor, e.g. {\"teamleader\": \"group:teamleaders\"}. Roles without a binding travel unresolved as role:.": "Charta facultativa d'in num da rolla ad in retschavider concret, p.ex. {\"teamleader\": \"group:teamleaders\"}. Rollas senza colliaziun viageschan betg resolvidas sco role:.",
+ "Optional on a fixed rule, required on observedShift: {whenWeekday: weekday name or ISO 1..7, days: integer}.": "Facultativ tar ina regla fixed, obligatoric tar observedShift: {whenWeekday: num dal di u ISO 1..7, days: dumber entir}.",
+ "Ordered rungs: {key, trigger (preBreach|slaBreached), offset, offsetUnit (hours|businessDays|calendarDays), notifyRole[], escalateToRole[], priority, message, openIncident}.": "S-chalims ordinads: {key, trigger (preBreach|slaBreached), offset, offsetUnit (hours|businessDays|calendarDays), notifyRole[], escalateToRole[], priority, message, openIncident}.",
+ "Priority": "Prioritad",
+ "Role bindings": "Colliaziuns da rollas",
+ "Roles the matter is escalated to at this rung.": "Rollas a las qualas il cas vegn escalà sin quest s-chalim.",
+ "Roles told at this rung; handler is the subject's own performer.": "Rollas infurmadas sin quest s-chalim; handler è la persuna che tracta il cas.",
+ "Rungs": "S-chalims",
+ "Stable rung identity, e.g. preBreach:14:calendarDays; derived from trigger, offset and unit when absent.": "Identitad stabila dal s-chalim, p.ex. preBreach:14:calendarDays; sche ella manca, vegn ella derivada da l'impuls, dal spostament e da l'unitad.",
+ "The calendar's stable name, referenced by a timer's calendar_slug.": "Il num stabil dal chalender, al qual in timer sa referescha cun calendar_slug.",
+ "The closed date, Y-m-d.": "La data da la serrada, Y-m-d.",
+ "The holiday's name.": "Il num da la festa.",
+ "The ladder's stable name, referenced by a timer's ladder_slug.": "Il num stabil da la s-chala, a la quala in timer sa referescha cun ladder_slug.",
+ "The unit of the offset: the same set the SLA accepts.": "L'unitad dal spostament: il medem set che il SLA accepta.",
+ "The urgency the raised transition carries.": "L'urgenza che la transiziun activada porta.",
+ "The weekday (name) on which the date shifts, e.g. sunday for Koningsdag.": "Il di da l'emna (num) cura che la data vegn spustada, p.ex. sunday per Koningsdag.",
+ "UUID of the organisation this calendar is configured for. Empty for a shared calendar. The resolution order picks an organisation's calendar when the timer names none.": "UUID da l'organisaziun per la quala quest chalender è configurà. Vid per in chalender cundivis. Sch'il timer na numna nagin, tscherna l'urden da resoluziun il chalender da l'organisaziun.",
+ "UUID of the organisation this ladder is the default for. Empty for the shared default.": "UUID da l'organisaziun per la quala questa s-chala è il standard. Vid per il standard cundivis.",
+ "When weekday": "Sche la data croda sin",
+ "Whether reaching this rung opens an incident.": "Sche cuntanscher quest s-chalim avra in incident.",
+ "Why the day is closed.": "Pertge che quest di è serrà.",
+ "Working calendar": "Chalender da lavur",
+ "Working hours in one working day. Makes hours and businessDays commensurable.": "Uras da lavur en in di da lavur. Renda uras e dis da lavur cumparegliabels.",
+ "Working weekdays": "Dis da lavur da l'emna",
+ "fixed: a month/day; easter: an offset in days from Easter Sunday; observedShift: a month/day with a required observed shift.": "fixed: mais e di; easter: in spostament en dis a partir da la dumengia da Pasca; observedShift: mais e di cun spostament obligatoric.",
+ "preBreach fires before the deadline, slaBreached at or after it.": "preBreach vegn activà avant il termin, slaBreached al termin u suenter.",
+ "No such task": "Nagina tala incumbensa",
+ "The task does not exist, or it is not yours to see.": "L'incumbensa n'exista betg, u Vus na dastgais betg la vesair.",
+ "Details": "Detagls",
+ "Due": "Termin",
+ "Assignee": "Attribuì a",
+ "Requested by": "Dumandà da",
+ "Outcome": "Resultat",
+ "Ready to claim": "Pront per surpigliar",
+ "In progress": "En lavur",
+ "Terminated": "Terminà",
+ "Normal": "Normal",
+ "Urgent": "Urgent",
+ "Overdue by 1 day": "1 di en retard",
+ "Overdue by {days} days": "{days} dis en retard",
+ "Due today": "Termin oz",
+ "Due tomorrow": "Termin damaun",
+ "Due in {days} days": "Termin en {days} dis",
+ "Tasks": "Incumbensas",
+ "Task": "Incumbensa",
+ "Unassigned, open for claiming": "Betg attribuì, avert per surpigliar",
+ "Claim": "Surpigliar",
+ "Complete": "Terminar",
+ "Complete: {outcome}": "Terminar: {outcome}",
+ "Could not load the task": "L'incumbensa n'ha betg pudì vegnir chargiada",
+ "The task refused that action": "L'incumbensa ha refusà questa acziun"
},
"pluralForm": "nplurals=2; plural=(n != 1);",
"plurals": {
diff --git a/l10n/ro.js b/l10n/ro.js
index 9c7193534d..d8ac06a8a3 100644
--- a/l10n/ro.js
+++ b/l10n/ro.js
@@ -3,11 +3,21 @@ OC.L10N.register(
{
"3": "3",
"30": "30",
+ "from amount {amount}": "de la suma {amount}",
+ "Gated transition: {transition}": "Tranziție supravegheată: {transition}",
+ "Each declared chain provisions an ordered task sequence when its transition is attempted. Approvers decide in their task inbox, not here.": "Fiecare lanț declarat deschide o secvență ordonată de sarcini când tranziția este încercată. Aprobatorii decid în inboxul lor de sarcini, nu aici.",
+ "Declare x-openregister-approval-chains on this schema to gate a lifecycle transition on approval.": "Declarați x-openregister-approval-chains pe această schemă pentru ca o tranziție a ciclului de viață să necesite aprobare.",
+ "Approval sequences": "Secvențe de aprobare",
"%n entries have no hash yet": "%n intrări nu au încă un hash",
"%n entry has no hash yet": "%n intrare nu are încă un hash",
"(Dolphin required)": "(Dolphin necesar)",
+ "No approval chains declared": "Nu sunt declarate lanțuri de aprobare",
"(no subject)": "(fără subiect)",
"(no title)": "(fără titlu)",
+ "Role {role}": "Rol {role}",
+ "The transition is applied automatically once every step approves.": "Tranziția se aplică automat de îndată ce fiecare pas este aprobat.",
+ "The requester may not decide their own approval.": "Solicitantul nu poate decide asupra propriei aprobări.",
+ "Tier routing on field: {field}": "Rutare pe trepte după câmpul: {field}",
"(unnamed)": "(fără nume)",
"(untitled card)": "(card fără titlu)",
"({count} selected)": "({count} selectate)",
@@ -2738,7 +2748,84 @@ OC.L10N.register(
"_Object successfully deleted_::_Objects successfully deleted_": ["Obiectul a fost șters cu succes","Obiectele au fost șterse cu succes","Obiectele au fost șterse cu succes"],
"_Purge {count} object from database_::_Purge {count} objects from database_": ["Epurați {count} obiect din baza de date","Epurați {count} obiecte din baza de date","Epurați {count} de obiecte din baza de date"],
"_Restore {count} object_::_Restore {count} objects_": ["Restaurați {count} obiect","Restaurați {count} obiecte","Restaurați {count} de obiecte"],
- "_Successfully restored {count} object_::_Successfully restored {count} objects_": ["S-a restaurat cu succes {count} obiect","S-au restaurat cu succes {count} obiecte","S-au restaurat cu succes {count} de obiecte"]
+ "_Successfully restored {count} object_::_Successfully restored {count} objects_": ["S-a restaurat cu succes {count} obiect","S-au restaurat cu succes {count} obiecte","S-au restaurat cu succes {count} de obiecte"],
+ "A message identity the notification subsystem resolves.": "O identitate de mesaj pe care o rezolvă sistemul de notificări.",
+ "Computed non-working-date rules. kind fixed: {month, day, name, observedShift?: {whenWeekday, days}}. kind easter: {offset, name}, offset in days from Easter Sunday. kind observedShift: a fixed date with a required shift.": "Reguli calculate pentru zilele nelucrătoare. Fel fixed: {month, day, name, observedShift?: {whenWeekday, days}}. Fel easter: {offset, name}, decalaj în zile de la Duminica Paștelui. Fel observedShift: o dată fixă cu mutare obligatorie.",
+ "Date": "Dată",
+ "Day": "Zi",
+ "Day of a fixed or observedShift rule; ignored by an easter rule.": "Ziua unei reguli fixed sau observedShift; o regulă easter o ignoră.",
+ "Days": "Zile",
+ "Days from Easter Sunday for an easter rule; ignored by the other kinds.": "Zile de la Duminica Paștelui pentru o regulă easter; celelalte feluri le ignoră.",
+ "Distance from the deadline, in the offset unit.": "Distanța până la termen, în unitatea decalajului.",
+ "Enumerated one-off closures as {date, name}. Allowed alongside rules; refused as the whole calendar.": "Închideri punctuale enumerate ca {date, name}. Permise pe lângă reguli; refuzate drept întregul calendar.",
+ "Escalate to roles": "Roluri de escaladare",
+ "Escalation ladder": "Scară de escaladare",
+ "Exception dates": "Date de excepție",
+ "Hours per working day": "Ore pe zi lucrătoare",
+ "How many days the observed date shifts, e.g. -1 for the Saturday before.": "Cu câte zile se mută data sărbătorită, de ex. -1 pentru sâmbăta dinainte.",
+ "Human-readable title.": "Titlu lizibil.",
+ "ISO weekdays (1 = Monday, 7 = Sunday) that are working days.": "Zilele ISO ale săptămânii (1 = luni, 7 = duminică) ce sunt lucrătoare.",
+ "Kind": "Fel",
+ "Message": "Mesaj",
+ "Month": "Lună",
+ "Month of a fixed or observedShift rule; ignored by an easter rule.": "Luna unei reguli fixed sau observedShift; o regulă easter o ignoră.",
+ "Non-working-date rules": "Reguli pentru zilele nelucrătoare",
+ "Notify roles": "Roluri de anunțat",
+ "Observed shift": "Mutarea sărbătorii",
+ "Offset": "Decalaj",
+ "Offset unit": "Unitatea decalajului",
+ "Open incident": "Deschide un incident",
+ "Optional map from a role name to a concrete recipient descriptor, e.g. {\"teamleader\": \"group:teamleaders\"}. Roles without a binding travel unresolved as role:.": "Hartă opțională de la un nume de rol la un destinatar concret, de ex. {\"teamleader\": \"group:teamleaders\"}. Rolurile fără legătură călătoresc nerezolvate ca role:.",
+ "Optional on a fixed rule, required on observedShift: {whenWeekday: weekday name or ISO 1..7, days: integer}.": "Opțional la o regulă fixed, obligatoriu la observedShift: {whenWeekday: numele zilei sau ISO 1..7, days: număr întreg}.",
+ "Ordered rungs: {key, trigger (preBreach|slaBreached), offset, offsetUnit (hours|businessDays|calendarDays), notifyRole[], escalateToRole[], priority, message, openIncident}.": "Trepte ordonate: {key, trigger (preBreach|slaBreached), offset, offsetUnit (hours|businessDays|calendarDays), notifyRole[], escalateToRole[], priority, message, openIncident}.",
+ "Priority": "Prioritate",
+ "Role bindings": "Legături de roluri",
+ "Roles the matter is escalated to at this rung.": "Rolurile către care se escaladează dosarul la această treaptă.",
+ "Roles told at this rung; handler is the subject's own performer.": "Rolurile anunțate la această treaptă; handler este persoana care se ocupă de dosar.",
+ "Rungs": "Trepte",
+ "Stable rung identity, e.g. preBreach:14:calendarDays; derived from trigger, offset and unit when absent.": "Identitatea stabilă a treptei, de ex. preBreach:14:calendarDays; când lipsește, e derivată din declanșator, decalaj și unitate.",
+ "The calendar's stable name, referenced by a timer's calendar_slug.": "Numele stabil al calendarului, referit prin calendar_slug al unui cronometru.",
+ "The closed date, Y-m-d.": "Data închiderii, Y-m-d.",
+ "The holiday's name.": "Numele sărbătorii.",
+ "The ladder's stable name, referenced by a timer's ladder_slug.": "Numele stabil al scării, referit prin ladder_slug al unui cronometru.",
+ "The unit of the offset: the same set the SLA accepts.": "Unitatea decalajului: același set pe care îl acceptă SLA-ul.",
+ "The urgency the raised transition carries.": "Urgența purtată de tranziția declanșată.",
+ "The weekday (name) on which the date shifts, e.g. sunday for Koningsdag.": "Ziua săptămânii (nume) la care data se mută, de ex. sunday pentru Koningsdag.",
+ "UUID of the organisation this calendar is configured for. Empty for a shared calendar. The resolution order picks an organisation's calendar when the timer names none.": "UUID-ul organizației pentru care este configurat acest calendar. Gol pentru un calendar partajat. Dacă cronometrul nu numește niciunul, ordinea de rezolvare alege calendarul organizației.",
+ "UUID of the organisation this ladder is the default for. Empty for the shared default.": "UUID-ul organizației pentru care această scară este implicită. Gol pentru implicitul partajat.",
+ "When weekday": "Dacă pică într-o zi de",
+ "Whether reaching this rung opens an incident.": "Dacă atingerea acestei trepte deschide un incident.",
+ "Why the day is closed.": "De ce este închisă ziua.",
+ "Working calendar": "Calendar de lucru",
+ "Working hours in one working day. Makes hours and businessDays commensurable.": "Ore lucrate într-o zi lucrătoare. Face comparabile orele și zilele lucrătoare.",
+ "Working weekdays": "Zilele lucrătoare ale săptămânii",
+ "fixed: a month/day; easter: an offset in days from Easter Sunday; observedShift: a month/day with a required observed shift.": "fixed: lună și zi; easter: un decalaj în zile de la Duminica Paștelui; observedShift: lună și zi cu mutare obligatorie.",
+ "preBreach fires before the deadline, slaBreached at or after it.": "preBreach se declanșează înaintea termenului, slaBreached la termen sau după.",
+ "No such task": "Nu există o astfel de sarcină",
+ "The task does not exist, or it is not yours to see.": "Sarcina nu există sau nu aveți dreptul să o vedeți.",
+ "Details": "Detalii",
+ "Due": "Scadență",
+ "Assignee": "Atribuit lui",
+ "Requested by": "Solicitat de",
+ "Outcome": "Rezultat",
+ "Ready to claim": "Gata de preluare",
+ "In progress": "În curs",
+ "Terminated": "Încheiată",
+ "Normal": "Normal",
+ "Urgent": "Urgent",
+ "Overdue by 1 day": "Întârziată cu 1 zi",
+ "Overdue by {days} days": "Întârziată cu {days} zile",
+ "Due today": "Scadentă azi",
+ "Due tomorrow": "Scadentă mâine",
+ "Due in {days} days": "Scadentă în {days} zile",
+ "Tasks": "Sarcini",
+ "Task": "Sarcină",
+ "Unassigned, open for claiming": "Neatribuită, deschisă preluării",
+ "Claim": "Preia",
+ "Complete": "Finalizează",
+ "Complete: {outcome}": "Finalizează: {outcome}",
+ "Could not load the task": "Sarcina nu a putut fi încărcată",
+ "The task refused that action": "Sarcina a refuzat această acțiune"
},
"nplurals=3; plural=(n==1?0:(((n%100>19)||((n%100==0)&&(n!=0)))?2:1));"
)
diff --git a/l10n/ro.json b/l10n/ro.json
index 4d4072b2a3..08281b1d04 100644
--- a/l10n/ro.json
+++ b/l10n/ro.json
@@ -1,10 +1,20 @@
{
"translations": {
+ "from amount {amount}": "de la suma {amount}",
+ "Gated transition: {transition}": "Tranziție supravegheată: {transition}",
+ "Each declared chain provisions an ordered task sequence when its transition is attempted. Approvers decide in their task inbox, not here.": "Fiecare lanț declarat deschide o secvență ordonată de sarcini când tranziția este încercată. Aprobatorii decid în inboxul lor de sarcini, nu aici.",
+ "Declare x-openregister-approval-chains on this schema to gate a lifecycle transition on approval.": "Declarați x-openregister-approval-chains pe această schemă pentru ca o tranziție a ciclului de viață să necesite aprobare.",
+ "Approval sequences": "Secvențe de aprobare",
"%n entries have no hash yet": "%n intrări nu au încă un hash",
"%n entry has no hash yet": "%n intrare nu are încă un hash",
"(Dolphin required)": "(Dolphin necesar)",
+ "No approval chains declared": "Nu sunt declarate lanțuri de aprobare",
"(no subject)": "(fără subiect)",
"(no title)": "(fără titlu)",
+ "Role {role}": "Rol {role}",
+ "The transition is applied automatically once every step approves.": "Tranziția se aplică automat de îndată ce fiecare pas este aprobat.",
+ "The requester may not decide their own approval.": "Solicitantul nu poate decide asupra propriei aprobări.",
+ "Tier routing on field: {field}": "Rutare pe trepte după câmpul: {field}",
"(unnamed)": "(fără nume)",
"(untitled card)": "(card fără titlu)",
"({count} selected)": "({count} selectate)",
@@ -2801,7 +2811,84 @@
"S-a restaurat cu succes {count} obiect",
"S-au restaurat cu succes {count} obiecte",
"S-au restaurat cu succes {count} de obiecte"
- ]
+ ],
+ "A message identity the notification subsystem resolves.": "O identitate de mesaj pe care o rezolvă sistemul de notificări.",
+ "Computed non-working-date rules. kind fixed: {month, day, name, observedShift?: {whenWeekday, days}}. kind easter: {offset, name}, offset in days from Easter Sunday. kind observedShift: a fixed date with a required shift.": "Reguli calculate pentru zilele nelucrătoare. Fel fixed: {month, day, name, observedShift?: {whenWeekday, days}}. Fel easter: {offset, name}, decalaj în zile de la Duminica Paștelui. Fel observedShift: o dată fixă cu mutare obligatorie.",
+ "Date": "Dată",
+ "Day": "Zi",
+ "Day of a fixed or observedShift rule; ignored by an easter rule.": "Ziua unei reguli fixed sau observedShift; o regulă easter o ignoră.",
+ "Days": "Zile",
+ "Days from Easter Sunday for an easter rule; ignored by the other kinds.": "Zile de la Duminica Paștelui pentru o regulă easter; celelalte feluri le ignoră.",
+ "Distance from the deadline, in the offset unit.": "Distanța până la termen, în unitatea decalajului.",
+ "Enumerated one-off closures as {date, name}. Allowed alongside rules; refused as the whole calendar.": "Închideri punctuale enumerate ca {date, name}. Permise pe lângă reguli; refuzate drept întregul calendar.",
+ "Escalate to roles": "Roluri de escaladare",
+ "Escalation ladder": "Scară de escaladare",
+ "Exception dates": "Date de excepție",
+ "Hours per working day": "Ore pe zi lucrătoare",
+ "How many days the observed date shifts, e.g. -1 for the Saturday before.": "Cu câte zile se mută data sărbătorită, de ex. -1 pentru sâmbăta dinainte.",
+ "Human-readable title.": "Titlu lizibil.",
+ "ISO weekdays (1 = Monday, 7 = Sunday) that are working days.": "Zilele ISO ale săptămânii (1 = luni, 7 = duminică) ce sunt lucrătoare.",
+ "Kind": "Fel",
+ "Message": "Mesaj",
+ "Month": "Lună",
+ "Month of a fixed or observedShift rule; ignored by an easter rule.": "Luna unei reguli fixed sau observedShift; o regulă easter o ignoră.",
+ "Non-working-date rules": "Reguli pentru zilele nelucrătoare",
+ "Notify roles": "Roluri de anunțat",
+ "Observed shift": "Mutarea sărbătorii",
+ "Offset": "Decalaj",
+ "Offset unit": "Unitatea decalajului",
+ "Open incident": "Deschide un incident",
+ "Optional map from a role name to a concrete recipient descriptor, e.g. {\"teamleader\": \"group:teamleaders\"}. Roles without a binding travel unresolved as role:.": "Hartă opțională de la un nume de rol la un destinatar concret, de ex. {\"teamleader\": \"group:teamleaders\"}. Rolurile fără legătură călătoresc nerezolvate ca role:.",
+ "Optional on a fixed rule, required on observedShift: {whenWeekday: weekday name or ISO 1..7, days: integer}.": "Opțional la o regulă fixed, obligatoriu la observedShift: {whenWeekday: numele zilei sau ISO 1..7, days: număr întreg}.",
+ "Ordered rungs: {key, trigger (preBreach|slaBreached), offset, offsetUnit (hours|businessDays|calendarDays), notifyRole[], escalateToRole[], priority, message, openIncident}.": "Trepte ordonate: {key, trigger (preBreach|slaBreached), offset, offsetUnit (hours|businessDays|calendarDays), notifyRole[], escalateToRole[], priority, message, openIncident}.",
+ "Priority": "Prioritate",
+ "Role bindings": "Legături de roluri",
+ "Roles the matter is escalated to at this rung.": "Rolurile către care se escaladează dosarul la această treaptă.",
+ "Roles told at this rung; handler is the subject's own performer.": "Rolurile anunțate la această treaptă; handler este persoana care se ocupă de dosar.",
+ "Rungs": "Trepte",
+ "Stable rung identity, e.g. preBreach:14:calendarDays; derived from trigger, offset and unit when absent.": "Identitatea stabilă a treptei, de ex. preBreach:14:calendarDays; când lipsește, e derivată din declanșator, decalaj și unitate.",
+ "The calendar's stable name, referenced by a timer's calendar_slug.": "Numele stabil al calendarului, referit prin calendar_slug al unui cronometru.",
+ "The closed date, Y-m-d.": "Data închiderii, Y-m-d.",
+ "The holiday's name.": "Numele sărbătorii.",
+ "The ladder's stable name, referenced by a timer's ladder_slug.": "Numele stabil al scării, referit prin ladder_slug al unui cronometru.",
+ "The unit of the offset: the same set the SLA accepts.": "Unitatea decalajului: același set pe care îl acceptă SLA-ul.",
+ "The urgency the raised transition carries.": "Urgența purtată de tranziția declanșată.",
+ "The weekday (name) on which the date shifts, e.g. sunday for Koningsdag.": "Ziua săptămânii (nume) la care data se mută, de ex. sunday pentru Koningsdag.",
+ "UUID of the organisation this calendar is configured for. Empty for a shared calendar. The resolution order picks an organisation's calendar when the timer names none.": "UUID-ul organizației pentru care este configurat acest calendar. Gol pentru un calendar partajat. Dacă cronometrul nu numește niciunul, ordinea de rezolvare alege calendarul organizației.",
+ "UUID of the organisation this ladder is the default for. Empty for the shared default.": "UUID-ul organizației pentru care această scară este implicită. Gol pentru implicitul partajat.",
+ "When weekday": "Dacă pică într-o zi de",
+ "Whether reaching this rung opens an incident.": "Dacă atingerea acestei trepte deschide un incident.",
+ "Why the day is closed.": "De ce este închisă ziua.",
+ "Working calendar": "Calendar de lucru",
+ "Working hours in one working day. Makes hours and businessDays commensurable.": "Ore lucrate într-o zi lucrătoare. Face comparabile orele și zilele lucrătoare.",
+ "Working weekdays": "Zilele lucrătoare ale săptămânii",
+ "fixed: a month/day; easter: an offset in days from Easter Sunday; observedShift: a month/day with a required observed shift.": "fixed: lună și zi; easter: un decalaj în zile de la Duminica Paștelui; observedShift: lună și zi cu mutare obligatorie.",
+ "preBreach fires before the deadline, slaBreached at or after it.": "preBreach se declanșează înaintea termenului, slaBreached la termen sau după.",
+ "No such task": "Nu există o astfel de sarcină",
+ "The task does not exist, or it is not yours to see.": "Sarcina nu există sau nu aveți dreptul să o vedeți.",
+ "Details": "Detalii",
+ "Due": "Scadență",
+ "Assignee": "Atribuit lui",
+ "Requested by": "Solicitat de",
+ "Outcome": "Rezultat",
+ "Ready to claim": "Gata de preluare",
+ "In progress": "În curs",
+ "Terminated": "Încheiată",
+ "Normal": "Normal",
+ "Urgent": "Urgent",
+ "Overdue by 1 day": "Întârziată cu 1 zi",
+ "Overdue by {days} days": "Întârziată cu {days} zile",
+ "Due today": "Scadentă azi",
+ "Due tomorrow": "Scadentă mâine",
+ "Due in {days} days": "Scadentă în {days} zile",
+ "Tasks": "Sarcini",
+ "Task": "Sarcină",
+ "Unassigned, open for claiming": "Neatribuită, deschisă preluării",
+ "Claim": "Preia",
+ "Complete": "Finalizează",
+ "Complete: {outcome}": "Finalizează: {outcome}",
+ "Could not load the task": "Sarcina nu a putut fi încărcată",
+ "The task refused that action": "Sarcina a refuzat această acțiune"
},
"pluralForm": "nplurals=3; plural=(n==1?0:(((n%100>19)||((n%100==0)&&(n!=0)))?2:1));",
"plurals": {
diff --git a/l10n/ru.js b/l10n/ru.js
index 635bb23f80..6487989365 100644
--- a/l10n/ru.js
+++ b/l10n/ru.js
@@ -3,11 +3,21 @@ OC.L10N.register(
{
"3": "3",
"30": "30",
+ "from amount {amount}": "от суммы {amount}",
+ "Gated transition: {transition}": "Контролируемый переход: {transition}",
+ "Each declared chain provisions an ordered task sequence when its transition is attempted. Approvers decide in their task inbox, not here.": "Каждая объявленная цепочка открывает упорядоченную последовательность задач при попытке перехода. Согласующие решают в своём ящике задач, а не здесь.",
+ "Declare x-openregister-approval-chains on this schema to gate a lifecycle transition on approval.": "Объявите x-openregister-approval-chains в этой схеме, чтобы переход жизненного цикла требовал согласования.",
+ "Approval sequences": "Последовательности согласования",
"%n entries have no hash yet": "%n записей ещё не имеют хеша",
"%n entry has no hash yet": "%n запись ещё не имеет хеша",
"(Dolphin required)": "(требуется Dolphin)",
+ "No approval chains declared": "Цепочки согласования не объявлены",
"(no subject)": "(без темы)",
"(no title)": "(без названия)",
+ "Role {role}": "Роль {role}",
+ "The transition is applied automatically once every step approves.": "Переход применяется автоматически, как только каждый шаг согласован.",
+ "The requester may not decide their own approval.": "Заявитель не может решать по собственному согласованию.",
+ "Tier routing on field: {field}": "Ступенчатая маршрутизация по полю: {field}",
"(unnamed)": "(без имени)",
"(untitled card)": "(карточка без названия)",
"({count} selected)": "({count} выбрано)",
@@ -2738,7 +2748,84 @@ OC.L10N.register(
"_Object successfully deleted_::_Objects successfully deleted_": ["Объект успешно удалён","Объекты успешно удалены","Объекты успешно удалены","Объекты успешно удалены"],
"_Purge {count} object from database_::_Purge {count} objects from database_": ["Очистить {count} объект из базы данных","Очистить {count} объекта из базы данных","Очистить {count} объектов из базы данных","Очистить {count} объекта из базы данных"],
"_Restore {count} object_::_Restore {count} objects_": ["Восстановить {count} объект","Восстановить {count} объекта","Восстановить {count} объектов","Восстановить {count} объекта"],
- "_Successfully restored {count} object_::_Successfully restored {count} objects_": ["Успешно восстановлен {count} объект","Успешно восстановлено {count} объекта","Успешно восстановлено {count} объектов","Успешно восстановлено {count} объекта"]
+ "_Successfully restored {count} object_::_Successfully restored {count} objects_": ["Успешно восстановлен {count} объект","Успешно восстановлено {count} объекта","Успешно восстановлено {count} объектов","Успешно восстановлено {count} объекта"],
+ "A message identity the notification subsystem resolves.": "A message identity the notification subsystem resolves.",
+ "Computed non-working-date rules. kind fixed: {month, day, name, observedShift?: {whenWeekday, days}}. kind easter: {offset, name}, offset in days from Easter Sunday. kind observedShift: a fixed date with a required shift.": "Computed non-working-date rules. kind fixed: {month, day, name, observedShift?: {whenWeekday, days}}. kind easter: {offset, name}, offset in days from Easter Sunday. kind observedShift: a fixed date with a required shift.",
+ "Date": "Date",
+ "Day": "Day",
+ "Day of a fixed or observedShift rule; ignored by an easter rule.": "Day of a fixed or observedShift rule; ignored by an easter rule.",
+ "Days": "Days",
+ "Days from Easter Sunday for an easter rule; ignored by the other kinds.": "Days from Easter Sunday for an easter rule; ignored by the other kinds.",
+ "Distance from the deadline, in the offset unit.": "Distance from the deadline, in the offset unit.",
+ "Enumerated one-off closures as {date, name}. Allowed alongside rules; refused as the whole calendar.": "Enumerated one-off closures as {date, name}. Allowed alongside rules; refused as the whole calendar.",
+ "Escalate to roles": "Escalate to roles",
+ "Escalation ladder": "Escalation ladder",
+ "Exception dates": "Exception dates",
+ "Hours per working day": "Hours per working day",
+ "How many days the observed date shifts, e.g. -1 for the Saturday before.": "How many days the observed date shifts, e.g. -1 for the Saturday before.",
+ "Human-readable title.": "Human-readable title.",
+ "ISO weekdays (1 = Monday, 7 = Sunday) that are working days.": "ISO weekdays (1 = Monday, 7 = Sunday) that are working days.",
+ "Kind": "Kind",
+ "Message": "Message",
+ "Month": "Month",
+ "Month of a fixed or observedShift rule; ignored by an easter rule.": "Month of a fixed or observedShift rule; ignored by an easter rule.",
+ "Non-working-date rules": "Non-working-date rules",
+ "Notify roles": "Notify roles",
+ "Observed shift": "Observed shift",
+ "Offset": "Offset",
+ "Offset unit": "Offset unit",
+ "Open incident": "Open incident",
+ "Optional map from a role name to a concrete recipient descriptor, e.g. {\"teamleader\": \"group:teamleaders\"}. Roles without a binding travel unresolved as role:.": "Optional map from a role name to a concrete recipient descriptor, e.g. {\"teamleader\": \"group:teamleaders\"}. Roles without a binding travel unresolved as role:.",
+ "Optional on a fixed rule, required on observedShift: {whenWeekday: weekday name or ISO 1..7, days: integer}.": "Optional on a fixed rule, required on observedShift: {whenWeekday: weekday name or ISO 1..7, days: integer}.",
+ "Ordered rungs: {key, trigger (preBreach|slaBreached), offset, offsetUnit (hours|businessDays|calendarDays), notifyRole[], escalateToRole[], priority, message, openIncident}.": "Ordered rungs: {key, trigger (preBreach|slaBreached), offset, offsetUnit (hours|businessDays|calendarDays), notifyRole[], escalateToRole[], priority, message, openIncident}.",
+ "Priority": "Priority",
+ "Role bindings": "Role bindings",
+ "Roles the matter is escalated to at this rung.": "Roles the matter is escalated to at this rung.",
+ "Roles told at this rung; handler is the subject's own performer.": "Roles told at this rung; handler is the subject's own performer.",
+ "Rungs": "Rungs",
+ "Stable rung identity, e.g. preBreach:14:calendarDays; derived from trigger, offset and unit when absent.": "Stable rung identity, e.g. preBreach:14:calendarDays; derived from trigger, offset and unit when absent.",
+ "The calendar's stable name, referenced by a timer's calendar_slug.": "The calendar's stable name, referenced by a timer's calendar_slug.",
+ "The closed date, Y-m-d.": "The closed date, Y-m-d.",
+ "The holiday's name.": "The holiday's name.",
+ "The ladder's stable name, referenced by a timer's ladder_slug.": "The ladder's stable name, referenced by a timer's ladder_slug.",
+ "The unit of the offset: the same set the SLA accepts.": "The unit of the offset: the same set the SLA accepts.",
+ "The urgency the raised transition carries.": "The urgency the raised transition carries.",
+ "The weekday (name) on which the date shifts, e.g. sunday for Koningsdag.": "The weekday (name) on which the date shifts, e.g. sunday for Koningsdag.",
+ "UUID of the organisation this calendar is configured for. Empty for a shared calendar. The resolution order picks an organisation's calendar when the timer names none.": "UUID of the organisation this calendar is configured for. Empty for a shared calendar. The resolution order picks an organisation's calendar when the timer names none.",
+ "UUID of the organisation this ladder is the default for. Empty for the shared default.": "UUID of the organisation this ladder is the default for. Empty for the shared default.",
+ "When weekday": "When weekday",
+ "Whether reaching this rung opens an incident.": "Whether reaching this rung opens an incident.",
+ "Why the day is closed.": "Why the day is closed.",
+ "Working calendar": "Working calendar",
+ "Working hours in one working day. Makes hours and businessDays commensurable.": "Working hours in one working day. Makes hours and businessDays commensurable.",
+ "Working weekdays": "Working weekdays",
+ "fixed: a month/day; easter: an offset in days from Easter Sunday; observedShift: a month/day with a required observed shift.": "fixed: a month/day; easter: an offset in days from Easter Sunday; observedShift: a month/day with a required observed shift.",
+ "preBreach fires before the deadline, slaBreached at or after it.": "preBreach fires before the deadline, slaBreached at or after it.",
+ "No such task": "Нет такой задачи",
+ "The task does not exist, or it is not yours to see.": "Задача не существует, или у вас нет права её видеть.",
+ "Details": "Подробности",
+ "Due": "Срок",
+ "Assignee": "Исполнитель",
+ "Requested by": "Запросил",
+ "Outcome": "Результат",
+ "Ready to claim": "Готово к взятию",
+ "In progress": "В работе",
+ "Terminated": "Прекращено",
+ "Normal": "Обычный",
+ "Urgent": "Срочный",
+ "Overdue by 1 day": "Просрочено на 1 день",
+ "Overdue by {days} days": "Просрочено на {days} дн.",
+ "Due today": "Срок сегодня",
+ "Due tomorrow": "Срок завтра",
+ "Due in {days} days": "Срок через {days} дн.",
+ "Tasks": "Задачи",
+ "Task": "Задача",
+ "Unassigned, open for claiming": "Не назначено, можно взять",
+ "Claim": "Взять",
+ "Complete": "Завершить",
+ "Complete: {outcome}": "Завершить: {outcome}",
+ "Could not load the task": "Не удалось загрузить задачу",
+ "The task refused that action": "Задача отклонила это действие"
},
"nplurals=4; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<12 || n%100>14) ? 1 : n%10==0 || (n%10>=5 && n%10<=9) || (n%100>=11 && n%100<=14)? 2 : 3);"
)
diff --git a/l10n/ru.json b/l10n/ru.json
index 8d388540df..6a8d58da27 100644
--- a/l10n/ru.json
+++ b/l10n/ru.json
@@ -1,10 +1,20 @@
{
"translations": {
+ "from amount {amount}": "от суммы {amount}",
+ "Gated transition: {transition}": "Контролируемый переход: {transition}",
+ "Each declared chain provisions an ordered task sequence when its transition is attempted. Approvers decide in their task inbox, not here.": "Каждая объявленная цепочка открывает упорядоченную последовательность задач при попытке перехода. Согласующие решают в своём ящике задач, а не здесь.",
+ "Declare x-openregister-approval-chains on this schema to gate a lifecycle transition on approval.": "Объявите x-openregister-approval-chains в этой схеме, чтобы переход жизненного цикла требовал согласования.",
+ "Approval sequences": "Последовательности согласования",
"%n entries have no hash yet": "%n записей ещё не имеют хеша",
"%n entry has no hash yet": "%n запись ещё не имеет хеша",
"(Dolphin required)": "(требуется Dolphin)",
+ "No approval chains declared": "Цепочки согласования не объявлены",
"(no subject)": "(без темы)",
"(no title)": "(без названия)",
+ "Role {role}": "Роль {role}",
+ "The transition is applied automatically once every step approves.": "Переход применяется автоматически, как только каждый шаг согласован.",
+ "The requester may not decide their own approval.": "Заявитель не может решать по собственному согласованию.",
+ "Tier routing on field: {field}": "Ступенчатая маршрутизация по полю: {field}",
"(unnamed)": "(без имени)",
"(untitled card)": "(карточка без названия)",
"({count} selected)": "({count} выбрано)",
@@ -2817,7 +2827,84 @@
"Успешно восстановлено {count} объекта",
"Успешно восстановлено {count} объектов",
"Успешно восстановлено {count} объекта"
- ]
+ ],
+ "A message identity the notification subsystem resolves.": "A message identity the notification subsystem resolves.",
+ "Computed non-working-date rules. kind fixed: {month, day, name, observedShift?: {whenWeekday, days}}. kind easter: {offset, name}, offset in days from Easter Sunday. kind observedShift: a fixed date with a required shift.": "Computed non-working-date rules. kind fixed: {month, day, name, observedShift?: {whenWeekday, days}}. kind easter: {offset, name}, offset in days from Easter Sunday. kind observedShift: a fixed date with a required shift.",
+ "Date": "Date",
+ "Day": "Day",
+ "Day of a fixed or observedShift rule; ignored by an easter rule.": "Day of a fixed or observedShift rule; ignored by an easter rule.",
+ "Days": "Days",
+ "Days from Easter Sunday for an easter rule; ignored by the other kinds.": "Days from Easter Sunday for an easter rule; ignored by the other kinds.",
+ "Distance from the deadline, in the offset unit.": "Distance from the deadline, in the offset unit.",
+ "Enumerated one-off closures as {date, name}. Allowed alongside rules; refused as the whole calendar.": "Enumerated one-off closures as {date, name}. Allowed alongside rules; refused as the whole calendar.",
+ "Escalate to roles": "Escalate to roles",
+ "Escalation ladder": "Escalation ladder",
+ "Exception dates": "Exception dates",
+ "Hours per working day": "Hours per working day",
+ "How many days the observed date shifts, e.g. -1 for the Saturday before.": "How many days the observed date shifts, e.g. -1 for the Saturday before.",
+ "Human-readable title.": "Human-readable title.",
+ "ISO weekdays (1 = Monday, 7 = Sunday) that are working days.": "ISO weekdays (1 = Monday, 7 = Sunday) that are working days.",
+ "Kind": "Kind",
+ "Message": "Message",
+ "Month": "Month",
+ "Month of a fixed or observedShift rule; ignored by an easter rule.": "Month of a fixed or observedShift rule; ignored by an easter rule.",
+ "Non-working-date rules": "Non-working-date rules",
+ "Notify roles": "Notify roles",
+ "Observed shift": "Observed shift",
+ "Offset": "Offset",
+ "Offset unit": "Offset unit",
+ "Open incident": "Open incident",
+ "Optional map from a role name to a concrete recipient descriptor, e.g. {\"teamleader\": \"group:teamleaders\"}. Roles without a binding travel unresolved as role:.": "Optional map from a role name to a concrete recipient descriptor, e.g. {\"teamleader\": \"group:teamleaders\"}. Roles without a binding travel unresolved as role:.",
+ "Optional on a fixed rule, required on observedShift: {whenWeekday: weekday name or ISO 1..7, days: integer}.": "Optional on a fixed rule, required on observedShift: {whenWeekday: weekday name or ISO 1..7, days: integer}.",
+ "Ordered rungs: {key, trigger (preBreach|slaBreached), offset, offsetUnit (hours|businessDays|calendarDays), notifyRole[], escalateToRole[], priority, message, openIncident}.": "Ordered rungs: {key, trigger (preBreach|slaBreached), offset, offsetUnit (hours|businessDays|calendarDays), notifyRole[], escalateToRole[], priority, message, openIncident}.",
+ "Priority": "Priority",
+ "Role bindings": "Role bindings",
+ "Roles the matter is escalated to at this rung.": "Roles the matter is escalated to at this rung.",
+ "Roles told at this rung; handler is the subject's own performer.": "Roles told at this rung; handler is the subject's own performer.",
+ "Rungs": "Rungs",
+ "Stable rung identity, e.g. preBreach:14:calendarDays; derived from trigger, offset and unit when absent.": "Stable rung identity, e.g. preBreach:14:calendarDays; derived from trigger, offset and unit when absent.",
+ "The calendar's stable name, referenced by a timer's calendar_slug.": "The calendar's stable name, referenced by a timer's calendar_slug.",
+ "The closed date, Y-m-d.": "The closed date, Y-m-d.",
+ "The holiday's name.": "The holiday's name.",
+ "The ladder's stable name, referenced by a timer's ladder_slug.": "The ladder's stable name, referenced by a timer's ladder_slug.",
+ "The unit of the offset: the same set the SLA accepts.": "The unit of the offset: the same set the SLA accepts.",
+ "The urgency the raised transition carries.": "The urgency the raised transition carries.",
+ "The weekday (name) on which the date shifts, e.g. sunday for Koningsdag.": "The weekday (name) on which the date shifts, e.g. sunday for Koningsdag.",
+ "UUID of the organisation this calendar is configured for. Empty for a shared calendar. The resolution order picks an organisation's calendar when the timer names none.": "UUID of the organisation this calendar is configured for. Empty for a shared calendar. The resolution order picks an organisation's calendar when the timer names none.",
+ "UUID of the organisation this ladder is the default for. Empty for the shared default.": "UUID of the organisation this ladder is the default for. Empty for the shared default.",
+ "When weekday": "When weekday",
+ "Whether reaching this rung opens an incident.": "Whether reaching this rung opens an incident.",
+ "Why the day is closed.": "Why the day is closed.",
+ "Working calendar": "Working calendar",
+ "Working hours in one working day. Makes hours and businessDays commensurable.": "Working hours in one working day. Makes hours and businessDays commensurable.",
+ "Working weekdays": "Working weekdays",
+ "fixed: a month/day; easter: an offset in days from Easter Sunday; observedShift: a month/day with a required observed shift.": "fixed: a month/day; easter: an offset in days from Easter Sunday; observedShift: a month/day with a required observed shift.",
+ "preBreach fires before the deadline, slaBreached at or after it.": "preBreach fires before the deadline, slaBreached at or after it.",
+ "No such task": "Нет такой задачи",
+ "The task does not exist, or it is not yours to see.": "Задача не существует, или у вас нет права её видеть.",
+ "Details": "Подробности",
+ "Due": "Срок",
+ "Assignee": "Исполнитель",
+ "Requested by": "Запросил",
+ "Outcome": "Результат",
+ "Ready to claim": "Готово к взятию",
+ "In progress": "В работе",
+ "Terminated": "Прекращено",
+ "Normal": "Обычный",
+ "Urgent": "Срочный",
+ "Overdue by 1 day": "Просрочено на 1 день",
+ "Overdue by {days} days": "Просрочено на {days} дн.",
+ "Due today": "Срок сегодня",
+ "Due tomorrow": "Срок завтра",
+ "Due in {days} days": "Срок через {days} дн.",
+ "Tasks": "Задачи",
+ "Task": "Задача",
+ "Unassigned, open for claiming": "Не назначено, можно взять",
+ "Claim": "Взять",
+ "Complete": "Завершить",
+ "Complete: {outcome}": "Завершить: {outcome}",
+ "Could not load the task": "Не удалось загрузить задачу",
+ "The task refused that action": "Задача отклонила это действие"
},
"pluralForm": "nplurals=4; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<12 || n%100>14) ? 1 : n%10==0 || (n%10>=5 && n%10<=9) || (n%100>=11 && n%100<=14)? 2 : 3);",
"plurals": {
diff --git a/l10n/sk.js b/l10n/sk.js
index f4330cc41d..1be84b03a1 100644
--- a/l10n/sk.js
+++ b/l10n/sk.js
@@ -3,11 +3,21 @@ OC.L10N.register(
{
"3": "3",
"30": "30",
+ "from amount {amount}": "od sumy {amount}",
+ "Gated transition: {transition}": "Strážený prechod: {transition}",
+ "Each declared chain provisions an ordered task sequence when its transition is attempted. Approvers decide in their task inbox, not here.": "Každý deklarovaný reťazec otvorí usporiadanú sekvenciu úloh pri pokuse o prechod. Schvaľovatelia rozhodujú vo svojej schránke úloh, nie tu.",
+ "Declare x-openregister-approval-chains on this schema to gate a lifecycle transition on approval.": "Deklarujte x-openregister-approval-chains na tejto schéme, aby prechod životného cyklu podliehal schváleniu.",
+ "Approval sequences": "Schvaľovacie sekvencie",
"%n entries have no hash yet": "%n záznamov zatiaľ nemá odtlačok",
"%n entry has no hash yet": "%n záznam zatiaľ nemá odtlačok",
"(Dolphin required)": "(vyžaduje sa Dolphin)",
+ "No approval chains declared": "Nie sú deklarované žiadne schvaľovacie reťazce",
"(no subject)": "(bez predmetu)",
"(no title)": "(bez názvu)",
+ "Role {role}": "Rola {role}",
+ "The transition is applied automatically once every step approves.": "Prechod sa použije automaticky, len čo je každý krok schválený.",
+ "The requester may not decide their own approval.": "Žiadateľ nesmie rozhodovať o vlastnom schválení.",
+ "Tier routing on field: {field}": "Smerovanie podľa pásiem cez pole: {field}",
"(unnamed)": "(bez názvu)",
"(untitled card)": "(karta bez názvu)",
"({count} selected)": "(vybrané: {count})",
@@ -2738,7 +2748,84 @@ OC.L10N.register(
"_Object successfully deleted_::_Objects successfully deleted_": ["Objekt bol úspešne odstránený","Objekty boli úspešne odstránené","Objekty boli úspešne odstránené","Objekty boli úspešne odstránené"],
"_Purge {count} object from database_::_Purge {count} objects from database_": ["Vymazať {count} objekt z databázy","Vymazať {count} objekty z databázy","Vymazať {count} objektu z databázy","Vymazať {count} objektov z databázy"],
"_Restore {count} object_::_Restore {count} objects_": ["Obnoviť {count} objekt","Obnoviť {count} objekty","Obnoviť {count} objektu","Obnoviť {count} objektov"],
- "_Successfully restored {count} object_::_Successfully restored {count} objects_": ["Úspešne obnovený {count} objekt","Úspešne obnovené {count} objekty","Úspešne obnovených {count} objektu","Úspešne obnovených {count} objektov"]
+ "_Successfully restored {count} object_::_Successfully restored {count} objects_": ["Úspešne obnovený {count} objekt","Úspešne obnovené {count} objekty","Úspešne obnovených {count} objektu","Úspešne obnovených {count} objektov"],
+ "A message identity the notification subsystem resolves.": "Identita správy, ktorú rozlíši systém upozornení.",
+ "Computed non-working-date rules. kind fixed: {month, day, name, observedShift?: {whenWeekday, days}}. kind easter: {offset, name}, offset in days from Easter Sunday. kind observedShift: a fixed date with a required shift.": "Vypočítané pravidlá nepracovných dní. Druh fixed: {month, day, name, observedShift?: {whenWeekday, days}}. Druh easter: {offset, name}, odstup v dňoch od Veľkonočnej nedele. Druh observedShift: pevný dátum s povinným presunom.",
+ "Date": "Dátum",
+ "Day": "Deň",
+ "Day of a fixed or observedShift rule; ignored by an easter rule.": "Deň pravidla fixed alebo observedShift; pravidlo easter ho ignoruje.",
+ "Days": "Dni",
+ "Days from Easter Sunday for an easter rule; ignored by the other kinds.": "Dni od Veľkonočnej nedele pre pravidlo easter; ostatné druhy ich ignorujú.",
+ "Distance from the deadline, in the offset unit.": "Vzdialenosť od lehoty v jednotke odstupu.",
+ "Enumerated one-off closures as {date, name}. Allowed alongside rules; refused as the whole calendar.": "Jednorazové zatvorenia vymenované ako {date, name}. Povolené popri pravidlách; odmietnuté ako celý kalendár.",
+ "Escalate to roles": "Roly pre eskaláciu",
+ "Escalation ladder": "Eskalačný rebrík",
+ "Exception dates": "Výnimočné dátumy",
+ "Hours per working day": "Hodín na pracovný deň",
+ "How many days the observed date shifts, e.g. -1 for the Saturday before.": "O koľko dní sa slávený dátum presunie, napr. -1 pre predchádzajúcu sobotu.",
+ "Human-readable title.": "Čitateľný názov.",
+ "ISO weekdays (1 = Monday, 7 = Sunday) that are working days.": "ISO dni v týždni (1 = pondelok, 7 = nedeľa), ktoré sú pracovné.",
+ "Kind": "Druh",
+ "Message": "Správa",
+ "Month": "Mesiac",
+ "Month of a fixed or observedShift rule; ignored by an easter rule.": "Mesiac pravidla fixed alebo observedShift; pravidlo easter ho ignoruje.",
+ "Non-working-date rules": "Pravidlá nepracovných dní",
+ "Notify roles": "Roly na upozornenie",
+ "Observed shift": "Presun sviatku",
+ "Offset": "Odstup",
+ "Offset unit": "Jednotka odstupu",
+ "Open incident": "Otvoriť incident",
+ "Optional map from a role name to a concrete recipient descriptor, e.g. {\"teamleader\": \"group:teamleaders\"}. Roles without a binding travel unresolved as role:.": "Voliteľná mapa z názvu roly na konkrétneho príjemcu, napr. {\"teamleader\": \"group:teamleaders\"}. Roly bez väzby putujú nerozlíšené ako role:.",
+ "Optional on a fixed rule, required on observedShift: {whenWeekday: weekday name or ISO 1..7, days: integer}.": "Voliteľné pri pravidle fixed, povinné pri observedShift: {whenWeekday: názov dňa alebo ISO 1..7, days: celé číslo}.",
+ "Ordered rungs: {key, trigger (preBreach|slaBreached), offset, offsetUnit (hours|businessDays|calendarDays), notifyRole[], escalateToRole[], priority, message, openIncident}.": "Zoradené priečky: {key, trigger (preBreach|slaBreached), offset, offsetUnit (hours|businessDays|calendarDays), notifyRole[], escalateToRole[], priority, message, openIncident}.",
+ "Priority": "Priorita",
+ "Role bindings": "Väzby rolí",
+ "Roles the matter is escalated to at this rung.": "Roly, na ktoré sa vec na tejto priečke eskaluje.",
+ "Roles told at this rung; handler is the subject's own performer.": "Roly upozornené na tejto priečke; handler je osoba, ktorá vec vybavuje.",
+ "Rungs": "Priečky",
+ "Stable rung identity, e.g. preBreach:14:calendarDays; derived from trigger, offset and unit when absent.": "Stála identita priečky, napr. preBreach:14:calendarDays; ak chýba, odvodí sa zo spúšťača, odstupu a jednotky.",
+ "The calendar's stable name, referenced by a timer's calendar_slug.": "Stály názov kalendára, na ktorý časovač odkazuje cez calendar_slug.",
+ "The closed date, Y-m-d.": "Dátum zatvorenia, Y-m-d.",
+ "The holiday's name.": "Názov sviatku.",
+ "The ladder's stable name, referenced by a timer's ladder_slug.": "Stály názov rebríka, na ktorý časovač odkazuje cez ladder_slug.",
+ "The unit of the offset: the same set the SLA accepts.": "Jednotka odstupu: rovnaká množina, akú prijíma SLA.",
+ "The urgency the raised transition carries.": "Naliehavosť, ktorú nesie vyvolaný prechod.",
+ "The weekday (name) on which the date shifts, e.g. sunday for Koningsdag.": "Deň v týždni (názov), pri ktorom sa dátum presunie, napr. sunday pre Koningsdag.",
+ "UUID of the organisation this calendar is configured for. Empty for a shared calendar. The resolution order picks an organisation's calendar when the timer names none.": "UUID organizácie, pre ktorú je tento kalendár nastavený. Prázdne pri zdieľanom kalendári. Ak časovač žiadny nemenuje, poradie rozlíšenia vyberie kalendár organizácie.",
+ "UUID of the organisation this ladder is the default for. Empty for the shared default.": "UUID organizácie, pre ktorú je tento rebrík predvolený. Prázdne pri zdieľanom predvolenom.",
+ "When weekday": "Ak pripadne na",
+ "Whether reaching this rung opens an incident.": "Či dosiahnutie tejto priečky otvorí incident.",
+ "Why the day is closed.": "Prečo je deň zatvorený.",
+ "Working calendar": "Pracovný kalendár",
+ "Working hours in one working day. Makes hours and businessDays commensurable.": "Odpracované hodiny v jednom pracovnom dni. Robí hodiny a pracovné dni porovnateľnými.",
+ "Working weekdays": "Pracovné dni v týždni",
+ "fixed: a month/day; easter: an offset in days from Easter Sunday; observedShift: a month/day with a required observed shift.": "fixed: mesiac a deň; easter: odstup v dňoch od Veľkonočnej nedele; observedShift: mesiac a deň s povinným presunom.",
+ "preBreach fires before the deadline, slaBreached at or after it.": "preBreach sa spúšťa pred lehotou, slaBreached v lehote alebo po nej.",
+ "No such task": "Žiadna taká úloha",
+ "The task does not exist, or it is not yours to see.": "Úloha neexistuje, alebo ju nesmiete vidieť.",
+ "Details": "Podrobnosti",
+ "Due": "Termín",
+ "Assignee": "Priradené",
+ "Requested by": "Vyžiadal",
+ "Outcome": "Výsledok",
+ "Ready to claim": "Pripravené na prevzatie",
+ "In progress": "Prebieha",
+ "Terminated": "Ukončené",
+ "Normal": "Normálna",
+ "Urgent": "Naliehavé",
+ "Overdue by 1 day": "1 deň po termíne",
+ "Overdue by {days} days": "{days} dní po termíne",
+ "Due today": "Termín dnes",
+ "Due tomorrow": "Termín zajtra",
+ "Due in {days} days": "Termín o {days} dní",
+ "Tasks": "Úlohy",
+ "Task": "Úloha",
+ "Unassigned, open for claiming": "Nepriradené, možno prevziať",
+ "Claim": "Prevziať",
+ "Complete": "Dokončiť",
+ "Complete: {outcome}": "Dokončiť: {outcome}",
+ "Could not load the task": "Úlohu sa nepodarilo načítať",
+ "The task refused that action": "Úloha túto akciu odmietla"
},
"nplurals=4; plural=(n % 1 == 0 && n == 1 ? 0 : n % 1 == 0 && n >= 2 && n <= 4 ? 1 : n % 1 != 0 ? 2: 3);"
)
diff --git a/l10n/sk.json b/l10n/sk.json
index fd364af032..04b9c5f7bd 100644
--- a/l10n/sk.json
+++ b/l10n/sk.json
@@ -1,10 +1,20 @@
{
"translations": {
+ "from amount {amount}": "od sumy {amount}",
+ "Gated transition: {transition}": "Strážený prechod: {transition}",
+ "Each declared chain provisions an ordered task sequence when its transition is attempted. Approvers decide in their task inbox, not here.": "Každý deklarovaný reťazec otvorí usporiadanú sekvenciu úloh pri pokuse o prechod. Schvaľovatelia rozhodujú vo svojej schránke úloh, nie tu.",
+ "Declare x-openregister-approval-chains on this schema to gate a lifecycle transition on approval.": "Deklarujte x-openregister-approval-chains na tejto schéme, aby prechod životného cyklu podliehal schváleniu.",
+ "Approval sequences": "Schvaľovacie sekvencie",
"%n entries have no hash yet": "%n záznamov zatiaľ nemá odtlačok",
"%n entry has no hash yet": "%n záznam zatiaľ nemá odtlačok",
"(Dolphin required)": "(vyžaduje sa Dolphin)",
+ "No approval chains declared": "Nie sú deklarované žiadne schvaľovacie reťazce",
"(no subject)": "(bez predmetu)",
"(no title)": "(bez názvu)",
+ "Role {role}": "Rola {role}",
+ "The transition is applied automatically once every step approves.": "Prechod sa použije automaticky, len čo je každý krok schválený.",
+ "The requester may not decide their own approval.": "Žiadateľ nesmie rozhodovať o vlastnom schválení.",
+ "Tier routing on field: {field}": "Smerovanie podľa pásiem cez pole: {field}",
"(unnamed)": "(bez názvu)",
"(untitled card)": "(karta bez názvu)",
"({count} selected)": "(vybrané: {count})",
@@ -2817,7 +2827,84 @@
"Úspešne obnovené {count} objekty",
"Úspešne obnovených {count} objektu",
"Úspešne obnovených {count} objektov"
- ]
+ ],
+ "A message identity the notification subsystem resolves.": "Identita správy, ktorú rozlíši systém upozornení.",
+ "Computed non-working-date rules. kind fixed: {month, day, name, observedShift?: {whenWeekday, days}}. kind easter: {offset, name}, offset in days from Easter Sunday. kind observedShift: a fixed date with a required shift.": "Vypočítané pravidlá nepracovných dní. Druh fixed: {month, day, name, observedShift?: {whenWeekday, days}}. Druh easter: {offset, name}, odstup v dňoch od Veľkonočnej nedele. Druh observedShift: pevný dátum s povinným presunom.",
+ "Date": "Dátum",
+ "Day": "Deň",
+ "Day of a fixed or observedShift rule; ignored by an easter rule.": "Deň pravidla fixed alebo observedShift; pravidlo easter ho ignoruje.",
+ "Days": "Dni",
+ "Days from Easter Sunday for an easter rule; ignored by the other kinds.": "Dni od Veľkonočnej nedele pre pravidlo easter; ostatné druhy ich ignorujú.",
+ "Distance from the deadline, in the offset unit.": "Vzdialenosť od lehoty v jednotke odstupu.",
+ "Enumerated one-off closures as {date, name}. Allowed alongside rules; refused as the whole calendar.": "Jednorazové zatvorenia vymenované ako {date, name}. Povolené popri pravidlách; odmietnuté ako celý kalendár.",
+ "Escalate to roles": "Roly pre eskaláciu",
+ "Escalation ladder": "Eskalačný rebrík",
+ "Exception dates": "Výnimočné dátumy",
+ "Hours per working day": "Hodín na pracovný deň",
+ "How many days the observed date shifts, e.g. -1 for the Saturday before.": "O koľko dní sa slávený dátum presunie, napr. -1 pre predchádzajúcu sobotu.",
+ "Human-readable title.": "Čitateľný názov.",
+ "ISO weekdays (1 = Monday, 7 = Sunday) that are working days.": "ISO dni v týždni (1 = pondelok, 7 = nedeľa), ktoré sú pracovné.",
+ "Kind": "Druh",
+ "Message": "Správa",
+ "Month": "Mesiac",
+ "Month of a fixed or observedShift rule; ignored by an easter rule.": "Mesiac pravidla fixed alebo observedShift; pravidlo easter ho ignoruje.",
+ "Non-working-date rules": "Pravidlá nepracovných dní",
+ "Notify roles": "Roly na upozornenie",
+ "Observed shift": "Presun sviatku",
+ "Offset": "Odstup",
+ "Offset unit": "Jednotka odstupu",
+ "Open incident": "Otvoriť incident",
+ "Optional map from a role name to a concrete recipient descriptor, e.g. {\"teamleader\": \"group:teamleaders\"}. Roles without a binding travel unresolved as role:.": "Voliteľná mapa z názvu roly na konkrétneho príjemcu, napr. {\"teamleader\": \"group:teamleaders\"}. Roly bez väzby putujú nerozlíšené ako role:.",
+ "Optional on a fixed rule, required on observedShift: {whenWeekday: weekday name or ISO 1..7, days: integer}.": "Voliteľné pri pravidle fixed, povinné pri observedShift: {whenWeekday: názov dňa alebo ISO 1..7, days: celé číslo}.",
+ "Ordered rungs: {key, trigger (preBreach|slaBreached), offset, offsetUnit (hours|businessDays|calendarDays), notifyRole[], escalateToRole[], priority, message, openIncident}.": "Zoradené priečky: {key, trigger (preBreach|slaBreached), offset, offsetUnit (hours|businessDays|calendarDays), notifyRole[], escalateToRole[], priority, message, openIncident}.",
+ "Priority": "Priorita",
+ "Role bindings": "Väzby rolí",
+ "Roles the matter is escalated to at this rung.": "Roly, na ktoré sa vec na tejto priečke eskaluje.",
+ "Roles told at this rung; handler is the subject's own performer.": "Roly upozornené na tejto priečke; handler je osoba, ktorá vec vybavuje.",
+ "Rungs": "Priečky",
+ "Stable rung identity, e.g. preBreach:14:calendarDays; derived from trigger, offset and unit when absent.": "Stála identita priečky, napr. preBreach:14:calendarDays; ak chýba, odvodí sa zo spúšťača, odstupu a jednotky.",
+ "The calendar's stable name, referenced by a timer's calendar_slug.": "Stály názov kalendára, na ktorý časovač odkazuje cez calendar_slug.",
+ "The closed date, Y-m-d.": "Dátum zatvorenia, Y-m-d.",
+ "The holiday's name.": "Názov sviatku.",
+ "The ladder's stable name, referenced by a timer's ladder_slug.": "Stály názov rebríka, na ktorý časovač odkazuje cez ladder_slug.",
+ "The unit of the offset: the same set the SLA accepts.": "Jednotka odstupu: rovnaká množina, akú prijíma SLA.",
+ "The urgency the raised transition carries.": "Naliehavosť, ktorú nesie vyvolaný prechod.",
+ "The weekday (name) on which the date shifts, e.g. sunday for Koningsdag.": "Deň v týždni (názov), pri ktorom sa dátum presunie, napr. sunday pre Koningsdag.",
+ "UUID of the organisation this calendar is configured for. Empty for a shared calendar. The resolution order picks an organisation's calendar when the timer names none.": "UUID organizácie, pre ktorú je tento kalendár nastavený. Prázdne pri zdieľanom kalendári. Ak časovač žiadny nemenuje, poradie rozlíšenia vyberie kalendár organizácie.",
+ "UUID of the organisation this ladder is the default for. Empty for the shared default.": "UUID organizácie, pre ktorú je tento rebrík predvolený. Prázdne pri zdieľanom predvolenom.",
+ "When weekday": "Ak pripadne na",
+ "Whether reaching this rung opens an incident.": "Či dosiahnutie tejto priečky otvorí incident.",
+ "Why the day is closed.": "Prečo je deň zatvorený.",
+ "Working calendar": "Pracovný kalendár",
+ "Working hours in one working day. Makes hours and businessDays commensurable.": "Odpracované hodiny v jednom pracovnom dni. Robí hodiny a pracovné dni porovnateľnými.",
+ "Working weekdays": "Pracovné dni v týždni",
+ "fixed: a month/day; easter: an offset in days from Easter Sunday; observedShift: a month/day with a required observed shift.": "fixed: mesiac a deň; easter: odstup v dňoch od Veľkonočnej nedele; observedShift: mesiac a deň s povinným presunom.",
+ "preBreach fires before the deadline, slaBreached at or after it.": "preBreach sa spúšťa pred lehotou, slaBreached v lehote alebo po nej.",
+ "No such task": "Žiadna taká úloha",
+ "The task does not exist, or it is not yours to see.": "Úloha neexistuje, alebo ju nesmiete vidieť.",
+ "Details": "Podrobnosti",
+ "Due": "Termín",
+ "Assignee": "Priradené",
+ "Requested by": "Vyžiadal",
+ "Outcome": "Výsledok",
+ "Ready to claim": "Pripravené na prevzatie",
+ "In progress": "Prebieha",
+ "Terminated": "Ukončené",
+ "Normal": "Normálna",
+ "Urgent": "Naliehavé",
+ "Overdue by 1 day": "1 deň po termíne",
+ "Overdue by {days} days": "{days} dní po termíne",
+ "Due today": "Termín dnes",
+ "Due tomorrow": "Termín zajtra",
+ "Due in {days} days": "Termín o {days} dní",
+ "Tasks": "Úlohy",
+ "Task": "Úloha",
+ "Unassigned, open for claiming": "Nepriradené, možno prevziať",
+ "Claim": "Prevziať",
+ "Complete": "Dokončiť",
+ "Complete: {outcome}": "Dokončiť: {outcome}",
+ "Could not load the task": "Úlohu sa nepodarilo načítať",
+ "The task refused that action": "Úloha túto akciu odmietla"
},
"pluralForm": "nplurals=4; plural=(n % 1 == 0 && n == 1 ? 0 : n % 1 == 0 && n >= 2 && n <= 4 ? 1 : n % 1 != 0 ? 2: 3);",
"plurals": {
diff --git a/l10n/sl.js b/l10n/sl.js
index 9b919c67d5..bfc280390c 100644
--- a/l10n/sl.js
+++ b/l10n/sl.js
@@ -3,11 +3,21 @@ OC.L10N.register(
{
"3": "3",
"30": "30",
+ "from amount {amount}": "od zneska {amount}",
+ "Gated transition: {transition}": "Nadzorovan prehod: {transition}",
+ "Each declared chain provisions an ordered task sequence when its transition is attempted. Approvers decide in their task inbox, not here.": "Vsaka deklarirana veriga ob poskusu prehoda odpre urejeno zaporedje nalog. Odobritelji odločajo v svojem nabiralniku nalog, ne tukaj.",
+ "Declare x-openregister-approval-chains on this schema to gate a lifecycle transition on approval.": "Deklarirajte x-openregister-approval-chains na tej shemi, da prehod življenjskega cikla zahteva odobritev.",
+ "Approval sequences": "Zaporedja odobritev",
"%n entries have no hash yet": "%n vnosov še nima zgoščene vrednosti",
"%n entry has no hash yet": "%n vnos še nima zgoščene vrednosti",
"(Dolphin required)": "(Potreben Dolphin)",
+ "No approval chains declared": "Ni deklariranih verig odobritev",
"(no subject)": "(brez zadeve)",
"(no title)": "(brez naslova)",
+ "Role {role}": "Vloga {role}",
+ "The transition is applied automatically once every step approves.": "Prehod se uporabi samodejno, ko je vsak korak odobren.",
+ "The requester may not decide their own approval.": "Predlagatelj ne sme odločati o lastni odobritvi.",
+ "Tier routing on field: {field}": "Stopenjsko usmerjanje po polju: {field}",
"(unnamed)": "(brez imena)",
"(untitled card)": "(kartica brez naslova)",
"({count} selected)": "({count} izbrano)",
@@ -2738,7 +2748,84 @@ OC.L10N.register(
"_Object successfully deleted_::_Objects successfully deleted_": ["Objekt je uspešno izbrisan","Objekta sta uspešno izbrisana","Objekti so uspešno izbrisani","Objekti so uspešno izbrisani"],
"_Purge {count} object from database_::_Purge {count} objects from database_": ["Trajno odstrani {count} objekt iz baze podatkov","Trajno odstrani {count} objekta iz baze podatkov","Trajno odstrani {count} objekte iz baze podatkov","Trajno odstrani {count} objektov iz baze podatkov"],
"_Restore {count} object_::_Restore {count} objects_": ["Obnovi {count} objekt","Obnovi {count} objekta","Obnovi {count} objekte","Obnovi {count} objektov"],
- "_Successfully restored {count} object_::_Successfully restored {count} objects_": ["Uspešno obnovljen {count} objekt","Uspešno obnovljena {count} objekta","Uspešno obnovljeni {count} objekti","Uspešno obnovljenih {count} objektov"]
+ "_Successfully restored {count} object_::_Successfully restored {count} objects_": ["Uspešno obnovljen {count} objekt","Uspešno obnovljena {count} objekta","Uspešno obnovljeni {count} objekti","Uspešno obnovljenih {count} objektov"],
+ "A message identity the notification subsystem resolves.": "Istovetnost sporočila, ki jo razreši sistem obvestil.",
+ "Computed non-working-date rules. kind fixed: {month, day, name, observedShift?: {whenWeekday, days}}. kind easter: {offset, name}, offset in days from Easter Sunday. kind observedShift: a fixed date with a required shift.": "Izračunana pravila nedelovnih dni. Vrsta fixed: {month, day, name, observedShift?: {whenWeekday, days}}. Vrsta easter: {offset, name}, odmik v dneh od velikonočne nedelje. Vrsta observedShift: nespremenljiv datum z obvezno prestavitvijo.",
+ "Date": "Datum",
+ "Day": "Dan",
+ "Day of a fixed or observedShift rule; ignored by an easter rule.": "Dan pravila fixed ali observedShift; pravilo easter ga prezre.",
+ "Days": "Dnevi",
+ "Days from Easter Sunday for an easter rule; ignored by the other kinds.": "Dnevi od velikonočne nedelje za pravilo easter; druge vrste jih prezrejo.",
+ "Distance from the deadline, in the offset unit.": "Razdalja do roka v enoti odmika.",
+ "Enumerated one-off closures as {date, name}. Allowed alongside rules; refused as the whole calendar.": "Posamezna zaprtja, našteta kot {date, name}. Dovoljena ob pravilih; zavrnjena kot celoten koledar.",
+ "Escalate to roles": "Vloge za stopnjevanje",
+ "Escalation ladder": "Stopnjevalna lestev",
+ "Exception dates": "Izjemni datumi",
+ "Hours per working day": "Ur na delovni dan",
+ "How many days the observed date shifts, e.g. -1 for the Saturday before.": "Za koliko dni se praznovani datum prestavi, npr. -1 za soboto prej.",
+ "Human-readable title.": "Berljiv naslov.",
+ "ISO weekdays (1 = Monday, 7 = Sunday) that are working days.": "ISO dnevi v tednu (1 = ponedeljek, 7 = nedelja), ki so delovni.",
+ "Kind": "Vrsta",
+ "Message": "Sporočilo",
+ "Month": "Mesec",
+ "Month of a fixed or observedShift rule; ignored by an easter rule.": "Mesec pravila fixed ali observedShift; pravilo easter ga prezre.",
+ "Non-working-date rules": "Pravila nedelovnih dni",
+ "Notify roles": "Vloge za obveščanje",
+ "Observed shift": "Prestavitev praznika",
+ "Offset": "Odmik",
+ "Offset unit": "Enota odmika",
+ "Open incident": "Odpri incident",
+ "Optional map from a role name to a concrete recipient descriptor, e.g. {\"teamleader\": \"group:teamleaders\"}. Roles without a binding travel unresolved as role:.": "Neobvezna preslikava imena vloge v konkretnega prejemnika, npr. {\"teamleader\": \"group:teamleaders\"}. Vloge brez vezave potujejo nerazrešene kot role:.",
+ "Optional on a fixed rule, required on observedShift: {whenWeekday: weekday name or ISO 1..7, days: integer}.": "Neobvezno pri pravilu fixed, obvezno pri observedShift: {whenWeekday: ime dneva ali ISO 1..7, days: celo število}.",
+ "Ordered rungs: {key, trigger (preBreach|slaBreached), offset, offsetUnit (hours|businessDays|calendarDays), notifyRole[], escalateToRole[], priority, message, openIncident}.": "Urejene prečke: {key, trigger (preBreach|slaBreached), offset, offsetUnit (hours|businessDays|calendarDays), notifyRole[], escalateToRole[], priority, message, openIncident}.",
+ "Priority": "Prednost",
+ "Role bindings": "Vezave vlog",
+ "Roles the matter is escalated to at this rung.": "Vloge, na katere se zadeva na tej prečki stopnjuje.",
+ "Roles told at this rung; handler is the subject's own performer.": "Vloge, obveščene na tej prečki; handler je oseba, ki zadevo obravnava.",
+ "Rungs": "Prečke",
+ "Stable rung identity, e.g. preBreach:14:calendarDays; derived from trigger, offset and unit when absent.": "Stalna istovetnost prečke, npr. preBreach:14:calendarDays; če manjka, se izpelje iz sprožilca, odmika in enote.",
+ "The calendar's stable name, referenced by a timer's calendar_slug.": "Stalno ime koledarja, na katero se časovnik sklicuje prek calendar_slug.",
+ "The closed date, Y-m-d.": "Datum zaprtja, Y-m-d.",
+ "The holiday's name.": "Ime praznika.",
+ "The ladder's stable name, referenced by a timer's ladder_slug.": "Stalno ime lestve, na katero se časovnik sklicuje prek ladder_slug.",
+ "The unit of the offset: the same set the SLA accepts.": "Enota odmika: ista množica, kot jo sprejme SLA.",
+ "The urgency the raised transition carries.": "Nujnost, ki jo nosi sproženi prehod.",
+ "The weekday (name) on which the date shifts, e.g. sunday for Koningsdag.": "Dan v tednu (ime), ob katerem se datum prestavi, npr. sunday za Koningsdag.",
+ "UUID of the organisation this calendar is configured for. Empty for a shared calendar. The resolution order picks an organisation's calendar when the timer names none.": "UUID organizacije, za katero je ta koledar nastavljen. Prazno pri skupnem koledarju. Če časovnik ne imenuje nobenega, vrstni red razreševanja izbere koledar organizacije.",
+ "UUID of the organisation this ladder is the default for. Empty for the shared default.": "UUID organizacije, za katero je ta lestev privzeta. Prazno pri skupni privzeti.",
+ "When weekday": "Če pade na",
+ "Whether reaching this rung opens an incident.": "Ali dosežena prečka odpre incident.",
+ "Why the day is closed.": "Zakaj je dan zaprt.",
+ "Working calendar": "Delovni koledar",
+ "Working hours in one working day. Makes hours and businessDays commensurable.": "Delovne ure v enem delovnem dnevu. Naredi ure in delovne dni primerljive.",
+ "Working weekdays": "Delovni dnevi v tednu",
+ "fixed: a month/day; easter: an offset in days from Easter Sunday; observedShift: a month/day with a required observed shift.": "fixed: mesec in dan; easter: odmik v dneh od velikonočne nedelje; observedShift: mesec in dan z obvezno prestavitvijo.",
+ "preBreach fires before the deadline, slaBreached at or after it.": "preBreach se sproži pred rokom, slaBreached ob roku ali po njem.",
+ "No such task": "Ni takšne naloge",
+ "The task does not exist, or it is not yours to see.": "Naloga ne obstaja ali pa je ne smete videti.",
+ "Details": "Podrobnosti",
+ "Due": "Rok",
+ "Assignee": "Dodeljeno",
+ "Requested by": "Zahteval",
+ "Outcome": "Izid",
+ "Ready to claim": "Pripravljeno za prevzem",
+ "In progress": "V teku",
+ "Terminated": "Prekinjeno",
+ "Normal": "Običajno",
+ "Urgent": "Nujno",
+ "Overdue by 1 day": "1 dan čez rok",
+ "Overdue by {days} days": "{days} dni čez rok",
+ "Due today": "Rok danes",
+ "Due tomorrow": "Rok jutri",
+ "Due in {days} days": "Rok čez {days} dni",
+ "Tasks": "Naloge",
+ "Task": "Naloga",
+ "Unassigned, open for claiming": "Nedodeljeno, odprto za prevzem",
+ "Claim": "Prevzemi",
+ "Complete": "Dokončaj",
+ "Complete: {outcome}": "Dokončaj: {outcome}",
+ "Could not load the task": "Naloge ni bilo mogoče naložiti",
+ "The task refused that action": "Naloga je zavrnila to dejanje"
},
"nplurals=4; plural=(n%100==1 ? 0 : n%100==2 ? 1 : n%100==3 || n%100==4 ? 2 : 3);"
)
diff --git a/l10n/sl.json b/l10n/sl.json
index 7d98c6b9b2..a45222bfdd 100644
--- a/l10n/sl.json
+++ b/l10n/sl.json
@@ -1,10 +1,20 @@
{
"translations": {
+ "from amount {amount}": "od zneska {amount}",
+ "Gated transition: {transition}": "Nadzorovan prehod: {transition}",
+ "Each declared chain provisions an ordered task sequence when its transition is attempted. Approvers decide in their task inbox, not here.": "Vsaka deklarirana veriga ob poskusu prehoda odpre urejeno zaporedje nalog. Odobritelji odločajo v svojem nabiralniku nalog, ne tukaj.",
+ "Declare x-openregister-approval-chains on this schema to gate a lifecycle transition on approval.": "Deklarirajte x-openregister-approval-chains na tej shemi, da prehod življenjskega cikla zahteva odobritev.",
+ "Approval sequences": "Zaporedja odobritev",
"%n entries have no hash yet": "%n vnosov še nima zgoščene vrednosti",
"%n entry has no hash yet": "%n vnos še nima zgoščene vrednosti",
"(Dolphin required)": "(Potreben Dolphin)",
+ "No approval chains declared": "Ni deklariranih verig odobritev",
"(no subject)": "(brez zadeve)",
"(no title)": "(brez naslova)",
+ "Role {role}": "Vloga {role}",
+ "The transition is applied automatically once every step approves.": "Prehod se uporabi samodejno, ko je vsak korak odobren.",
+ "The requester may not decide their own approval.": "Predlagatelj ne sme odločati o lastni odobritvi.",
+ "Tier routing on field: {field}": "Stopenjsko usmerjanje po polju: {field}",
"(unnamed)": "(brez imena)",
"(untitled card)": "(kartica brez naslova)",
"({count} selected)": "({count} izbrano)",
@@ -2817,7 +2827,84 @@
"Uspešno obnovljena {count} objekta",
"Uspešno obnovljeni {count} objekti",
"Uspešno obnovljenih {count} objektov"
- ]
+ ],
+ "A message identity the notification subsystem resolves.": "Istovetnost sporočila, ki jo razreši sistem obvestil.",
+ "Computed non-working-date rules. kind fixed: {month, day, name, observedShift?: {whenWeekday, days}}. kind easter: {offset, name}, offset in days from Easter Sunday. kind observedShift: a fixed date with a required shift.": "Izračunana pravila nedelovnih dni. Vrsta fixed: {month, day, name, observedShift?: {whenWeekday, days}}. Vrsta easter: {offset, name}, odmik v dneh od velikonočne nedelje. Vrsta observedShift: nespremenljiv datum z obvezno prestavitvijo.",
+ "Date": "Datum",
+ "Day": "Dan",
+ "Day of a fixed or observedShift rule; ignored by an easter rule.": "Dan pravila fixed ali observedShift; pravilo easter ga prezre.",
+ "Days": "Dnevi",
+ "Days from Easter Sunday for an easter rule; ignored by the other kinds.": "Dnevi od velikonočne nedelje za pravilo easter; druge vrste jih prezrejo.",
+ "Distance from the deadline, in the offset unit.": "Razdalja do roka v enoti odmika.",
+ "Enumerated one-off closures as {date, name}. Allowed alongside rules; refused as the whole calendar.": "Posamezna zaprtja, našteta kot {date, name}. Dovoljena ob pravilih; zavrnjena kot celoten koledar.",
+ "Escalate to roles": "Vloge za stopnjevanje",
+ "Escalation ladder": "Stopnjevalna lestev",
+ "Exception dates": "Izjemni datumi",
+ "Hours per working day": "Ur na delovni dan",
+ "How many days the observed date shifts, e.g. -1 for the Saturday before.": "Za koliko dni se praznovani datum prestavi, npr. -1 za soboto prej.",
+ "Human-readable title.": "Berljiv naslov.",
+ "ISO weekdays (1 = Monday, 7 = Sunday) that are working days.": "ISO dnevi v tednu (1 = ponedeljek, 7 = nedelja), ki so delovni.",
+ "Kind": "Vrsta",
+ "Message": "Sporočilo",
+ "Month": "Mesec",
+ "Month of a fixed or observedShift rule; ignored by an easter rule.": "Mesec pravila fixed ali observedShift; pravilo easter ga prezre.",
+ "Non-working-date rules": "Pravila nedelovnih dni",
+ "Notify roles": "Vloge za obveščanje",
+ "Observed shift": "Prestavitev praznika",
+ "Offset": "Odmik",
+ "Offset unit": "Enota odmika",
+ "Open incident": "Odpri incident",
+ "Optional map from a role name to a concrete recipient descriptor, e.g. {\"teamleader\": \"group:teamleaders\"}. Roles without a binding travel unresolved as role:.": "Neobvezna preslikava imena vloge v konkretnega prejemnika, npr. {\"teamleader\": \"group:teamleaders\"}. Vloge brez vezave potujejo nerazrešene kot role:.",
+ "Optional on a fixed rule, required on observedShift: {whenWeekday: weekday name or ISO 1..7, days: integer}.": "Neobvezno pri pravilu fixed, obvezno pri observedShift: {whenWeekday: ime dneva ali ISO 1..7, days: celo število}.",
+ "Ordered rungs: {key, trigger (preBreach|slaBreached), offset, offsetUnit (hours|businessDays|calendarDays), notifyRole[], escalateToRole[], priority, message, openIncident}.": "Urejene prečke: {key, trigger (preBreach|slaBreached), offset, offsetUnit (hours|businessDays|calendarDays), notifyRole[], escalateToRole[], priority, message, openIncident}.",
+ "Priority": "Prednost",
+ "Role bindings": "Vezave vlog",
+ "Roles the matter is escalated to at this rung.": "Vloge, na katere se zadeva na tej prečki stopnjuje.",
+ "Roles told at this rung; handler is the subject's own performer.": "Vloge, obveščene na tej prečki; handler je oseba, ki zadevo obravnava.",
+ "Rungs": "Prečke",
+ "Stable rung identity, e.g. preBreach:14:calendarDays; derived from trigger, offset and unit when absent.": "Stalna istovetnost prečke, npr. preBreach:14:calendarDays; če manjka, se izpelje iz sprožilca, odmika in enote.",
+ "The calendar's stable name, referenced by a timer's calendar_slug.": "Stalno ime koledarja, na katero se časovnik sklicuje prek calendar_slug.",
+ "The closed date, Y-m-d.": "Datum zaprtja, Y-m-d.",
+ "The holiday's name.": "Ime praznika.",
+ "The ladder's stable name, referenced by a timer's ladder_slug.": "Stalno ime lestve, na katero se časovnik sklicuje prek ladder_slug.",
+ "The unit of the offset: the same set the SLA accepts.": "Enota odmika: ista množica, kot jo sprejme SLA.",
+ "The urgency the raised transition carries.": "Nujnost, ki jo nosi sproženi prehod.",
+ "The weekday (name) on which the date shifts, e.g. sunday for Koningsdag.": "Dan v tednu (ime), ob katerem se datum prestavi, npr. sunday za Koningsdag.",
+ "UUID of the organisation this calendar is configured for. Empty for a shared calendar. The resolution order picks an organisation's calendar when the timer names none.": "UUID organizacije, za katero je ta koledar nastavljen. Prazno pri skupnem koledarju. Če časovnik ne imenuje nobenega, vrstni red razreševanja izbere koledar organizacije.",
+ "UUID of the organisation this ladder is the default for. Empty for the shared default.": "UUID organizacije, za katero je ta lestev privzeta. Prazno pri skupni privzeti.",
+ "When weekday": "Če pade na",
+ "Whether reaching this rung opens an incident.": "Ali dosežena prečka odpre incident.",
+ "Why the day is closed.": "Zakaj je dan zaprt.",
+ "Working calendar": "Delovni koledar",
+ "Working hours in one working day. Makes hours and businessDays commensurable.": "Delovne ure v enem delovnem dnevu. Naredi ure in delovne dni primerljive.",
+ "Working weekdays": "Delovni dnevi v tednu",
+ "fixed: a month/day; easter: an offset in days from Easter Sunday; observedShift: a month/day with a required observed shift.": "fixed: mesec in dan; easter: odmik v dneh od velikonočne nedelje; observedShift: mesec in dan z obvezno prestavitvijo.",
+ "preBreach fires before the deadline, slaBreached at or after it.": "preBreach se sproži pred rokom, slaBreached ob roku ali po njem.",
+ "No such task": "Ni takšne naloge",
+ "The task does not exist, or it is not yours to see.": "Naloga ne obstaja ali pa je ne smete videti.",
+ "Details": "Podrobnosti",
+ "Due": "Rok",
+ "Assignee": "Dodeljeno",
+ "Requested by": "Zahteval",
+ "Outcome": "Izid",
+ "Ready to claim": "Pripravljeno za prevzem",
+ "In progress": "V teku",
+ "Terminated": "Prekinjeno",
+ "Normal": "Običajno",
+ "Urgent": "Nujno",
+ "Overdue by 1 day": "1 dan čez rok",
+ "Overdue by {days} days": "{days} dni čez rok",
+ "Due today": "Rok danes",
+ "Due tomorrow": "Rok jutri",
+ "Due in {days} days": "Rok čez {days} dni",
+ "Tasks": "Naloge",
+ "Task": "Naloga",
+ "Unassigned, open for claiming": "Nedodeljeno, odprto za prevzem",
+ "Claim": "Prevzemi",
+ "Complete": "Dokončaj",
+ "Complete: {outcome}": "Dokončaj: {outcome}",
+ "Could not load the task": "Naloge ni bilo mogoče naložiti",
+ "The task refused that action": "Naloga je zavrnila to dejanje"
},
"pluralForm": "nplurals=4; plural=(n%100==1 ? 0 : n%100==2 ? 1 : n%100==3 || n%100==4 ? 2 : 3);",
"plurals": {
diff --git a/l10n/sq.js b/l10n/sq.js
index d8bc753a4f..8a7022e2ff 100644
--- a/l10n/sq.js
+++ b/l10n/sq.js
@@ -3,11 +3,21 @@ OC.L10N.register(
{
"3": "3",
"30": "30",
+ "from amount {amount}": "nga shuma {amount}",
+ "Gated transition: {transition}": "Kalim i mbikëqyrur: {transition}",
+ "Each declared chain provisions an ordered task sequence when its transition is attempted. Approvers decide in their task inbox, not here.": "Çdo zinxhir i deklaruar hap një sekuencë të renditur detyrash kur kalimi provohet. Miratuesit vendosin në kutinë e tyre të detyrave, jo këtu.",
+ "Declare x-openregister-approval-chains on this schema to gate a lifecycle transition on approval.": "Deklaroni x-openregister-approval-chains në këtë skemë që një kalim i ciklit jetësor të kërkojë miratim.",
+ "Approval sequences": "Sekuenca miratimi",
"%n entries have no hash yet": "%n zëra ende nuk kanë hash",
"%n entry has no hash yet": "%n zë ende nuk ka hash",
"(Dolphin required)": "(Kërkohet Dolphin)",
+ "No approval chains declared": "Nuk ka zinxhirë miratimi të deklaruar",
"(no subject)": "(pa temë)",
"(no title)": "(pa titull)",
+ "Role {role}": "Roli {role}",
+ "The transition is applied automatically once every step approves.": "Kalimi zbatohet automatikisht sapo çdo hap të miratohet.",
+ "The requester may not decide their own approval.": "Kërkuesi nuk mund të vendosë për miratimin e vet.",
+ "Tier routing on field: {field}": "Drejtim me shkallë sipas fushës: {field}",
"(unnamed)": "(pa emër)",
"(untitled card)": "(kartë pa titull)",
"({count} selected)": "({count} të zgjedhura)",
@@ -2738,7 +2748,84 @@ OC.L10N.register(
"_Object successfully deleted_::_Objects successfully deleted_": ["Objekti u fshi me sukses","Objektet u fshinë me sukses"],
"_Purge {count} object from database_::_Purge {count} objects from database_": ["Pastro {count} objekt nga baza e të dhënave","Pastro {count} objekte nga baza e të dhënave"],
"_Restore {count} object_::_Restore {count} objects_": ["Ripristino {count} objekti","Ripristino {count} objekte"],
- "_Successfully restored {count} object_::_Successfully restored {count} objects_": ["{count} objekt u ripristinua me sukses","{count} objekte u ripristinuan me sukses"]
+ "_Successfully restored {count} object_::_Successfully restored {count} objects_": ["{count} objekt u ripristinua me sukses","{count} objekte u ripristinuan me sukses"],
+ "A message identity the notification subsystem resolves.": "Një identitet mesazhi që e zgjidh sistemi i njoftimeve.",
+ "Computed non-working-date rules. kind fixed: {month, day, name, observedShift?: {whenWeekday, days}}. kind easter: {offset, name}, offset in days from Easter Sunday. kind observedShift: a fixed date with a required shift.": "Rregulla të llogaritura të ditëve jo të punës. Lloji fixed: {month, day, name, observedShift?: {whenWeekday, days}}. Lloji easter: {offset, name}, zhvendosje në ditë nga e diela e Pashkëve. Lloji observedShift: një datë fikse me shtyrje të detyrueshme.",
+ "Date": "Data",
+ "Day": "Dita",
+ "Day of a fixed or observedShift rule; ignored by an easter rule.": "Dita e një rregulli fixed ose observedShift; rregulli easter e shpërfill.",
+ "Days": "Ditë",
+ "Days from Easter Sunday for an easter rule; ignored by the other kinds.": "Ditë nga e diela e Pashkëve për një rregull easter; llojet e tjera i shpërfillin.",
+ "Distance from the deadline, in the offset unit.": "Largësia nga afati, në njësinë e zhvendosjes.",
+ "Enumerated one-off closures as {date, name}. Allowed alongside rules; refused as the whole calendar.": "Mbyllje të njëhershme të renditura si {date, name}. Të lejuara krahas rregullave; të refuzuara si kalendari i tërë.",
+ "Escalate to roles": "Rolet e përshkallëzimit",
+ "Escalation ladder": "Shkalla e përshkallëzimit",
+ "Exception dates": "Datat e përjashtimit",
+ "Hours per working day": "Orë për ditë pune",
+ "How many days the observed date shifts, e.g. -1 for the Saturday before.": "Sa ditë shtyhet data e festuar, p.sh. -1 për të shtunën përpara.",
+ "Human-readable title.": "Titull i lexueshëm.",
+ "ISO weekdays (1 = Monday, 7 = Sunday) that are working days.": "Ditët ISO të javës (1 = e hënë, 7 = e diel) që janë ditë pune.",
+ "Kind": "Lloji",
+ "Message": "Mesazhi",
+ "Month": "Muaji",
+ "Month of a fixed or observedShift rule; ignored by an easter rule.": "Muaji i një rregulli fixed ose observedShift; rregulli easter e shpërfill.",
+ "Non-working-date rules": "Rregullat e ditëve jo të punës",
+ "Notify roles": "Rolet për njoftim",
+ "Observed shift": "Shtyrja e festës",
+ "Offset": "Zhvendosja",
+ "Offset unit": "Njësia e zhvendosjes",
+ "Open incident": "Hap incident",
+ "Optional map from a role name to a concrete recipient descriptor, e.g. {\"teamleader\": \"group:teamleaders\"}. Roles without a binding travel unresolved as role:.": "Hartë opsionale nga emri i një roli te një marrës konkret, p.sh. {\"teamleader\": \"group:teamleaders\"}. Rolet pa lidhje udhëtojnë të pazgjidhura si role:.",
+ "Optional on a fixed rule, required on observedShift: {whenWeekday: weekday name or ISO 1..7, days: integer}.": "Opsionale te rregulli fixed, e detyrueshme te observedShift: {whenWeekday: emri i ditës ose ISO 1..7, days: numër i plotë}.",
+ "Ordered rungs: {key, trigger (preBreach|slaBreached), offset, offsetUnit (hours|businessDays|calendarDays), notifyRole[], escalateToRole[], priority, message, openIncident}.": "Shkallë të renditura: {key, trigger (preBreach|slaBreached), offset, offsetUnit (hours|businessDays|calendarDays), notifyRole[], escalateToRole[], priority, message, openIncident}.",
+ "Priority": "Përparësia",
+ "Role bindings": "Lidhjet e roleve",
+ "Roles the matter is escalated to at this rung.": "Rolet te të cilat çështja përshkallëzohet në këtë shkallë.",
+ "Roles told at this rung; handler is the subject's own performer.": "Rolet e njoftuara në këtë shkallë; handler është personi që trajton çështjen.",
+ "Rungs": "Shkallët",
+ "Stable rung identity, e.g. preBreach:14:calendarDays; derived from trigger, offset and unit when absent.": "Identiteti i qëndrueshëm i shkallës, p.sh. preBreach:14:calendarDays; kur mungon, rrjedh nga shkrehësi, zhvendosja dhe njësia.",
+ "The calendar's stable name, referenced by a timer's calendar_slug.": "Emri i qëndrueshëm i kalendarit, të cilit një kohëmatës i referohet me calendar_slug.",
+ "The closed date, Y-m-d.": "Data e mbylljes, Y-m-d.",
+ "The holiday's name.": "Emri i festës.",
+ "The ladder's stable name, referenced by a timer's ladder_slug.": "Emri i qëndrueshëm i shkallës, të cilit një kohëmatës i referohet me ladder_slug.",
+ "The unit of the offset: the same set the SLA accepts.": "Njësia e zhvendosjes: i njëjti grup që pranon SLA.",
+ "The urgency the raised transition carries.": "Urgjenca që mbart kalimi i shkrehur.",
+ "The weekday (name) on which the date shifts, e.g. sunday for Koningsdag.": "Dita e javës (emri) kur data shtyhet, p.sh. sunday për Koningsdag.",
+ "UUID of the organisation this calendar is configured for. Empty for a shared calendar. The resolution order picks an organisation's calendar when the timer names none.": "UUID i organizatës për të cilën është konfiguruar ky kalendar. Bosh për një kalendar të përbashkët. Nëse kohëmatësi nuk emërton asnjë, radha e zgjidhjes zgjedh kalendarin e organizatës.",
+ "UUID of the organisation this ladder is the default for. Empty for the shared default.": "UUID i organizatës për të cilën kjo shkallë është parazgjedhja. Bosh për parazgjedhjen e përbashkët.",
+ "When weekday": "Nëse bie ditën e",
+ "Whether reaching this rung opens an incident.": "Nëse arritja e kësaj shkalle hap një incident.",
+ "Why the day is closed.": "Pse është e mbyllur ajo ditë.",
+ "Working calendar": "Kalendari i punës",
+ "Working hours in one working day. Makes hours and businessDays commensurable.": "Orët e punës në një ditë pune. I bën orët dhe ditët e punës të krahasueshme.",
+ "Working weekdays": "Ditët e punës të javës",
+ "fixed: a month/day; easter: an offset in days from Easter Sunday; observedShift: a month/day with a required observed shift.": "fixed: muaj dhe ditë; easter: një zhvendosje në ditë nga e diela e Pashkëve; observedShift: muaj dhe ditë me shtyrje të detyrueshme.",
+ "preBreach fires before the deadline, slaBreached at or after it.": "preBreach shkrehet para afatit, slaBreached në afat ose pas tij.",
+ "No such task": "Nuk ka detyrë të tillë",
+ "The task does not exist, or it is not yours to see.": "Detyra nuk ekziston, ose nuk keni të drejtë ta shihni.",
+ "Details": "Detaje",
+ "Due": "Afati",
+ "Assignee": "Caktuar",
+ "Requested by": "Kërkuar nga",
+ "Outcome": "Rezultati",
+ "Ready to claim": "Gati për t'u marrë",
+ "In progress": "Në vazhdim",
+ "Terminated": "Përfunduar",
+ "Normal": "Normale",
+ "Urgent": "Urgjente",
+ "Overdue by 1 day": "1 ditë me vonesë",
+ "Overdue by {days} days": "{days} ditë me vonesë",
+ "Due today": "Afati sot",
+ "Due tomorrow": "Afati nesër",
+ "Due in {days} days": "Afati pas {days} ditësh",
+ "Tasks": "Detyra",
+ "Task": "Detyrë",
+ "Unassigned, open for claiming": "E pacaktuar, e hapur për t'u marrë",
+ "Claim": "Merr",
+ "Complete": "Përfundo",
+ "Complete: {outcome}": "Përfundo: {outcome}",
+ "Could not load the task": "Detyra nuk u ngarkua dot",
+ "The task refused that action": "Detyra e refuzoi atë veprim"
},
"nplurals=2; plural=(n != 1);"
)
diff --git a/l10n/sq.json b/l10n/sq.json
index 05b9eb2618..611f326a2a 100644
--- a/l10n/sq.json
+++ b/l10n/sq.json
@@ -1,10 +1,20 @@
{
"translations": {
+ "from amount {amount}": "nga shuma {amount}",
+ "Gated transition: {transition}": "Kalim i mbikëqyrur: {transition}",
+ "Each declared chain provisions an ordered task sequence when its transition is attempted. Approvers decide in their task inbox, not here.": "Çdo zinxhir i deklaruar hap një sekuencë të renditur detyrash kur kalimi provohet. Miratuesit vendosin në kutinë e tyre të detyrave, jo këtu.",
+ "Declare x-openregister-approval-chains on this schema to gate a lifecycle transition on approval.": "Deklaroni x-openregister-approval-chains në këtë skemë që një kalim i ciklit jetësor të kërkojë miratim.",
+ "Approval sequences": "Sekuenca miratimi",
"%n entries have no hash yet": "%n zëra ende nuk kanë hash",
"%n entry has no hash yet": "%n zë ende nuk ka hash",
"(Dolphin required)": "(Kërkohet Dolphin)",
+ "No approval chains declared": "Nuk ka zinxhirë miratimi të deklaruar",
"(no subject)": "(pa temë)",
"(no title)": "(pa titull)",
+ "Role {role}": "Roli {role}",
+ "The transition is applied automatically once every step approves.": "Kalimi zbatohet automatikisht sapo çdo hap të miratohet.",
+ "The requester may not decide their own approval.": "Kërkuesi nuk mund të vendosë për miratimin e vet.",
+ "Tier routing on field: {field}": "Drejtim me shkallë sipas fushës: {field}",
"(unnamed)": "(pa emër)",
"(untitled card)": "(kartë pa titull)",
"({count} selected)": "({count} të zgjedhura)",
@@ -2785,7 +2795,84 @@
"_Successfully restored {count} object_::_Successfully restored {count} objects_": [
"{count} objekt u ripristinua me sukses",
"{count} objekte u ripristinuan me sukses"
- ]
+ ],
+ "A message identity the notification subsystem resolves.": "Një identitet mesazhi që e zgjidh sistemi i njoftimeve.",
+ "Computed non-working-date rules. kind fixed: {month, day, name, observedShift?: {whenWeekday, days}}. kind easter: {offset, name}, offset in days from Easter Sunday. kind observedShift: a fixed date with a required shift.": "Rregulla të llogaritura të ditëve jo të punës. Lloji fixed: {month, day, name, observedShift?: {whenWeekday, days}}. Lloji easter: {offset, name}, zhvendosje në ditë nga e diela e Pashkëve. Lloji observedShift: një datë fikse me shtyrje të detyrueshme.",
+ "Date": "Data",
+ "Day": "Dita",
+ "Day of a fixed or observedShift rule; ignored by an easter rule.": "Dita e një rregulli fixed ose observedShift; rregulli easter e shpërfill.",
+ "Days": "Ditë",
+ "Days from Easter Sunday for an easter rule; ignored by the other kinds.": "Ditë nga e diela e Pashkëve për një rregull easter; llojet e tjera i shpërfillin.",
+ "Distance from the deadline, in the offset unit.": "Largësia nga afati, në njësinë e zhvendosjes.",
+ "Enumerated one-off closures as {date, name}. Allowed alongside rules; refused as the whole calendar.": "Mbyllje të njëhershme të renditura si {date, name}. Të lejuara krahas rregullave; të refuzuara si kalendari i tërë.",
+ "Escalate to roles": "Rolet e përshkallëzimit",
+ "Escalation ladder": "Shkalla e përshkallëzimit",
+ "Exception dates": "Datat e përjashtimit",
+ "Hours per working day": "Orë për ditë pune",
+ "How many days the observed date shifts, e.g. -1 for the Saturday before.": "Sa ditë shtyhet data e festuar, p.sh. -1 për të shtunën përpara.",
+ "Human-readable title.": "Titull i lexueshëm.",
+ "ISO weekdays (1 = Monday, 7 = Sunday) that are working days.": "Ditët ISO të javës (1 = e hënë, 7 = e diel) që janë ditë pune.",
+ "Kind": "Lloji",
+ "Message": "Mesazhi",
+ "Month": "Muaji",
+ "Month of a fixed or observedShift rule; ignored by an easter rule.": "Muaji i një rregulli fixed ose observedShift; rregulli easter e shpërfill.",
+ "Non-working-date rules": "Rregullat e ditëve jo të punës",
+ "Notify roles": "Rolet për njoftim",
+ "Observed shift": "Shtyrja e festës",
+ "Offset": "Zhvendosja",
+ "Offset unit": "Njësia e zhvendosjes",
+ "Open incident": "Hap incident",
+ "Optional map from a role name to a concrete recipient descriptor, e.g. {\"teamleader\": \"group:teamleaders\"}. Roles without a binding travel unresolved as role:.": "Hartë opsionale nga emri i një roli te një marrës konkret, p.sh. {\"teamleader\": \"group:teamleaders\"}. Rolet pa lidhje udhëtojnë të pazgjidhura si role:.",
+ "Optional on a fixed rule, required on observedShift: {whenWeekday: weekday name or ISO 1..7, days: integer}.": "Opsionale te rregulli fixed, e detyrueshme te observedShift: {whenWeekday: emri i ditës ose ISO 1..7, days: numër i plotë}.",
+ "Ordered rungs: {key, trigger (preBreach|slaBreached), offset, offsetUnit (hours|businessDays|calendarDays), notifyRole[], escalateToRole[], priority, message, openIncident}.": "Shkallë të renditura: {key, trigger (preBreach|slaBreached), offset, offsetUnit (hours|businessDays|calendarDays), notifyRole[], escalateToRole[], priority, message, openIncident}.",
+ "Priority": "Përparësia",
+ "Role bindings": "Lidhjet e roleve",
+ "Roles the matter is escalated to at this rung.": "Rolet te të cilat çështja përshkallëzohet në këtë shkallë.",
+ "Roles told at this rung; handler is the subject's own performer.": "Rolet e njoftuara në këtë shkallë; handler është personi që trajton çështjen.",
+ "Rungs": "Shkallët",
+ "Stable rung identity, e.g. preBreach:14:calendarDays; derived from trigger, offset and unit when absent.": "Identiteti i qëndrueshëm i shkallës, p.sh. preBreach:14:calendarDays; kur mungon, rrjedh nga shkrehësi, zhvendosja dhe njësia.",
+ "The calendar's stable name, referenced by a timer's calendar_slug.": "Emri i qëndrueshëm i kalendarit, të cilit një kohëmatës i referohet me calendar_slug.",
+ "The closed date, Y-m-d.": "Data e mbylljes, Y-m-d.",
+ "The holiday's name.": "Emri i festës.",
+ "The ladder's stable name, referenced by a timer's ladder_slug.": "Emri i qëndrueshëm i shkallës, të cilit një kohëmatës i referohet me ladder_slug.",
+ "The unit of the offset: the same set the SLA accepts.": "Njësia e zhvendosjes: i njëjti grup që pranon SLA.",
+ "The urgency the raised transition carries.": "Urgjenca që mbart kalimi i shkrehur.",
+ "The weekday (name) on which the date shifts, e.g. sunday for Koningsdag.": "Dita e javës (emri) kur data shtyhet, p.sh. sunday për Koningsdag.",
+ "UUID of the organisation this calendar is configured for. Empty for a shared calendar. The resolution order picks an organisation's calendar when the timer names none.": "UUID i organizatës për të cilën është konfiguruar ky kalendar. Bosh për një kalendar të përbashkët. Nëse kohëmatësi nuk emërton asnjë, radha e zgjidhjes zgjedh kalendarin e organizatës.",
+ "UUID of the organisation this ladder is the default for. Empty for the shared default.": "UUID i organizatës për të cilën kjo shkallë është parazgjedhja. Bosh për parazgjedhjen e përbashkët.",
+ "When weekday": "Nëse bie ditën e",
+ "Whether reaching this rung opens an incident.": "Nëse arritja e kësaj shkalle hap një incident.",
+ "Why the day is closed.": "Pse është e mbyllur ajo ditë.",
+ "Working calendar": "Kalendari i punës",
+ "Working hours in one working day. Makes hours and businessDays commensurable.": "Orët e punës në një ditë pune. I bën orët dhe ditët e punës të krahasueshme.",
+ "Working weekdays": "Ditët e punës të javës",
+ "fixed: a month/day; easter: an offset in days from Easter Sunday; observedShift: a month/day with a required observed shift.": "fixed: muaj dhe ditë; easter: një zhvendosje në ditë nga e diela e Pashkëve; observedShift: muaj dhe ditë me shtyrje të detyrueshme.",
+ "preBreach fires before the deadline, slaBreached at or after it.": "preBreach shkrehet para afatit, slaBreached në afat ose pas tij.",
+ "No such task": "Nuk ka detyrë të tillë",
+ "The task does not exist, or it is not yours to see.": "Detyra nuk ekziston, ose nuk keni të drejtë ta shihni.",
+ "Details": "Detaje",
+ "Due": "Afati",
+ "Assignee": "Caktuar",
+ "Requested by": "Kërkuar nga",
+ "Outcome": "Rezultati",
+ "Ready to claim": "Gati për t'u marrë",
+ "In progress": "Në vazhdim",
+ "Terminated": "Përfunduar",
+ "Normal": "Normale",
+ "Urgent": "Urgjente",
+ "Overdue by 1 day": "1 ditë me vonesë",
+ "Overdue by {days} days": "{days} ditë me vonesë",
+ "Due today": "Afati sot",
+ "Due tomorrow": "Afati nesër",
+ "Due in {days} days": "Afati pas {days} ditësh",
+ "Tasks": "Detyra",
+ "Task": "Detyrë",
+ "Unassigned, open for claiming": "E pacaktuar, e hapur për t'u marrë",
+ "Claim": "Merr",
+ "Complete": "Përfundo",
+ "Complete: {outcome}": "Përfundo: {outcome}",
+ "Could not load the task": "Detyra nuk u ngarkua dot",
+ "The task refused that action": "Detyra e refuzoi atë veprim"
},
"pluralForm": "nplurals=2; plural=(n != 1);",
"plurals": {
diff --git a/l10n/sr.js b/l10n/sr.js
index 41cc91ce44..e4e3cd26c6 100644
--- a/l10n/sr.js
+++ b/l10n/sr.js
@@ -3,11 +3,21 @@ OC.L10N.register(
{
"3": "3",
"30": "30",
+ "from amount {amount}": "od iznosa {amount}",
+ "Gated transition: {transition}": "Nadzirani prelaz: {transition}",
+ "Each declared chain provisions an ordered task sequence when its transition is attempted. Approvers decide in their task inbox, not here.": "Svaki deklarisani lanac otvara uređeni niz zadataka kada se prelaz pokuša. Odobravaoci odlučuju u svom prijemnom sandučetu zadataka, ne ovde.",
+ "Declare x-openregister-approval-chains on this schema to gate a lifecycle transition on approval.": "Deklarišite x-openregister-approval-chains na ovoj šemi da bi prelaz životnog ciklusa zahtevao odobrenje.",
+ "Approval sequences": "Nizovi odobravanja",
"%n entries have no hash yet": "%n unosa još nema heš",
"%n entry has no hash yet": "%n unos još nema heš",
"(Dolphin required)": "(Potreban Dolphin)",
+ "No approval chains declared": "Nema deklarisanih lanaca odobravanja",
"(no subject)": "(bez predmeta)",
"(no title)": "(bez naslova)",
+ "Role {role}": "Uloga {role}",
+ "The transition is applied automatically once every step approves.": "Prelaz se primenjuje automatski čim svaki korak bude odobren.",
+ "The requester may not decide their own approval.": "Podnosilac zahteva ne može odlučivati o sopstvenom odobrenju.",
+ "Tier routing on field: {field}": "Stepenasto usmeravanje po polju: {field}",
"(unnamed)": "(bez naziva)",
"(untitled card)": "(kartica bez naslova)",
"({count} selected)": "({count} odabrano)",
@@ -2738,7 +2748,84 @@ OC.L10N.register(
"_Object successfully deleted_::_Objects successfully deleted_": ["Objekt je uspješno izbrisan","Objekti su uspješno izbrisani","Objekti su uspješno izbrisani"],
"_Purge {count} object from database_::_Purge {count} objects from database_": ["Trajno ukloni {count} objekt iz baze podataka","Trajno ukloni {count} objekta iz baze podataka","Trajno ukloni {count} objekata iz baze podataka"],
"_Restore {count} object_::_Restore {count} objects_": ["Vrati {count} objekt","Vrati {count} objekta","Vrati {count} objekata"],
- "_Successfully restored {count} object_::_Successfully restored {count} objects_": ["Uspješno vraćen {count} objekt","Uspješno vraćena {count} objekta","Uspješno vraćeno {count} objekata"]
+ "_Successfully restored {count} object_::_Successfully restored {count} objects_": ["Uspješno vraćen {count} objekt","Uspješno vraćena {count} objekta","Uspješno vraćeno {count} objekata"],
+ "A message identity the notification subsystem resolves.": "Идентитет поруке који разрешава систем обавештења.",
+ "Computed non-working-date rules. kind fixed: {month, day, name, observedShift?: {whenWeekday, days}}. kind easter: {offset, name}, offset in days from Easter Sunday. kind observedShift: a fixed date with a required shift.": "Израчуната правила нерадних дана. Врста fixed: {month, day, name, observedShift?: {whenWeekday, days}}. Врста easter: {offset, name}, помак у данима од Ускршње недеље. Врста observedShift: непомичан датум са обавезним померањем.",
+ "Date": "Датум",
+ "Day": "Дан",
+ "Day of a fixed or observedShift rule; ignored by an easter rule.": "Дан правила fixed или observedShift; правило easter га занемарује.",
+ "Days": "Дани",
+ "Days from Easter Sunday for an easter rule; ignored by the other kinds.": "Дани од Ускршње недеље за правило easter; друге их врсте занемарују.",
+ "Distance from the deadline, in the offset unit.": "Удаљеност од рока у јединици помака.",
+ "Enumerated one-off closures as {date, name}. Allowed alongside rules; refused as the whole calendar.": "Појединачна затварања набројана као {date, name}. Дозвољена уз правила; одбијена као цео календар.",
+ "Escalate to roles": "Улоге за ескалацију",
+ "Escalation ladder": "Лествица ескалације",
+ "Exception dates": "Изузетни датуми",
+ "Hours per working day": "Сати по радном дану",
+ "How many days the observed date shifts, e.g. -1 for the Saturday before.": "За колико се дана слављени датум помера, нпр. -1 за суботу пре.",
+ "Human-readable title.": "Читљив наслов.",
+ "ISO weekdays (1 = Monday, 7 = Sunday) that are working days.": "ISO дани у недељи (1 = понедељак, 7 = недеља) који су радни.",
+ "Kind": "Врста",
+ "Message": "Порука",
+ "Month": "Месец",
+ "Month of a fixed or observedShift rule; ignored by an easter rule.": "Месец правила fixed или observedShift; правило easter га занемарује.",
+ "Non-working-date rules": "Правила нерадних дана",
+ "Notify roles": "Улоге за обавештење",
+ "Observed shift": "Померање празника",
+ "Offset": "Помак",
+ "Offset unit": "Јединица помака",
+ "Open incident": "Отвори инцидент",
+ "Optional map from a role name to a concrete recipient descriptor, e.g. {\"teamleader\": \"group:teamleaders\"}. Roles without a binding travel unresolved as role:.": "Необавезна мапа имена улоге на конкретног примаоца, нпр. {\"teamleader\": \"group:teamleaders\"}. Улоге без везе путују неразрешене као role:.",
+ "Optional on a fixed rule, required on observedShift: {whenWeekday: weekday name or ISO 1..7, days: integer}.": "Необавезно код правила fixed, обавезно код observedShift: {whenWeekday: име дана или ISO 1..7, days: цео број}.",
+ "Ordered rungs: {key, trigger (preBreach|slaBreached), offset, offsetUnit (hours|businessDays|calendarDays), notifyRole[], escalateToRole[], priority, message, openIncident}.": "Поређане пречке: {key, trigger (preBreach|slaBreached), offset, offsetUnit (hours|businessDays|calendarDays), notifyRole[], escalateToRole[], priority, message, openIncident}.",
+ "Priority": "Приоритет",
+ "Role bindings": "Везе улога",
+ "Roles the matter is escalated to at this rung.": "Улоге на које се предмет на овој пречки ескалира.",
+ "Roles told at this rung; handler is the subject's own performer.": "Улоге обавештене на овој пречки; handler је особа која обрађује предмет.",
+ "Rungs": "Пречке",
+ "Stable rung identity, e.g. preBreach:14:calendarDays; derived from trigger, offset and unit when absent.": "Стални идентитет пречке, нпр. preBreach:14:calendarDays; ако недостаје, изводи се из окидача, помака и јединице.",
+ "The calendar's stable name, referenced by a timer's calendar_slug.": "Стално име календара на које се тајмер позива преко calendar_slug.",
+ "The closed date, Y-m-d.": "Датум затварања, Y-m-d.",
+ "The holiday's name.": "Име празника.",
+ "The ladder's stable name, referenced by a timer's ladder_slug.": "Стално име лествице на које се тајмер позива преко ladder_slug.",
+ "The unit of the offset: the same set the SLA accepts.": "Јединица помака: исти скуп који SLA прихвата.",
+ "The urgency the raised transition carries.": "Хитност коју носи покренути прелаз.",
+ "The weekday (name) on which the date shifts, e.g. sunday for Koningsdag.": "Дан у недељи (име) на који се датум помера, нпр. sunday за Koningsdag.",
+ "UUID of the organisation this calendar is configured for. Empty for a shared calendar. The resolution order picks an organisation's calendar when the timer names none.": "UUID организације за коју је овај календар подешен. Празно за дељени календар. Ако тајмер не именује ниједан, редослед разрешавања бира календар организације.",
+ "UUID of the organisation this ladder is the default for. Empty for the shared default.": "UUID организације којој је ова лествица подразумевана. Празно за дељену подразумевану.",
+ "When weekday": "Ако падне у",
+ "Whether reaching this rung opens an incident.": "Да ли досезање ове пречке отвара инцидент.",
+ "Why the day is closed.": "Зашто је дан затворен.",
+ "Working calendar": "Радни календар",
+ "Working hours in one working day. Makes hours and businessDays commensurable.": "Радни сати у једном радном дану. Чини сате и радне дане упоредивима.",
+ "Working weekdays": "Радни дани у недељи",
+ "fixed: a month/day; easter: an offset in days from Easter Sunday; observedShift: a month/day with a required observed shift.": "fixed: месец и дан; easter: помак у данима од Ускршње недеље; observedShift: месец и дан са обавезним померањем.",
+ "preBreach fires before the deadline, slaBreached at or after it.": "preBreach се окида пре рока, slaBreached на рок или после њега.",
+ "No such task": "Нема таквог задатка",
+ "The task does not exist, or it is not yours to see.": "Задатак не постоји или немате право да га видите.",
+ "Details": "Детаљи",
+ "Due": "Рок",
+ "Assignee": "Додељено",
+ "Requested by": "Затражио",
+ "Outcome": "Исход",
+ "Ready to claim": "Спремно за преузимање",
+ "In progress": "У току",
+ "Terminated": "Прекинуто",
+ "Normal": "Нормално",
+ "Urgent": "Хитно",
+ "Overdue by 1 day": "Касни 1 дан",
+ "Overdue by {days} days": "Касни {days} дана",
+ "Due today": "Рок је данас",
+ "Due tomorrow": "Рок је сутра",
+ "Due in {days} days": "Рок за {days} дана",
+ "Tasks": "Задаци",
+ "Task": "Задатак",
+ "Unassigned, open for claiming": "Недодељено, отворено за преузимање",
+ "Claim": "Преузми",
+ "Complete": "Заврши",
+ "Complete: {outcome}": "Заврши: {outcome}",
+ "Could not load the task": "Задатак није могао да се учита",
+ "The task refused that action": "Задатак је одбио ту радњу"
},
"nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);"
)
diff --git a/l10n/sr.json b/l10n/sr.json
index 6f7c4b6337..8c549b5420 100644
--- a/l10n/sr.json
+++ b/l10n/sr.json
@@ -1,10 +1,20 @@
{
"translations": {
+ "from amount {amount}": "od iznosa {amount}",
+ "Gated transition: {transition}": "Nadzirani prelaz: {transition}",
+ "Each declared chain provisions an ordered task sequence when its transition is attempted. Approvers decide in their task inbox, not here.": "Svaki deklarisani lanac otvara uređeni niz zadataka kada se prelaz pokuša. Odobravaoci odlučuju u svom prijemnom sandučetu zadataka, ne ovde.",
+ "Declare x-openregister-approval-chains on this schema to gate a lifecycle transition on approval.": "Deklarišite x-openregister-approval-chains na ovoj šemi da bi prelaz životnog ciklusa zahtevao odobrenje.",
+ "Approval sequences": "Nizovi odobravanja",
"%n entries have no hash yet": "%n unosa još nema heš",
"%n entry has no hash yet": "%n unos još nema heš",
"(Dolphin required)": "(Potreban Dolphin)",
+ "No approval chains declared": "Nema deklarisanih lanaca odobravanja",
"(no subject)": "(bez predmeta)",
"(no title)": "(bez naslova)",
+ "Role {role}": "Uloga {role}",
+ "The transition is applied automatically once every step approves.": "Prelaz se primenjuje automatski čim svaki korak bude odobren.",
+ "The requester may not decide their own approval.": "Podnosilac zahteva ne može odlučivati o sopstvenom odobrenju.",
+ "Tier routing on field: {field}": "Stepenasto usmeravanje po polju: {field}",
"(unnamed)": "(bez naziva)",
"(untitled card)": "(kartica bez naslova)",
"({count} selected)": "({count} odabrano)",
@@ -2801,7 +2811,84 @@
"Uspješno vraćen {count} objekt",
"Uspješno vraćena {count} objekta",
"Uspješno vraćeno {count} objekata"
- ]
+ ],
+ "A message identity the notification subsystem resolves.": "Идентитет поруке који разрешава систем обавештења.",
+ "Computed non-working-date rules. kind fixed: {month, day, name, observedShift?: {whenWeekday, days}}. kind easter: {offset, name}, offset in days from Easter Sunday. kind observedShift: a fixed date with a required shift.": "Израчуната правила нерадних дана. Врста fixed: {month, day, name, observedShift?: {whenWeekday, days}}. Врста easter: {offset, name}, помак у данима од Ускршње недеље. Врста observedShift: непомичан датум са обавезним померањем.",
+ "Date": "Датум",
+ "Day": "Дан",
+ "Day of a fixed or observedShift rule; ignored by an easter rule.": "Дан правила fixed или observedShift; правило easter га занемарује.",
+ "Days": "Дани",
+ "Days from Easter Sunday for an easter rule; ignored by the other kinds.": "Дани од Ускршње недеље за правило easter; друге их врсте занемарују.",
+ "Distance from the deadline, in the offset unit.": "Удаљеност од рока у јединици помака.",
+ "Enumerated one-off closures as {date, name}. Allowed alongside rules; refused as the whole calendar.": "Појединачна затварања набројана као {date, name}. Дозвољена уз правила; одбијена као цео календар.",
+ "Escalate to roles": "Улоге за ескалацију",
+ "Escalation ladder": "Лествица ескалације",
+ "Exception dates": "Изузетни датуми",
+ "Hours per working day": "Сати по радном дану",
+ "How many days the observed date shifts, e.g. -1 for the Saturday before.": "За колико се дана слављени датум помера, нпр. -1 за суботу пре.",
+ "Human-readable title.": "Читљив наслов.",
+ "ISO weekdays (1 = Monday, 7 = Sunday) that are working days.": "ISO дани у недељи (1 = понедељак, 7 = недеља) који су радни.",
+ "Kind": "Врста",
+ "Message": "Порука",
+ "Month": "Месец",
+ "Month of a fixed or observedShift rule; ignored by an easter rule.": "Месец правила fixed или observedShift; правило easter га занемарује.",
+ "Non-working-date rules": "Правила нерадних дана",
+ "Notify roles": "Улоге за обавештење",
+ "Observed shift": "Померање празника",
+ "Offset": "Помак",
+ "Offset unit": "Јединица помака",
+ "Open incident": "Отвори инцидент",
+ "Optional map from a role name to a concrete recipient descriptor, e.g. {\"teamleader\": \"group:teamleaders\"}. Roles without a binding travel unresolved as role:.": "Необавезна мапа имена улоге на конкретног примаоца, нпр. {\"teamleader\": \"group:teamleaders\"}. Улоге без везе путују неразрешене као role:.",
+ "Optional on a fixed rule, required on observedShift: {whenWeekday: weekday name or ISO 1..7, days: integer}.": "Необавезно код правила fixed, обавезно код observedShift: {whenWeekday: име дана или ISO 1..7, days: цео број}.",
+ "Ordered rungs: {key, trigger (preBreach|slaBreached), offset, offsetUnit (hours|businessDays|calendarDays), notifyRole[], escalateToRole[], priority, message, openIncident}.": "Поређане пречке: {key, trigger (preBreach|slaBreached), offset, offsetUnit (hours|businessDays|calendarDays), notifyRole[], escalateToRole[], priority, message, openIncident}.",
+ "Priority": "Приоритет",
+ "Role bindings": "Везе улога",
+ "Roles the matter is escalated to at this rung.": "Улоге на које се предмет на овој пречки ескалира.",
+ "Roles told at this rung; handler is the subject's own performer.": "Улоге обавештене на овој пречки; handler је особа која обрађује предмет.",
+ "Rungs": "Пречке",
+ "Stable rung identity, e.g. preBreach:14:calendarDays; derived from trigger, offset and unit when absent.": "Стални идентитет пречке, нпр. preBreach:14:calendarDays; ако недостаје, изводи се из окидача, помака и јединице.",
+ "The calendar's stable name, referenced by a timer's calendar_slug.": "Стално име календара на које се тајмер позива преко calendar_slug.",
+ "The closed date, Y-m-d.": "Датум затварања, Y-m-d.",
+ "The holiday's name.": "Име празника.",
+ "The ladder's stable name, referenced by a timer's ladder_slug.": "Стално име лествице на које се тајмер позива преко ladder_slug.",
+ "The unit of the offset: the same set the SLA accepts.": "Јединица помака: исти скуп који SLA прихвата.",
+ "The urgency the raised transition carries.": "Хитност коју носи покренути прелаз.",
+ "The weekday (name) on which the date shifts, e.g. sunday for Koningsdag.": "Дан у недељи (име) на који се датум помера, нпр. sunday за Koningsdag.",
+ "UUID of the organisation this calendar is configured for. Empty for a shared calendar. The resolution order picks an organisation's calendar when the timer names none.": "UUID организације за коју је овај календар подешен. Празно за дељени календар. Ако тајмер не именује ниједан, редослед разрешавања бира календар организације.",
+ "UUID of the organisation this ladder is the default for. Empty for the shared default.": "UUID организације којој је ова лествица подразумевана. Празно за дељену подразумевану.",
+ "When weekday": "Ако падне у",
+ "Whether reaching this rung opens an incident.": "Да ли досезање ове пречке отвара инцидент.",
+ "Why the day is closed.": "Зашто је дан затворен.",
+ "Working calendar": "Радни календар",
+ "Working hours in one working day. Makes hours and businessDays commensurable.": "Радни сати у једном радном дану. Чини сате и радне дане упоредивима.",
+ "Working weekdays": "Радни дани у недељи",
+ "fixed: a month/day; easter: an offset in days from Easter Sunday; observedShift: a month/day with a required observed shift.": "fixed: месец и дан; easter: помак у данима од Ускршње недеље; observedShift: месец и дан са обавезним померањем.",
+ "preBreach fires before the deadline, slaBreached at or after it.": "preBreach се окида пре рока, slaBreached на рок или после њега.",
+ "No such task": "Нема таквог задатка",
+ "The task does not exist, or it is not yours to see.": "Задатак не постоји или немате право да га видите.",
+ "Details": "Детаљи",
+ "Due": "Рок",
+ "Assignee": "Додељено",
+ "Requested by": "Затражио",
+ "Outcome": "Исход",
+ "Ready to claim": "Спремно за преузимање",
+ "In progress": "У току",
+ "Terminated": "Прекинуто",
+ "Normal": "Нормално",
+ "Urgent": "Хитно",
+ "Overdue by 1 day": "Касни 1 дан",
+ "Overdue by {days} days": "Касни {days} дана",
+ "Due today": "Рок је данас",
+ "Due tomorrow": "Рок је сутра",
+ "Due in {days} days": "Рок за {days} дана",
+ "Tasks": "Задаци",
+ "Task": "Задатак",
+ "Unassigned, open for claiming": "Недодељено, отворено за преузимање",
+ "Claim": "Преузми",
+ "Complete": "Заврши",
+ "Complete: {outcome}": "Заврши: {outcome}",
+ "Could not load the task": "Задатак није могао да се учита",
+ "The task refused that action": "Задатак је одбио ту радњу"
},
"pluralForm": "nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);",
"plurals": {
diff --git a/l10n/sv.js b/l10n/sv.js
index 4e1d8bafb0..ff3779ce18 100644
--- a/l10n/sv.js
+++ b/l10n/sv.js
@@ -3,11 +3,21 @@ OC.L10N.register(
{
"3": "3",
"30": "30",
+ "from amount {amount}": "från belopp {amount}",
+ "Gated transition: {transition}": "Bevakad övergång: {transition}",
+ "Each declared chain provisions an ordered task sequence when its transition is attempted. Approvers decide in their task inbox, not here.": "Varje deklarerad kedja öppnar en ordnad uppgiftssekvens när övergången försöks. Godkännare beslutar i sin uppgiftsinkorg, inte här.",
+ "Declare x-openregister-approval-chains on this schema to gate a lifecycle transition on approval.": "Deklarera x-openregister-approval-chains på detta schema för att kräva godkännande före en livscykelövergång.",
+ "Approval sequences": "Godkännandesekvenser",
"%n entries have no hash yet": "%n poster saknar ännu hash",
"%n entry has no hash yet": "%n post saknar ännu hash",
"(Dolphin required)": "(Dolphin krävs)",
+ "No approval chains declared": "Inga godkännandekedjor deklarerade",
"(no subject)": "(inget ämne)",
"(no title)": "(ingen titel)",
+ "Role {role}": "Roll {role}",
+ "The transition is applied automatically once every step approves.": "Övergången tillämpas automatiskt när varje steg är godkänt.",
+ "The requester may not decide their own approval.": "Beställaren får inte avgöra sitt eget godkännande.",
+ "Tier routing on field: {field}": "Stegvis dirigering på fältet: {field}",
"(unnamed)": "(namnlös)",
"(untitled card)": "(namnlöst kort)",
"({count} selected)": "({count} valda)",
@@ -2738,7 +2748,84 @@ OC.L10N.register(
"_Object successfully deleted_::_Objects successfully deleted_": ["Objekt togs bort","Objekt togs bort"],
"_Purge {count} object from database_::_Purge {count} objects from database_": ["Rensa {count} objekt från databasen","Rensa {count} objekt från databasen"],
"_Restore {count} object_::_Restore {count} objects_": ["Återställ {count} objekt","Återställ {count} objekt"],
- "_Successfully restored {count} object_::_Successfully restored {count} objects_": ["{count} objekt återställdes","{count} objekt återställdes"]
+ "_Successfully restored {count} object_::_Successfully restored {count} objects_": ["{count} objekt återställdes","{count} objekt återställdes"],
+ "A message identity the notification subsystem resolves.": "A message identity the notification subsystem resolves.",
+ "Computed non-working-date rules. kind fixed: {month, day, name, observedShift?: {whenWeekday, days}}. kind easter: {offset, name}, offset in days from Easter Sunday. kind observedShift: a fixed date with a required shift.": "Computed non-working-date rules. kind fixed: {month, day, name, observedShift?: {whenWeekday, days}}. kind easter: {offset, name}, offset in days from Easter Sunday. kind observedShift: a fixed date with a required shift.",
+ "Date": "Date",
+ "Day": "Day",
+ "Day of a fixed or observedShift rule; ignored by an easter rule.": "Day of a fixed or observedShift rule; ignored by an easter rule.",
+ "Days": "Days",
+ "Days from Easter Sunday for an easter rule; ignored by the other kinds.": "Days from Easter Sunday for an easter rule; ignored by the other kinds.",
+ "Distance from the deadline, in the offset unit.": "Distance from the deadline, in the offset unit.",
+ "Enumerated one-off closures as {date, name}. Allowed alongside rules; refused as the whole calendar.": "Enumerated one-off closures as {date, name}. Allowed alongside rules; refused as the whole calendar.",
+ "Escalate to roles": "Escalate to roles",
+ "Escalation ladder": "Escalation ladder",
+ "Exception dates": "Exception dates",
+ "Hours per working day": "Hours per working day",
+ "How many days the observed date shifts, e.g. -1 for the Saturday before.": "How many days the observed date shifts, e.g. -1 for the Saturday before.",
+ "Human-readable title.": "Human-readable title.",
+ "ISO weekdays (1 = Monday, 7 = Sunday) that are working days.": "ISO weekdays (1 = Monday, 7 = Sunday) that are working days.",
+ "Kind": "Kind",
+ "Message": "Message",
+ "Month": "Month",
+ "Month of a fixed or observedShift rule; ignored by an easter rule.": "Month of a fixed or observedShift rule; ignored by an easter rule.",
+ "Non-working-date rules": "Non-working-date rules",
+ "Notify roles": "Notify roles",
+ "Observed shift": "Observed shift",
+ "Offset": "Offset",
+ "Offset unit": "Offset unit",
+ "Open incident": "Open incident",
+ "Optional map from a role name to a concrete recipient descriptor, e.g. {\"teamleader\": \"group:teamleaders\"}. Roles without a binding travel unresolved as role:.": "Optional map from a role name to a concrete recipient descriptor, e.g. {\"teamleader\": \"group:teamleaders\"}. Roles without a binding travel unresolved as role:.",
+ "Optional on a fixed rule, required on observedShift: {whenWeekday: weekday name or ISO 1..7, days: integer}.": "Optional on a fixed rule, required on observedShift: {whenWeekday: weekday name or ISO 1..7, days: integer}.",
+ "Ordered rungs: {key, trigger (preBreach|slaBreached), offset, offsetUnit (hours|businessDays|calendarDays), notifyRole[], escalateToRole[], priority, message, openIncident}.": "Ordered rungs: {key, trigger (preBreach|slaBreached), offset, offsetUnit (hours|businessDays|calendarDays), notifyRole[], escalateToRole[], priority, message, openIncident}.",
+ "Priority": "Priority",
+ "Role bindings": "Role bindings",
+ "Roles the matter is escalated to at this rung.": "Roles the matter is escalated to at this rung.",
+ "Roles told at this rung; handler is the subject's own performer.": "Roles told at this rung; handler is the subject's own performer.",
+ "Rungs": "Rungs",
+ "Stable rung identity, e.g. preBreach:14:calendarDays; derived from trigger, offset and unit when absent.": "Stable rung identity, e.g. preBreach:14:calendarDays; derived from trigger, offset and unit when absent.",
+ "The calendar's stable name, referenced by a timer's calendar_slug.": "The calendar's stable name, referenced by a timer's calendar_slug.",
+ "The closed date, Y-m-d.": "The closed date, Y-m-d.",
+ "The holiday's name.": "The holiday's name.",
+ "The ladder's stable name, referenced by a timer's ladder_slug.": "The ladder's stable name, referenced by a timer's ladder_slug.",
+ "The unit of the offset: the same set the SLA accepts.": "The unit of the offset: the same set the SLA accepts.",
+ "The urgency the raised transition carries.": "The urgency the raised transition carries.",
+ "The weekday (name) on which the date shifts, e.g. sunday for Koningsdag.": "The weekday (name) on which the date shifts, e.g. sunday for Koningsdag.",
+ "UUID of the organisation this calendar is configured for. Empty for a shared calendar. The resolution order picks an organisation's calendar when the timer names none.": "UUID of the organisation this calendar is configured for. Empty for a shared calendar. The resolution order picks an organisation's calendar when the timer names none.",
+ "UUID of the organisation this ladder is the default for. Empty for the shared default.": "UUID of the organisation this ladder is the default for. Empty for the shared default.",
+ "When weekday": "When weekday",
+ "Whether reaching this rung opens an incident.": "Whether reaching this rung opens an incident.",
+ "Why the day is closed.": "Why the day is closed.",
+ "Working calendar": "Working calendar",
+ "Working hours in one working day. Makes hours and businessDays commensurable.": "Working hours in one working day. Makes hours and businessDays commensurable.",
+ "Working weekdays": "Working weekdays",
+ "fixed: a month/day; easter: an offset in days from Easter Sunday; observedShift: a month/day with a required observed shift.": "fixed: a month/day; easter: an offset in days from Easter Sunday; observedShift: a month/day with a required observed shift.",
+ "preBreach fires before the deadline, slaBreached at or after it.": "preBreach fires before the deadline, slaBreached at or after it.",
+ "No such task": "Ingen sådan uppgift",
+ "The task does not exist, or it is not yours to see.": "Uppgiften finns inte, eller så får du inte se den.",
+ "Details": "Detaljer",
+ "Due": "Förfaller",
+ "Assignee": "Tilldelad",
+ "Requested by": "Begärd av",
+ "Outcome": "Utfall",
+ "Ready to claim": "Redo att ta",
+ "In progress": "Pågår",
+ "Terminated": "Avslutad",
+ "Normal": "Normal",
+ "Urgent": "Brådskande",
+ "Overdue by 1 day": "1 dag försenad",
+ "Overdue by {days} days": "{days} dagar försenad",
+ "Due today": "Förfaller i dag",
+ "Due tomorrow": "Förfaller i morgon",
+ "Due in {days} days": "Förfaller om {days} dagar",
+ "Tasks": "Uppgifter",
+ "Task": "Uppgift",
+ "Unassigned, open for claiming": "Otilldelad, öppen att ta",
+ "Claim": "Ta",
+ "Complete": "Slutför",
+ "Complete: {outcome}": "Slutför: {outcome}",
+ "Could not load the task": "Kunde inte läsa in uppgiften",
+ "The task refused that action": "Uppgiften nekade den åtgärden"
},
"nplurals=2; plural=(n != 1);"
)
diff --git a/l10n/sv.json b/l10n/sv.json
index e5f0e7cc06..7d1cc331b8 100644
--- a/l10n/sv.json
+++ b/l10n/sv.json
@@ -1,10 +1,20 @@
{
"translations": {
+ "from amount {amount}": "från belopp {amount}",
+ "Gated transition: {transition}": "Bevakad övergång: {transition}",
+ "Each declared chain provisions an ordered task sequence when its transition is attempted. Approvers decide in their task inbox, not here.": "Varje deklarerad kedja öppnar en ordnad uppgiftssekvens när övergången försöks. Godkännare beslutar i sin uppgiftsinkorg, inte här.",
+ "Declare x-openregister-approval-chains on this schema to gate a lifecycle transition on approval.": "Deklarera x-openregister-approval-chains på detta schema för att kräva godkännande före en livscykelövergång.",
+ "Approval sequences": "Godkännandesekvenser",
"%n entries have no hash yet": "%n poster saknar ännu hash",
"%n entry has no hash yet": "%n post saknar ännu hash",
"(Dolphin required)": "(Dolphin krävs)",
+ "No approval chains declared": "Inga godkännandekedjor deklarerade",
"(no subject)": "(inget ämne)",
"(no title)": "(ingen titel)",
+ "Role {role}": "Roll {role}",
+ "The transition is applied automatically once every step approves.": "Övergången tillämpas automatiskt när varje steg är godkänt.",
+ "The requester may not decide their own approval.": "Beställaren får inte avgöra sitt eget godkännande.",
+ "Tier routing on field: {field}": "Stegvis dirigering på fältet: {field}",
"(unnamed)": "(namnlös)",
"(untitled card)": "(namnlöst kort)",
"({count} selected)": "({count} valda)",
@@ -2785,7 +2795,84 @@
"_Successfully restored {count} object_::_Successfully restored {count} objects_": [
"{count} objekt återställdes",
"{count} objekt återställdes"
- ]
+ ],
+ "A message identity the notification subsystem resolves.": "A message identity the notification subsystem resolves.",
+ "Computed non-working-date rules. kind fixed: {month, day, name, observedShift?: {whenWeekday, days}}. kind easter: {offset, name}, offset in days from Easter Sunday. kind observedShift: a fixed date with a required shift.": "Computed non-working-date rules. kind fixed: {month, day, name, observedShift?: {whenWeekday, days}}. kind easter: {offset, name}, offset in days from Easter Sunday. kind observedShift: a fixed date with a required shift.",
+ "Date": "Date",
+ "Day": "Day",
+ "Day of a fixed or observedShift rule; ignored by an easter rule.": "Day of a fixed or observedShift rule; ignored by an easter rule.",
+ "Days": "Days",
+ "Days from Easter Sunday for an easter rule; ignored by the other kinds.": "Days from Easter Sunday for an easter rule; ignored by the other kinds.",
+ "Distance from the deadline, in the offset unit.": "Distance from the deadline, in the offset unit.",
+ "Enumerated one-off closures as {date, name}. Allowed alongside rules; refused as the whole calendar.": "Enumerated one-off closures as {date, name}. Allowed alongside rules; refused as the whole calendar.",
+ "Escalate to roles": "Escalate to roles",
+ "Escalation ladder": "Escalation ladder",
+ "Exception dates": "Exception dates",
+ "Hours per working day": "Hours per working day",
+ "How many days the observed date shifts, e.g. -1 for the Saturday before.": "How many days the observed date shifts, e.g. -1 for the Saturday before.",
+ "Human-readable title.": "Human-readable title.",
+ "ISO weekdays (1 = Monday, 7 = Sunday) that are working days.": "ISO weekdays (1 = Monday, 7 = Sunday) that are working days.",
+ "Kind": "Kind",
+ "Message": "Message",
+ "Month": "Month",
+ "Month of a fixed or observedShift rule; ignored by an easter rule.": "Month of a fixed or observedShift rule; ignored by an easter rule.",
+ "Non-working-date rules": "Non-working-date rules",
+ "Notify roles": "Notify roles",
+ "Observed shift": "Observed shift",
+ "Offset": "Offset",
+ "Offset unit": "Offset unit",
+ "Open incident": "Open incident",
+ "Optional map from a role name to a concrete recipient descriptor, e.g. {\"teamleader\": \"group:teamleaders\"}. Roles without a binding travel unresolved as role:.": "Optional map from a role name to a concrete recipient descriptor, e.g. {\"teamleader\": \"group:teamleaders\"}. Roles without a binding travel unresolved as role:.",
+ "Optional on a fixed rule, required on observedShift: {whenWeekday: weekday name or ISO 1..7, days: integer}.": "Optional on a fixed rule, required on observedShift: {whenWeekday: weekday name or ISO 1..7, days: integer}.",
+ "Ordered rungs: {key, trigger (preBreach|slaBreached), offset, offsetUnit (hours|businessDays|calendarDays), notifyRole[], escalateToRole[], priority, message, openIncident}.": "Ordered rungs: {key, trigger (preBreach|slaBreached), offset, offsetUnit (hours|businessDays|calendarDays), notifyRole[], escalateToRole[], priority, message, openIncident}.",
+ "Priority": "Priority",
+ "Role bindings": "Role bindings",
+ "Roles the matter is escalated to at this rung.": "Roles the matter is escalated to at this rung.",
+ "Roles told at this rung; handler is the subject's own performer.": "Roles told at this rung; handler is the subject's own performer.",
+ "Rungs": "Rungs",
+ "Stable rung identity, e.g. preBreach:14:calendarDays; derived from trigger, offset and unit when absent.": "Stable rung identity, e.g. preBreach:14:calendarDays; derived from trigger, offset and unit when absent.",
+ "The calendar's stable name, referenced by a timer's calendar_slug.": "The calendar's stable name, referenced by a timer's calendar_slug.",
+ "The closed date, Y-m-d.": "The closed date, Y-m-d.",
+ "The holiday's name.": "The holiday's name.",
+ "The ladder's stable name, referenced by a timer's ladder_slug.": "The ladder's stable name, referenced by a timer's ladder_slug.",
+ "The unit of the offset: the same set the SLA accepts.": "The unit of the offset: the same set the SLA accepts.",
+ "The urgency the raised transition carries.": "The urgency the raised transition carries.",
+ "The weekday (name) on which the date shifts, e.g. sunday for Koningsdag.": "The weekday (name) on which the date shifts, e.g. sunday for Koningsdag.",
+ "UUID of the organisation this calendar is configured for. Empty for a shared calendar. The resolution order picks an organisation's calendar when the timer names none.": "UUID of the organisation this calendar is configured for. Empty for a shared calendar. The resolution order picks an organisation's calendar when the timer names none.",
+ "UUID of the organisation this ladder is the default for. Empty for the shared default.": "UUID of the organisation this ladder is the default for. Empty for the shared default.",
+ "When weekday": "When weekday",
+ "Whether reaching this rung opens an incident.": "Whether reaching this rung opens an incident.",
+ "Why the day is closed.": "Why the day is closed.",
+ "Working calendar": "Working calendar",
+ "Working hours in one working day. Makes hours and businessDays commensurable.": "Working hours in one working day. Makes hours and businessDays commensurable.",
+ "Working weekdays": "Working weekdays",
+ "fixed: a month/day; easter: an offset in days from Easter Sunday; observedShift: a month/day with a required observed shift.": "fixed: a month/day; easter: an offset in days from Easter Sunday; observedShift: a month/day with a required observed shift.",
+ "preBreach fires before the deadline, slaBreached at or after it.": "preBreach fires before the deadline, slaBreached at or after it.",
+ "No such task": "Ingen sådan uppgift",
+ "The task does not exist, or it is not yours to see.": "Uppgiften finns inte, eller så får du inte se den.",
+ "Details": "Detaljer",
+ "Due": "Förfaller",
+ "Assignee": "Tilldelad",
+ "Requested by": "Begärd av",
+ "Outcome": "Utfall",
+ "Ready to claim": "Redo att ta",
+ "In progress": "Pågår",
+ "Terminated": "Avslutad",
+ "Normal": "Normal",
+ "Urgent": "Brådskande",
+ "Overdue by 1 day": "1 dag försenad",
+ "Overdue by {days} days": "{days} dagar försenad",
+ "Due today": "Förfaller i dag",
+ "Due tomorrow": "Förfaller i morgon",
+ "Due in {days} days": "Förfaller om {days} dagar",
+ "Tasks": "Uppgifter",
+ "Task": "Uppgift",
+ "Unassigned, open for claiming": "Otilldelad, öppen att ta",
+ "Claim": "Ta",
+ "Complete": "Slutför",
+ "Complete: {outcome}": "Slutför: {outcome}",
+ "Could not load the task": "Kunde inte läsa in uppgiften",
+ "The task refused that action": "Uppgiften nekade den åtgärden"
},
"pluralForm": "nplurals=2; plural=(n != 1);",
"plurals": {
diff --git a/l10n/tr.js b/l10n/tr.js
index cfd5b26051..fd732d5276 100644
--- a/l10n/tr.js
+++ b/l10n/tr.js
@@ -3,11 +3,21 @@ OC.L10N.register(
{
"3": "3",
"30": "30",
+ "from amount {amount}": "{amount} tutarından itibaren",
+ "Gated transition: {transition}": "Denetimli geçiş: {transition}",
+ "Each declared chain provisions an ordered task sequence when its transition is attempted. Approvers decide in their task inbox, not here.": "Bildirilen her zincir, geçiş denendiğinde sıralı bir görev dizisi açar. Onaylayanlar burada değil, görev gelen kutularında karar verir.",
+ "Declare x-openregister-approval-chains on this schema to gate a lifecycle transition on approval.": "Bir yaşam döngüsü geçişini onaya bağlamak için bu şemada x-openregister-approval-chains bildirin.",
+ "Approval sequences": "Onay dizileri",
"%n entries have no hash yet": "%n kaydın henüz karması yok",
"%n entry has no hash yet": "%n kaydın henüz karması yok",
"(Dolphin required)": "(Dolphin gerekli)",
+ "No approval chains declared": "Bildirilmiş onay zinciri yok",
"(no subject)": "(konu yok)",
"(no title)": "(başlık yok)",
+ "Role {role}": "Rol {role}",
+ "The transition is applied automatically once every step approves.": "Her adım onaylandığında geçiş otomatik olarak uygulanır.",
+ "The requester may not decide their own approval.": "Talep eden, kendi onayı hakkında karar veremez.",
+ "Tier routing on field: {field}": "Alan üzerinden kademeli yönlendirme: {field}",
"(unnamed)": "(adsız)",
"(untitled card)": "(başlıksız kart)",
"({count} selected)": "({count} seçildi)",
@@ -2738,7 +2748,84 @@ OC.L10N.register(
"_Object successfully deleted_::_Objects successfully deleted_": ["Nesne başarıyla silindi","Nesneler başarıyla silindi"],
"_Purge {count} object from database_::_Purge {count} objects from database_": ["Veritabanından {count} nesneyi temizle","Veritabanından {count} nesneyi temizle"],
"_Restore {count} object_::_Restore {count} objects_": ["{count} nesneyi geri yükle","{count} nesneyi geri yükle"],
- "_Successfully restored {count} object_::_Successfully restored {count} objects_": ["{count} nesne başarıyla geri yüklendi","{count} nesne başarıyla geri yüklendi"]
+ "_Successfully restored {count} object_::_Successfully restored {count} objects_": ["{count} nesne başarıyla geri yüklendi","{count} nesne başarıyla geri yüklendi"],
+ "A message identity the notification subsystem resolves.": "Bildirim sisteminin çözdüğü bir ileti kimliği.",
+ "Computed non-working-date rules. kind fixed: {month, day, name, observedShift?: {whenWeekday, days}}. kind easter: {offset, name}, offset in days from Easter Sunday. kind observedShift: a fixed date with a required shift.": "Hesaplanan tatil günü kuralları. Tür fixed: {month, day, name, observedShift?: {whenWeekday, days}}. Tür easter: {offset, name}, Paskalya pazarından gün olarak kaydırma. Tür observedShift: zorunlu aktarması olan sabit bir tarih.",
+ "Date": "Tarih",
+ "Day": "Gün",
+ "Day of a fixed or observedShift rule; ignored by an easter rule.": "fixed veya observedShift kuralının günü; easter kuralı bunu yok sayar.",
+ "Days": "Günler",
+ "Days from Easter Sunday for an easter rule; ignored by the other kinds.": "easter kuralı için Paskalya pazarından gün sayısı; diğer türler bunu yok sayar.",
+ "Distance from the deadline, in the offset unit.": "Kaydırma biriminde süreye olan uzaklık.",
+ "Enumerated one-off closures as {date, name}. Allowed alongside rules; refused as the whole calendar.": "{date, name} biçiminde sıralanan tek seferlik kapanışlar. Kuralların yanında izinli; takvimin tamamı olarak reddedilir.",
+ "Escalate to roles": "Yükseltilecek roller",
+ "Escalation ladder": "Yükseltme merdiveni",
+ "Exception dates": "İstisna tarihleri",
+ "Hours per working day": "İş günü başına saat",
+ "How many days the observed date shifts, e.g. -1 for the Saturday before.": "Kutlanan tarihin kaç gün aktarıldığı, örn. önceki cumartesi için -1.",
+ "Human-readable title.": "Okunabilir başlık.",
+ "ISO weekdays (1 = Monday, 7 = Sunday) that are working days.": "İş günü olan ISO hafta günleri (1 = pazartesi, 7 = pazar).",
+ "Kind": "Tür",
+ "Message": "İleti",
+ "Month": "Ay",
+ "Month of a fixed or observedShift rule; ignored by an easter rule.": "fixed veya observedShift kuralının ayı; easter kuralı bunu yok sayar.",
+ "Non-working-date rules": "Tatil günü kuralları",
+ "Notify roles": "Bildirilecek roller",
+ "Observed shift": "Tatilin aktarılması",
+ "Offset": "Kaydırma",
+ "Offset unit": "Kaydırma birimi",
+ "Open incident": "Olay aç",
+ "Optional map from a role name to a concrete recipient descriptor, e.g. {\"teamleader\": \"group:teamleaders\"}. Roles without a binding travel unresolved as role:.": "Rol adından somut bir alıcıya isteğe bağlı eşleme, örn. {\"teamleader\": \"group:teamleaders\"}. Bağlaması olmayan roller role: olarak çözülmeden ilerler.",
+ "Optional on a fixed rule, required on observedShift: {whenWeekday: weekday name or ISO 1..7, days: integer}.": "fixed kuralında isteğe bağlı, observedShift kuralında zorunlu: {whenWeekday: gün adı veya ISO 1..7, days: tam sayı}.",
+ "Ordered rungs: {key, trigger (preBreach|slaBreached), offset, offsetUnit (hours|businessDays|calendarDays), notifyRole[], escalateToRole[], priority, message, openIncident}.": "Sıralı basamaklar: {key, trigger (preBreach|slaBreached), offset, offsetUnit (hours|businessDays|calendarDays), notifyRole[], escalateToRole[], priority, message, openIncident}.",
+ "Priority": "Öncelik",
+ "Role bindings": "Rol bağlamaları",
+ "Roles the matter is escalated to at this rung.": "Konunun bu basamakta yükseltildiği roller.",
+ "Roles told at this rung; handler is the subject's own performer.": "Bu basamakta bildirilen roller; handler, işi yürüten kişidir.",
+ "Rungs": "Basamaklar",
+ "Stable rung identity, e.g. preBreach:14:calendarDays; derived from trigger, offset and unit when absent.": "Basamağın kalıcı kimliği, örn. preBreach:14:calendarDays; yoksa tetikleyici, kaydırma ve birimden türetilir.",
+ "The calendar's stable name, referenced by a timer's calendar_slug.": "Takvimin kalıcı adı; bir zamanlayıcı ona calendar_slug ile başvurur.",
+ "The closed date, Y-m-d.": "Kapalı tarih, Y-m-d.",
+ "The holiday's name.": "Tatilin adı.",
+ "The ladder's stable name, referenced by a timer's ladder_slug.": "Merdivenin kalıcı adı; bir zamanlayıcı ona ladder_slug ile başvurur.",
+ "The unit of the offset: the same set the SLA accepts.": "Kaydırmanın birimi: SLA'nın kabul ettiği aynı küme.",
+ "The urgency the raised transition carries.": "Tetiklenen geçişin taşıdığı aciliyet.",
+ "The weekday (name) on which the date shifts, e.g. sunday for Koningsdag.": "Tarihin aktarıldığı hafta günü (ad), örn. Koningsdag için sunday.",
+ "UUID of the organisation this calendar is configured for. Empty for a shared calendar. The resolution order picks an organisation's calendar when the timer names none.": "Bu takvimin yapılandırıldığı kuruluşun UUID değeri. Paylaşılan takvimde boş. Zamanlayıcı bir takvim adı vermezse çözüm sırası kuruluşun takvimini seçer.",
+ "UUID of the organisation this ladder is the default for. Empty for the shared default.": "Bu merdivenin varsayılan olduğu kuruluşun UUID değeri. Paylaşılan varsayılanda boş.",
+ "When weekday": "Şu güne denk gelirse",
+ "Whether reaching this rung opens an incident.": "Bu basamağa ulaşmanın bir olay açıp açmadığı.",
+ "Why the day is closed.": "Günün neden kapalı olduğu.",
+ "Working calendar": "Çalışma takvimi",
+ "Working hours in one working day. Makes hours and businessDays commensurable.": "Bir iş günündeki çalışma saatleri. Saatler ile iş günlerini karşılaştırılabilir kılar.",
+ "Working weekdays": "Haftanın iş günleri",
+ "fixed: a month/day; easter: an offset in days from Easter Sunday; observedShift: a month/day with a required observed shift.": "fixed: ay ve gün; easter: Paskalya pazarından gün olarak kaydırma; observedShift: zorunlu aktarması olan ay ve gün.",
+ "preBreach fires before the deadline, slaBreached at or after it.": "preBreach süre dolmadan önce, slaBreached süre dolduğunda veya sonrasında tetiklenir.",
+ "No such task": "Böyle bir görev yok",
+ "The task does not exist, or it is not yours to see.": "Görev yok ya da görme yetkiniz yok.",
+ "Details": "Ayrıntılar",
+ "Due": "Son tarih",
+ "Assignee": "Atanan",
+ "Requested by": "Talep eden",
+ "Outcome": "Sonuç",
+ "Ready to claim": "Üstlenilmeye hazır",
+ "In progress": "Devam ediyor",
+ "Terminated": "Sonlandırıldı",
+ "Normal": "Normal",
+ "Urgent": "Acil",
+ "Overdue by 1 day": "1 gün gecikmiş",
+ "Overdue by {days} days": "{days} gün gecikmiş",
+ "Due today": "Bugün teslim",
+ "Due tomorrow": "Yarın teslim",
+ "Due in {days} days": "{days} gün içinde teslim",
+ "Tasks": "Görevler",
+ "Task": "Görev",
+ "Unassigned, open for claiming": "Atanmamış, üstlenmeye açık",
+ "Claim": "Üstlen",
+ "Complete": "Tamamla",
+ "Complete: {outcome}": "Tamamla: {outcome}",
+ "Could not load the task": "Görev yüklenemedi",
+ "The task refused that action": "Görev bu eylemi reddetti"
},
"nplurals=2; plural=(n != 1);"
)
diff --git a/l10n/tr.json b/l10n/tr.json
index 09c952f238..14cd4305d2 100644
--- a/l10n/tr.json
+++ b/l10n/tr.json
@@ -1,10 +1,20 @@
{
"translations": {
+ "from amount {amount}": "{amount} tutarından itibaren",
+ "Gated transition: {transition}": "Denetimli geçiş: {transition}",
+ "Each declared chain provisions an ordered task sequence when its transition is attempted. Approvers decide in their task inbox, not here.": "Bildirilen her zincir, geçiş denendiğinde sıralı bir görev dizisi açar. Onaylayanlar burada değil, görev gelen kutularında karar verir.",
+ "Declare x-openregister-approval-chains on this schema to gate a lifecycle transition on approval.": "Bir yaşam döngüsü geçişini onaya bağlamak için bu şemada x-openregister-approval-chains bildirin.",
+ "Approval sequences": "Onay dizileri",
"%n entries have no hash yet": "%n kaydın henüz karması yok",
"%n entry has no hash yet": "%n kaydın henüz karması yok",
"(Dolphin required)": "(Dolphin gerekli)",
+ "No approval chains declared": "Bildirilmiş onay zinciri yok",
"(no subject)": "(konu yok)",
"(no title)": "(başlık yok)",
+ "Role {role}": "Rol {role}",
+ "The transition is applied automatically once every step approves.": "Her adım onaylandığında geçiş otomatik olarak uygulanır.",
+ "The requester may not decide their own approval.": "Talep eden, kendi onayı hakkında karar veremez.",
+ "Tier routing on field: {field}": "Alan üzerinden kademeli yönlendirme: {field}",
"(unnamed)": "(adsız)",
"(untitled card)": "(başlıksız kart)",
"({count} selected)": "({count} seçildi)",
@@ -2785,7 +2795,84 @@
"_Successfully restored {count} object_::_Successfully restored {count} objects_": [
"{count} nesne başarıyla geri yüklendi",
"{count} nesne başarıyla geri yüklendi"
- ]
+ ],
+ "A message identity the notification subsystem resolves.": "Bildirim sisteminin çözdüğü bir ileti kimliği.",
+ "Computed non-working-date rules. kind fixed: {month, day, name, observedShift?: {whenWeekday, days}}. kind easter: {offset, name}, offset in days from Easter Sunday. kind observedShift: a fixed date with a required shift.": "Hesaplanan tatil günü kuralları. Tür fixed: {month, day, name, observedShift?: {whenWeekday, days}}. Tür easter: {offset, name}, Paskalya pazarından gün olarak kaydırma. Tür observedShift: zorunlu aktarması olan sabit bir tarih.",
+ "Date": "Tarih",
+ "Day": "Gün",
+ "Day of a fixed or observedShift rule; ignored by an easter rule.": "fixed veya observedShift kuralının günü; easter kuralı bunu yok sayar.",
+ "Days": "Günler",
+ "Days from Easter Sunday for an easter rule; ignored by the other kinds.": "easter kuralı için Paskalya pazarından gün sayısı; diğer türler bunu yok sayar.",
+ "Distance from the deadline, in the offset unit.": "Kaydırma biriminde süreye olan uzaklık.",
+ "Enumerated one-off closures as {date, name}. Allowed alongside rules; refused as the whole calendar.": "{date, name} biçiminde sıralanan tek seferlik kapanışlar. Kuralların yanında izinli; takvimin tamamı olarak reddedilir.",
+ "Escalate to roles": "Yükseltilecek roller",
+ "Escalation ladder": "Yükseltme merdiveni",
+ "Exception dates": "İstisna tarihleri",
+ "Hours per working day": "İş günü başına saat",
+ "How many days the observed date shifts, e.g. -1 for the Saturday before.": "Kutlanan tarihin kaç gün aktarıldığı, örn. önceki cumartesi için -1.",
+ "Human-readable title.": "Okunabilir başlık.",
+ "ISO weekdays (1 = Monday, 7 = Sunday) that are working days.": "İş günü olan ISO hafta günleri (1 = pazartesi, 7 = pazar).",
+ "Kind": "Tür",
+ "Message": "İleti",
+ "Month": "Ay",
+ "Month of a fixed or observedShift rule; ignored by an easter rule.": "fixed veya observedShift kuralının ayı; easter kuralı bunu yok sayar.",
+ "Non-working-date rules": "Tatil günü kuralları",
+ "Notify roles": "Bildirilecek roller",
+ "Observed shift": "Tatilin aktarılması",
+ "Offset": "Kaydırma",
+ "Offset unit": "Kaydırma birimi",
+ "Open incident": "Olay aç",
+ "Optional map from a role name to a concrete recipient descriptor, e.g. {\"teamleader\": \"group:teamleaders\"}. Roles without a binding travel unresolved as role:.": "Rol adından somut bir alıcıya isteğe bağlı eşleme, örn. {\"teamleader\": \"group:teamleaders\"}. Bağlaması olmayan roller role: olarak çözülmeden ilerler.",
+ "Optional on a fixed rule, required on observedShift: {whenWeekday: weekday name or ISO 1..7, days: integer}.": "fixed kuralında isteğe bağlı, observedShift kuralında zorunlu: {whenWeekday: gün adı veya ISO 1..7, days: tam sayı}.",
+ "Ordered rungs: {key, trigger (preBreach|slaBreached), offset, offsetUnit (hours|businessDays|calendarDays), notifyRole[], escalateToRole[], priority, message, openIncident}.": "Sıralı basamaklar: {key, trigger (preBreach|slaBreached), offset, offsetUnit (hours|businessDays|calendarDays), notifyRole[], escalateToRole[], priority, message, openIncident}.",
+ "Priority": "Öncelik",
+ "Role bindings": "Rol bağlamaları",
+ "Roles the matter is escalated to at this rung.": "Konunun bu basamakta yükseltildiği roller.",
+ "Roles told at this rung; handler is the subject's own performer.": "Bu basamakta bildirilen roller; handler, işi yürüten kişidir.",
+ "Rungs": "Basamaklar",
+ "Stable rung identity, e.g. preBreach:14:calendarDays; derived from trigger, offset and unit when absent.": "Basamağın kalıcı kimliği, örn. preBreach:14:calendarDays; yoksa tetikleyici, kaydırma ve birimden türetilir.",
+ "The calendar's stable name, referenced by a timer's calendar_slug.": "Takvimin kalıcı adı; bir zamanlayıcı ona calendar_slug ile başvurur.",
+ "The closed date, Y-m-d.": "Kapalı tarih, Y-m-d.",
+ "The holiday's name.": "Tatilin adı.",
+ "The ladder's stable name, referenced by a timer's ladder_slug.": "Merdivenin kalıcı adı; bir zamanlayıcı ona ladder_slug ile başvurur.",
+ "The unit of the offset: the same set the SLA accepts.": "Kaydırmanın birimi: SLA'nın kabul ettiği aynı küme.",
+ "The urgency the raised transition carries.": "Tetiklenen geçişin taşıdığı aciliyet.",
+ "The weekday (name) on which the date shifts, e.g. sunday for Koningsdag.": "Tarihin aktarıldığı hafta günü (ad), örn. Koningsdag için sunday.",
+ "UUID of the organisation this calendar is configured for. Empty for a shared calendar. The resolution order picks an organisation's calendar when the timer names none.": "Bu takvimin yapılandırıldığı kuruluşun UUID değeri. Paylaşılan takvimde boş. Zamanlayıcı bir takvim adı vermezse çözüm sırası kuruluşun takvimini seçer.",
+ "UUID of the organisation this ladder is the default for. Empty for the shared default.": "Bu merdivenin varsayılan olduğu kuruluşun UUID değeri. Paylaşılan varsayılanda boş.",
+ "When weekday": "Şu güne denk gelirse",
+ "Whether reaching this rung opens an incident.": "Bu basamağa ulaşmanın bir olay açıp açmadığı.",
+ "Why the day is closed.": "Günün neden kapalı olduğu.",
+ "Working calendar": "Çalışma takvimi",
+ "Working hours in one working day. Makes hours and businessDays commensurable.": "Bir iş günündeki çalışma saatleri. Saatler ile iş günlerini karşılaştırılabilir kılar.",
+ "Working weekdays": "Haftanın iş günleri",
+ "fixed: a month/day; easter: an offset in days from Easter Sunday; observedShift: a month/day with a required observed shift.": "fixed: ay ve gün; easter: Paskalya pazarından gün olarak kaydırma; observedShift: zorunlu aktarması olan ay ve gün.",
+ "preBreach fires before the deadline, slaBreached at or after it.": "preBreach süre dolmadan önce, slaBreached süre dolduğunda veya sonrasında tetiklenir.",
+ "No such task": "Böyle bir görev yok",
+ "The task does not exist, or it is not yours to see.": "Görev yok ya da görme yetkiniz yok.",
+ "Details": "Ayrıntılar",
+ "Due": "Son tarih",
+ "Assignee": "Atanan",
+ "Requested by": "Talep eden",
+ "Outcome": "Sonuç",
+ "Ready to claim": "Üstlenilmeye hazır",
+ "In progress": "Devam ediyor",
+ "Terminated": "Sonlandırıldı",
+ "Normal": "Normal",
+ "Urgent": "Acil",
+ "Overdue by 1 day": "1 gün gecikmiş",
+ "Overdue by {days} days": "{days} gün gecikmiş",
+ "Due today": "Bugün teslim",
+ "Due tomorrow": "Yarın teslim",
+ "Due in {days} days": "{days} gün içinde teslim",
+ "Tasks": "Görevler",
+ "Task": "Görev",
+ "Unassigned, open for claiming": "Atanmamış, üstlenmeye açık",
+ "Claim": "Üstlen",
+ "Complete": "Tamamla",
+ "Complete: {outcome}": "Tamamla: {outcome}",
+ "Could not load the task": "Görev yüklenemedi",
+ "The task refused that action": "Görev bu eylemi reddetti"
},
"pluralForm": "nplurals=2; plural=(n != 1);",
"plurals": {
diff --git a/l10n/uk.js b/l10n/uk.js
index 9b37cb19c4..5c2f72e8cf 100644
--- a/l10n/uk.js
+++ b/l10n/uk.js
@@ -3,11 +3,21 @@ OC.L10N.register(
{
"3": "3",
"30": "30",
+ "from amount {amount}": "від суми {amount}",
+ "Gated transition: {transition}": "Контрольований перехід: {transition}",
+ "Each declared chain provisions an ordered task sequence when its transition is attempted. Approvers decide in their task inbox, not here.": "Кожен оголошений ланцюжок відкриває впорядковану послідовність завдань під час спроби переходу. Погоджувачі вирішують у своїй скриньці завдань, а не тут.",
+ "Declare x-openregister-approval-chains on this schema to gate a lifecycle transition on approval.": "Оголосіть x-openregister-approval-chains у цій схемі, щоб перехід життєвого циклу вимагав погодження.",
+ "Approval sequences": "Послідовності погодження",
"%n entries have no hash yet": "%n записів ще не мають хешу",
"%n entry has no hash yet": "%n запис ще не має хешу",
"(Dolphin required)": "(требуется Dolphin)",
+ "No approval chains declared": "Не оголошено жодного ланцюжка погодження",
"(no subject)": "(без теми)",
"(no title)": "(без назви)",
+ "Role {role}": "Роль {role}",
+ "The transition is applied automatically once every step approves.": "Перехід застосовується автоматично, щойно кожен крок погоджено.",
+ "The requester may not decide their own approval.": "Запитувач не може вирішувати щодо власного погодження.",
+ "Tier routing on field: {field}": "Ступенева маршрутизація за полем: {field}",
"(unnamed)": "(без імені)",
"(untitled card)": "(картка без назви)",
"({count} selected)": "({count} вибрано)",
@@ -2738,7 +2748,84 @@ OC.L10N.register(
"_Object successfully deleted_::_Objects successfully deleted_": ["Об'єкт успішно видалено","Об'єкти успішно видалено","Об'єкти успішно видалено","Об'єкти успішно видалено"],
"_Purge {count} object from database_::_Purge {count} objects from database_": ["Очистити {count} об'єкт з бази даних","Очистити {count} об'єкти з бази даних","Очистити {count} об'єктів з бази даних","Очистити {count} об'єкта з бази даних"],
"_Restore {count} object_::_Restore {count} objects_": ["Відновити {count} об'єкт","Відновити {count} об'єкти","Відновити {count} об'єктів","Відновити {count} об'єкта"],
- "_Successfully restored {count} object_::_Successfully restored {count} objects_": ["Успішно відновлено {count} об'єкт","Успішно відновлено {count} об'єкти","Успішно відновлено {count} об'єктів","Успішно відновлено {count} об'єкта"]
+ "_Successfully restored {count} object_::_Successfully restored {count} objects_": ["Успішно відновлено {count} об'єкт","Успішно відновлено {count} об'єкти","Успішно відновлено {count} об'єктів","Успішно відновлено {count} об'єкта"],
+ "A message identity the notification subsystem resolves.": "A message identity the notification subsystem resolves.",
+ "Computed non-working-date rules. kind fixed: {month, day, name, observedShift?: {whenWeekday, days}}. kind easter: {offset, name}, offset in days from Easter Sunday. kind observedShift: a fixed date with a required shift.": "Computed non-working-date rules. kind fixed: {month, day, name, observedShift?: {whenWeekday, days}}. kind easter: {offset, name}, offset in days from Easter Sunday. kind observedShift: a fixed date with a required shift.",
+ "Date": "Date",
+ "Day": "Day",
+ "Day of a fixed or observedShift rule; ignored by an easter rule.": "Day of a fixed or observedShift rule; ignored by an easter rule.",
+ "Days": "Days",
+ "Days from Easter Sunday for an easter rule; ignored by the other kinds.": "Days from Easter Sunday for an easter rule; ignored by the other kinds.",
+ "Distance from the deadline, in the offset unit.": "Distance from the deadline, in the offset unit.",
+ "Enumerated one-off closures as {date, name}. Allowed alongside rules; refused as the whole calendar.": "Enumerated one-off closures as {date, name}. Allowed alongside rules; refused as the whole calendar.",
+ "Escalate to roles": "Escalate to roles",
+ "Escalation ladder": "Escalation ladder",
+ "Exception dates": "Exception dates",
+ "Hours per working day": "Hours per working day",
+ "How many days the observed date shifts, e.g. -1 for the Saturday before.": "How many days the observed date shifts, e.g. -1 for the Saturday before.",
+ "Human-readable title.": "Human-readable title.",
+ "ISO weekdays (1 = Monday, 7 = Sunday) that are working days.": "ISO weekdays (1 = Monday, 7 = Sunday) that are working days.",
+ "Kind": "Kind",
+ "Message": "Message",
+ "Month": "Month",
+ "Month of a fixed or observedShift rule; ignored by an easter rule.": "Month of a fixed or observedShift rule; ignored by an easter rule.",
+ "Non-working-date rules": "Non-working-date rules",
+ "Notify roles": "Notify roles",
+ "Observed shift": "Observed shift",
+ "Offset": "Offset",
+ "Offset unit": "Offset unit",
+ "Open incident": "Open incident",
+ "Optional map from a role name to a concrete recipient descriptor, e.g. {\"teamleader\": \"group:teamleaders\"}. Roles without a binding travel unresolved as role:.": "Optional map from a role name to a concrete recipient descriptor, e.g. {\"teamleader\": \"group:teamleaders\"}. Roles without a binding travel unresolved as role:.",
+ "Optional on a fixed rule, required on observedShift: {whenWeekday: weekday name or ISO 1..7, days: integer}.": "Optional on a fixed rule, required on observedShift: {whenWeekday: weekday name or ISO 1..7, days: integer}.",
+ "Ordered rungs: {key, trigger (preBreach|slaBreached), offset, offsetUnit (hours|businessDays|calendarDays), notifyRole[], escalateToRole[], priority, message, openIncident}.": "Ordered rungs: {key, trigger (preBreach|slaBreached), offset, offsetUnit (hours|businessDays|calendarDays), notifyRole[], escalateToRole[], priority, message, openIncident}.",
+ "Priority": "Priority",
+ "Role bindings": "Role bindings",
+ "Roles the matter is escalated to at this rung.": "Roles the matter is escalated to at this rung.",
+ "Roles told at this rung; handler is the subject's own performer.": "Roles told at this rung; handler is the subject's own performer.",
+ "Rungs": "Rungs",
+ "Stable rung identity, e.g. preBreach:14:calendarDays; derived from trigger, offset and unit when absent.": "Stable rung identity, e.g. preBreach:14:calendarDays; derived from trigger, offset and unit when absent.",
+ "The calendar's stable name, referenced by a timer's calendar_slug.": "The calendar's stable name, referenced by a timer's calendar_slug.",
+ "The closed date, Y-m-d.": "The closed date, Y-m-d.",
+ "The holiday's name.": "The holiday's name.",
+ "The ladder's stable name, referenced by a timer's ladder_slug.": "The ladder's stable name, referenced by a timer's ladder_slug.",
+ "The unit of the offset: the same set the SLA accepts.": "The unit of the offset: the same set the SLA accepts.",
+ "The urgency the raised transition carries.": "The urgency the raised transition carries.",
+ "The weekday (name) on which the date shifts, e.g. sunday for Koningsdag.": "The weekday (name) on which the date shifts, e.g. sunday for Koningsdag.",
+ "UUID of the organisation this calendar is configured for. Empty for a shared calendar. The resolution order picks an organisation's calendar when the timer names none.": "UUID of the organisation this calendar is configured for. Empty for a shared calendar. The resolution order picks an organisation's calendar when the timer names none.",
+ "UUID of the organisation this ladder is the default for. Empty for the shared default.": "UUID of the organisation this ladder is the default for. Empty for the shared default.",
+ "When weekday": "When weekday",
+ "Whether reaching this rung opens an incident.": "Whether reaching this rung opens an incident.",
+ "Why the day is closed.": "Why the day is closed.",
+ "Working calendar": "Working calendar",
+ "Working hours in one working day. Makes hours and businessDays commensurable.": "Working hours in one working day. Makes hours and businessDays commensurable.",
+ "Working weekdays": "Working weekdays",
+ "fixed: a month/day; easter: an offset in days from Easter Sunday; observedShift: a month/day with a required observed shift.": "fixed: a month/day; easter: an offset in days from Easter Sunday; observedShift: a month/day with a required observed shift.",
+ "preBreach fires before the deadline, slaBreached at or after it.": "preBreach fires before the deadline, slaBreached at or after it.",
+ "No such task": "Немає такого завдання",
+ "The task does not exist, or it is not yours to see.": "Завдання не існує, або ви не маєте права його бачити.",
+ "Details": "Деталі",
+ "Due": "Термін",
+ "Assignee": "Виконавець",
+ "Requested by": "Запитав",
+ "Outcome": "Результат",
+ "Ready to claim": "Готово до взяття",
+ "In progress": "Виконується",
+ "Terminated": "Припинено",
+ "Normal": "Звичайний",
+ "Urgent": "Терміновий",
+ "Overdue by 1 day": "Прострочено на 1 день",
+ "Overdue by {days} days": "Прострочено на {days} дн.",
+ "Due today": "Термін сьогодні",
+ "Due tomorrow": "Термін завтра",
+ "Due in {days} days": "Термін через {days} дн.",
+ "Tasks": "Завдання",
+ "Task": "Завдання",
+ "Unassigned, open for claiming": "Не призначено, відкрито для взяття",
+ "Claim": "Взяти",
+ "Complete": "Завершити",
+ "Complete: {outcome}": "Завершити: {outcome}",
+ "Could not load the task": "Не вдалося завантажити завдання",
+ "The task refused that action": "Завдання відхилило цю дію"
},
"nplurals=4; plural=(n % 1 == 0 && n % 10 == 1 && n % 100 != 11 ? 0 : n % 1 == 0 && n % 10 >= 2 && n % 10 <= 4 && (n % 100 < 12 || n % 100 > 14) ? 1 : n % 1 == 0 && (n % 10 ==0 || (n % 10 >=5 && n % 10 <=9) || (n % 100 >=11 && n % 100 <=14 )) ? 2: 3);"
)
diff --git a/l10n/uk.json b/l10n/uk.json
index 4b5e9117f8..d7af5ba7c2 100644
--- a/l10n/uk.json
+++ b/l10n/uk.json
@@ -1,10 +1,20 @@
{
"translations": {
+ "from amount {amount}": "від суми {amount}",
+ "Gated transition: {transition}": "Контрольований перехід: {transition}",
+ "Each declared chain provisions an ordered task sequence when its transition is attempted. Approvers decide in their task inbox, not here.": "Кожен оголошений ланцюжок відкриває впорядковану послідовність завдань під час спроби переходу. Погоджувачі вирішують у своїй скриньці завдань, а не тут.",
+ "Declare x-openregister-approval-chains on this schema to gate a lifecycle transition on approval.": "Оголосіть x-openregister-approval-chains у цій схемі, щоб перехід життєвого циклу вимагав погодження.",
+ "Approval sequences": "Послідовності погодження",
"%n entries have no hash yet": "%n записів ще не мають хешу",
"%n entry has no hash yet": "%n запис ще не має хешу",
"(Dolphin required)": "(требуется Dolphin)",
+ "No approval chains declared": "Не оголошено жодного ланцюжка погодження",
"(no subject)": "(без теми)",
"(no title)": "(без назви)",
+ "Role {role}": "Роль {role}",
+ "The transition is applied automatically once every step approves.": "Перехід застосовується автоматично, щойно кожен крок погоджено.",
+ "The requester may not decide their own approval.": "Запитувач не може вирішувати щодо власного погодження.",
+ "Tier routing on field: {field}": "Ступенева маршрутизація за полем: {field}",
"(unnamed)": "(без імені)",
"(untitled card)": "(картка без назви)",
"({count} selected)": "({count} вибрано)",
@@ -2817,7 +2827,84 @@
"Успішно відновлено {count} об'єкти",
"Успішно відновлено {count} об'єктів",
"Успішно відновлено {count} об'єкта"
- ]
+ ],
+ "A message identity the notification subsystem resolves.": "A message identity the notification subsystem resolves.",
+ "Computed non-working-date rules. kind fixed: {month, day, name, observedShift?: {whenWeekday, days}}. kind easter: {offset, name}, offset in days from Easter Sunday. kind observedShift: a fixed date with a required shift.": "Computed non-working-date rules. kind fixed: {month, day, name, observedShift?: {whenWeekday, days}}. kind easter: {offset, name}, offset in days from Easter Sunday. kind observedShift: a fixed date with a required shift.",
+ "Date": "Date",
+ "Day": "Day",
+ "Day of a fixed or observedShift rule; ignored by an easter rule.": "Day of a fixed or observedShift rule; ignored by an easter rule.",
+ "Days": "Days",
+ "Days from Easter Sunday for an easter rule; ignored by the other kinds.": "Days from Easter Sunday for an easter rule; ignored by the other kinds.",
+ "Distance from the deadline, in the offset unit.": "Distance from the deadline, in the offset unit.",
+ "Enumerated one-off closures as {date, name}. Allowed alongside rules; refused as the whole calendar.": "Enumerated one-off closures as {date, name}. Allowed alongside rules; refused as the whole calendar.",
+ "Escalate to roles": "Escalate to roles",
+ "Escalation ladder": "Escalation ladder",
+ "Exception dates": "Exception dates",
+ "Hours per working day": "Hours per working day",
+ "How many days the observed date shifts, e.g. -1 for the Saturday before.": "How many days the observed date shifts, e.g. -1 for the Saturday before.",
+ "Human-readable title.": "Human-readable title.",
+ "ISO weekdays (1 = Monday, 7 = Sunday) that are working days.": "ISO weekdays (1 = Monday, 7 = Sunday) that are working days.",
+ "Kind": "Kind",
+ "Message": "Message",
+ "Month": "Month",
+ "Month of a fixed or observedShift rule; ignored by an easter rule.": "Month of a fixed or observedShift rule; ignored by an easter rule.",
+ "Non-working-date rules": "Non-working-date rules",
+ "Notify roles": "Notify roles",
+ "Observed shift": "Observed shift",
+ "Offset": "Offset",
+ "Offset unit": "Offset unit",
+ "Open incident": "Open incident",
+ "Optional map from a role name to a concrete recipient descriptor, e.g. {\"teamleader\": \"group:teamleaders\"}. Roles without a binding travel unresolved as role:.": "Optional map from a role name to a concrete recipient descriptor, e.g. {\"teamleader\": \"group:teamleaders\"}. Roles without a binding travel unresolved as role:.",
+ "Optional on a fixed rule, required on observedShift: {whenWeekday: weekday name or ISO 1..7, days: integer}.": "Optional on a fixed rule, required on observedShift: {whenWeekday: weekday name or ISO 1..7, days: integer}.",
+ "Ordered rungs: {key, trigger (preBreach|slaBreached), offset, offsetUnit (hours|businessDays|calendarDays), notifyRole[], escalateToRole[], priority, message, openIncident}.": "Ordered rungs: {key, trigger (preBreach|slaBreached), offset, offsetUnit (hours|businessDays|calendarDays), notifyRole[], escalateToRole[], priority, message, openIncident}.",
+ "Priority": "Priority",
+ "Role bindings": "Role bindings",
+ "Roles the matter is escalated to at this rung.": "Roles the matter is escalated to at this rung.",
+ "Roles told at this rung; handler is the subject's own performer.": "Roles told at this rung; handler is the subject's own performer.",
+ "Rungs": "Rungs",
+ "Stable rung identity, e.g. preBreach:14:calendarDays; derived from trigger, offset and unit when absent.": "Stable rung identity, e.g. preBreach:14:calendarDays; derived from trigger, offset and unit when absent.",
+ "The calendar's stable name, referenced by a timer's calendar_slug.": "The calendar's stable name, referenced by a timer's calendar_slug.",
+ "The closed date, Y-m-d.": "The closed date, Y-m-d.",
+ "The holiday's name.": "The holiday's name.",
+ "The ladder's stable name, referenced by a timer's ladder_slug.": "The ladder's stable name, referenced by a timer's ladder_slug.",
+ "The unit of the offset: the same set the SLA accepts.": "The unit of the offset: the same set the SLA accepts.",
+ "The urgency the raised transition carries.": "The urgency the raised transition carries.",
+ "The weekday (name) on which the date shifts, e.g. sunday for Koningsdag.": "The weekday (name) on which the date shifts, e.g. sunday for Koningsdag.",
+ "UUID of the organisation this calendar is configured for. Empty for a shared calendar. The resolution order picks an organisation's calendar when the timer names none.": "UUID of the organisation this calendar is configured for. Empty for a shared calendar. The resolution order picks an organisation's calendar when the timer names none.",
+ "UUID of the organisation this ladder is the default for. Empty for the shared default.": "UUID of the organisation this ladder is the default for. Empty for the shared default.",
+ "When weekday": "When weekday",
+ "Whether reaching this rung opens an incident.": "Whether reaching this rung opens an incident.",
+ "Why the day is closed.": "Why the day is closed.",
+ "Working calendar": "Working calendar",
+ "Working hours in one working day. Makes hours and businessDays commensurable.": "Working hours in one working day. Makes hours and businessDays commensurable.",
+ "Working weekdays": "Working weekdays",
+ "fixed: a month/day; easter: an offset in days from Easter Sunday; observedShift: a month/day with a required observed shift.": "fixed: a month/day; easter: an offset in days from Easter Sunday; observedShift: a month/day with a required observed shift.",
+ "preBreach fires before the deadline, slaBreached at or after it.": "preBreach fires before the deadline, slaBreached at or after it.",
+ "No such task": "Немає такого завдання",
+ "The task does not exist, or it is not yours to see.": "Завдання не існує, або ви не маєте права його бачити.",
+ "Details": "Деталі",
+ "Due": "Термін",
+ "Assignee": "Виконавець",
+ "Requested by": "Запитав",
+ "Outcome": "Результат",
+ "Ready to claim": "Готово до взяття",
+ "In progress": "Виконується",
+ "Terminated": "Припинено",
+ "Normal": "Звичайний",
+ "Urgent": "Терміновий",
+ "Overdue by 1 day": "Прострочено на 1 день",
+ "Overdue by {days} days": "Прострочено на {days} дн.",
+ "Due today": "Термін сьогодні",
+ "Due tomorrow": "Термін завтра",
+ "Due in {days} days": "Термін через {days} дн.",
+ "Tasks": "Завдання",
+ "Task": "Завдання",
+ "Unassigned, open for claiming": "Не призначено, відкрито для взяття",
+ "Claim": "Взяти",
+ "Complete": "Завершити",
+ "Complete: {outcome}": "Завершити: {outcome}",
+ "Could not load the task": "Не вдалося завантажити завдання",
+ "The task refused that action": "Завдання відхилило цю дію"
},
"pluralForm": "nplurals=4; plural=(n % 1 == 0 && n % 10 == 1 && n % 100 != 11 ? 0 : n % 1 == 0 && n % 10 >= 2 && n % 10 <= 4 && (n % 100 < 12 || n % 100 > 14) ? 1 : n % 1 == 0 && (n % 10 ==0 || (n % 10 >=5 && n % 10 <=9) || (n % 100 >=11 && n % 100 <=14 )) ? 2: 3);",
"plurals": {
diff --git a/lib/AppHost/Routes.php b/lib/AppHost/Routes.php
index 8a8b56f4eb..3dbc0d7a18 100644
--- a/lib/AppHost/Routes.php
+++ b/lib/AppHost/Routes.php
@@ -165,7 +165,18 @@ private static function catchAllRoute(): array {
'name' => 'dashboard#catchAll',
'url' => '/{path}',
'verb' => 'GET',
- 'requirements' => ['path' => '.+'],
+ // ⚠️ `(?!api/)` is load-bearing for any adopter whose routes.php
+ // also declares a `resources` block. Nextcloud's RouteParser
+ // processes the `routes` array BEFORE the `resources` array
+ // (RouteParser::parseDefaultRoutes) and Symfony matches in
+ // insertion order, so this route registers ahead of every
+ // resource-generated route no matter that it is appended LAST
+ // here. `.+` matches slashes, so without the lookahead it
+ // swallows GET api/ and answers the SPA shell with
+ // HTTP 200 — a JSON caller receives HTML and nothing errors
+ // loudly. zaakafhandelapp lost all seventeen of its ZGW resource
+ // routes that way. The SPA never needs an `api/` path.
+ 'requirements' => ['path' => '(?!api/).+'],
'defaults' => ['path' => ''],
];
}//end catchAllRoute()
diff --git a/lib/AppInfo/Application.php b/lib/AppInfo/Application.php
index 45973c2c9c..73ff7a4171 100644
--- a/lib/AppInfo/Application.php
+++ b/lib/AppInfo/Application.php
@@ -67,7 +67,6 @@
use OCA\OpenRegister\Db\WebhookMapper;
use OCA\OpenRegister\Event\AgentCreatedEvent;
use OCA\OpenRegister\Event\AgentUpdatedEvent;
-use OCA\OpenRegister\Event\ApprovalStepCompletedEvent;
use OCA\OpenRegister\Event\ConfigurationCreatedEvent;
use OCA\OpenRegister\Event\ConfigurationUpdatedEvent;
use OCA\OpenRegister\Event\DeepLinkRegistrationEvent;
@@ -101,7 +100,6 @@
use OCA\OpenRegister\Listener\CalculationOnSaveListener;
use OCA\OpenRegister\Listener\CommentsEntityListener;
use OCA\OpenRegister\Listener\ContextChatSubmissionListener;
-use OCA\OpenRegister\Listener\EventCatalogListener;
use OCA\OpenRegister\Listener\FileChangeListener;
use OCA\OpenRegister\Listener\FilesSidebarListener;
use OCA\OpenRegister\Listener\FlowEngineRegistrationListener;
@@ -224,6 +222,7 @@
use OCA\OpenRegister\Service\ObjectSource\FederatedObjectSourceProvider;
use OCA\OpenRegister\Service\ObjectSource\FilesObjectSourceProvider;
use OCA\OpenRegister\Service\ObjectSource\GroupObjectSourceProvider;
+use OCA\OpenRegister\Service\ObjectSource\OrganisationObjectSourceProvider;
use OCA\OpenRegister\Service\ObjectSource\ObjectSourceRegistry;
use OCA\OpenRegister\Service\ObjectSource\TablesColumnMapper;
use OCA\OpenRegister\Service\ObjectSource\TablesObjectSourceProvider;
@@ -235,6 +234,7 @@
use OCA\OpenRegister\Service\OpenProjectLinkService;
use OCA\OpenRegister\Service\OrganisationService;
use OCA\OpenRegister\Service\PhotoLinkService;
+use OCA\OpenRegister\Service\Portal\PortalPartyResolver;
use OCA\OpenRegister\Service\Schema\SchemaDiffService;
use OCA\OpenRegister\Service\Schema\SchemaMigrationPlanner;
use OCA\OpenRegister\Service\Schema\SchemaMigrationService;
@@ -242,6 +242,7 @@
use OCA\OpenRegister\Service\Schema\SchemaVersioningService;
use OCA\OpenRegister\Service\SchemaImport\DialectDetector;
use OCA\OpenRegister\Service\SchemaImport\SchemaImportService;
+use OCA\OpenRegister\Service\Task\TaskInboxService;
use OCA\OpenRegister\Service\SchemaImport\ThreeWayMerge;
use OCA\OpenRegister\Service\Schemas\FacetCacheHandler;
use OCA\OpenRegister\Service\Schemas\PropertyValidatorHandler;
@@ -526,7 +527,11 @@ function () {
\OCA\OpenRegister\Service\Flow\FlowStepDispatcher::class,
static function ($c) {
return new RegistryStepDispatcher(
- registry: $c->get(\OCA\OpenRegister\Service\Flow\FlowNodeRegistry::class)
+ registry: $c->get(\OCA\OpenRegister\Service\Flow\FlowNodeRegistry::class),
+ // The acting-identity scope IS container state, unlike the
+ // guard: a loop's body steps must scope a contributed node
+ // to the run's runAs exactly as top-level steps do.
+ scope: $c->get(\OCA\OpenRegister\Service\Flow\FlowRunAsScope::class)
);
}
);
@@ -822,6 +827,33 @@ function (ContainerInterface $container) {
}
);
+ // The task inbox and the portal party resolver read the object store
+ // through AbstractObjectMapper, which the autowirer cannot build (it is
+ // abstract) and would silently default to null: an inbox row without
+ // subject context, and a portal task that can match nobody. Both are
+ // wired to the MagicMapper explicitly for that reason.
+ $context->registerService(
+ TaskInboxService::class,
+ function (ContainerInterface $container) {
+ return new TaskInboxService(
+ tasks: $container->get(\OCA\OpenRegister\Db\TaskMapper::class),
+ temporal: $container->get(\OCA\OpenRegister\Service\Task\TaskTemporalProjection::class),
+ logger: $container->get('Psr\Log\LoggerInterface'),
+ objects: $container->get(MagicMapper::class),
+ deliveries: $container->get(\OCA\OpenRegister\Db\PortalTaskDeliveryMapper::class)
+ );
+ }
+ );
+
+ $context->registerService(
+ PortalPartyResolver::class,
+ function (ContainerInterface $container) {
+ return new PortalPartyResolver(
+ objects: $container->get(MagicMapper::class)
+ );
+ }
+ );
+
// EntityRelationMapper is registered explicitly because it constructor-injects
// `IEventDispatcher` to dispatch `EntityRelationDecisionUpdatedEvent`. Every
// other event-dispatcher-dependent mapper in this method (SchemaMapper,
@@ -1110,7 +1142,6 @@ function (ContainerInterface $container) {
searchTrailMapper: $container->get(SearchTrailMapper::class),
userManager: $container->get('OCP\IUserManager'),
db: $container->get('OCP\IDBConnection'),
- setupHandler: null,
objectCacheService: null,
container: $container,
appName: 'openregister',
@@ -1181,11 +1212,24 @@ private function registerObjectInteractionServices(IRegistrationContext $context
$context->registerService(
TaskService::class,
function (ContainerInterface $container) {
+ // The write-back gate is resolved lazily and best-effort: without
+ // it a PROJECTED VTODO's update is refused (fail closed), and
+ // standalone VTODOs are unaffected either way.
+ $gate = null;
+ try {
+ $gate = $container->get(\OCA\OpenRegister\Service\Task\TaskVtodoWriteBackGate::class);
+ } catch (\Throwable $e) {
+ $container->get('Psr\Log\LoggerInterface')->debug(
+ '[Application] TaskVtodoWriteBackGate unavailable for TaskService: ' . $e->getMessage()
+ );
+ }
+
return new TaskService(
calDavBackend: $container->get('OCA\DAV\CalDAV\CalDavBackend'),
userSession: $container->get('OCP\IUserSession'),
logger: $container->get('Psr\Log\LoggerInterface'),
- urlGenerator: $container->get('OCP\IURLGenerator')
+ urlGenerator: $container->get('OCP\IURLGenerator'),
+ gate: $gate
);
}
);
@@ -1431,6 +1475,18 @@ function (ContainerInterface $container) {
}
);
+ $context->registerService(
+ OrganisationObjectSourceProvider::class,
+ function (ContainerInterface $container) {
+ return new OrganisationObjectSourceProvider(
+ organisationMapper: $container->get('OCA\OpenRegister\Db\OrganisationMapper'),
+ userSession: $container->get('OCP\IUserSession'),
+ groupManager: $container->get('OCP\IGroupManager'),
+ logger: $container->get('Psr\Log\LoggerInterface')
+ );
+ }
+ );
+
$context->registerService(
ContactsObjectSourceProvider::class,
function (ContainerInterface $container) {
@@ -2521,17 +2577,147 @@ private function registerEventListeners(IRegistrationContext $context): void {
$context->registerEventListener(ObjectCreatingEvent::class, FlowNodePreflightListener::class);
$context->registerEventListener(ObjectUpdatingEvent::class, FlowNodePreflightListener::class);
+ // Task cancellation propagation (flow-task-entity, design D-8): a run
+ // persisted in a terminal status terminates its open tasks, with the
+ // reason recorded. The event fires from FlowRunMapper::update() — the
+ // one choke point all terminal writes pass — and may fire repeatedly;
+ // the listener is idempotent, and a task with run_uuid null is
+ // structurally out of its reach.
+ $context->registerEventListener(
+ \OCA\OpenRegister\Event\FlowRunTerminalEvent::class,
+ \OCA\OpenRegister\Listener\TaskRunTerminalListener::class
+ );
+
+// The other direction (flow-user-task-node): a task the graph raised
+ // reached a terminal state, so its suspended run is woken and, per the
+ // node's `advance` budget, continued in-request. Fires AFTER the task's
+ // own transaction committed (the listener skips uncommitted dispatches);
+ // a failure here costs latency, never the completion.
+ $context->registerEventListener(
+ \OCA\OpenRegister\Event\TaskTerminalEvent::class,
+ \OCA\OpenRegister\Listener\UserTaskTerminalListener::class
+ );
+
+ // Business-timer cancellation propagation (flow-business-timers, design
+ // D-9): a terminal task (TaskMapper, both write paths) or a terminal run
+ // (FlowRunMapper) cancels its open timers INSIDE the write that made the
+ // subject terminal, so no escalation goes out about finished work. The
+ // listener is idempotent and never deletes.
+ $context->registerEventListener(
+ \OCA\OpenRegister\Event\TaskTerminalEvent::class,
+ \OCA\OpenRegister\Listener\FlowTimerSubjectTerminalListener::class
+ );
+ $context->registerEventListener(
+ \OCA\OpenRegister\Event\FlowRunTerminalEvent::class,
+ \OCA\OpenRegister\Listener\FlowTimerSubjectTerminalListener::class
+ );
+
+ // The portal reminder (flow-portal-task, design D-8): a preBreach rung
+ // of flow-business-timers on an EXTERNAL task becomes a reminder
+ // delivery request through the portal seam; a slaBreached rung stays
+ // inward. Registered by the event's NAME because the timers change is
+ // built in parallel and its event class may not be on this branch yet;
+ // the listener is duck-typed against the event's published surface, so
+ // the two merge in either order.
+ $context->registerEventListener(
+ \OCA\OpenRegister\Listener\PortalTaskReminderListener::EVENT_CLASS,
+ \OCA\OpenRegister\Listener\PortalTaskReminderListener::class
+ );
+
+ // Task projections (flow-task-inbox-projections): a committed
+ // transition becomes a declarative notification and a VTODO in the
+ // assignee's calendar. Both run AFTER the commit and neither can fail
+ // the transition (design D-8). Withdrawal runs before delivery, so the
+ // notification listener is registered first.
+ $context->registerEventListener(
+ \OCA\OpenRegister\Event\TaskTransitionedEvent::class,
+ \OCA\OpenRegister\Listener\TaskNotificationListener::class
+ );
+ $context->registerEventListener(
+ \OCA\OpenRegister\Event\TaskTransitionedEvent::class,
+ \OCA\OpenRegister\Listener\TaskCalendarProjectionListener::class
+ );
+
+ // Dismiss-on-terminality, on the same terminal-task event the
+ // user-task node listens to: no approve button and no open VTODO
+ // survives a terminal task, however it became terminal. Idempotent
+ // beside the transition listeners above: a second withdrawal finds
+ // nothing to withdraw and a second render finds nothing changed.
+ $context->registerEventListener(
+ \OCA\OpenRegister\Event\TaskTerminalEvent::class,
+ \OCA\OpenRegister\Listener\TaskTerminalProjectionListener::class
+ );
+
+ // The safety-net write-back hook (design D-6): calendar writes that
+ // reached the backend without traversing the Sabre plugin are
+ // reverted to the engine's truth, and the actor is told why.
+ $context->registerEventListener(
+ \OCP\Calendar\Events\CalendarObjectUpdatedEvent::class,
+ \OCA\OpenRegister\Listener\TaskVtodoWriteBackListener::class
+ );
+ $context->registerEventListener(
+ \OCP\Calendar\Events\CalendarObjectDeletedEvent::class,
+ \OCA\OpenRegister\Listener\TaskVtodoWriteBackListener::class
+ );
+
+ // The case layer (flow-cmmn-case-semantics). A realisation ending (a task
+ // or a run) drives its plan item; an object change may satisfy a sentry;
+ // and a plan item reaching a terminal state is a catalog event fired
+ // against the anchoring object. Nothing under Service\Flow depends on
+ // Service\Case: these listeners are the only coupling, and it points one
+ // way. TaskTerminalEvent is dispatched by TaskService after the
+ // terminal transition commits (flow-user-task-node); the same
+ // reconciliation also runs on every case-plan evaluation, so a missed
+ // event costs latency, never correctness.
+ $context->registerEventListener(
+ \OCA\OpenRegister\Event\TaskTerminalEvent::class,
+ \OCA\OpenRegister\Listener\CaseTaskTerminalListener::class
+ );
+ $context->registerEventListener(
+ \OCA\OpenRegister\Event\FlowRunTerminalEvent::class,
+ \OCA\OpenRegister\Listener\CaseRunTerminalListener::class
+ );
+ $context->registerEventListener(ObjectUpdatedEvent::class, \OCA\OpenRegister\Listener\CaseObjectEventListener::class);
+ $context->registerEventListener(ObjectTransitionedEvent::class, \OCA\OpenRegister\Listener\CaseObjectEventListener::class);
+ // Routed through FlowTriggerListener, the ONE object-trigger path (the
+ // branch that retired EventCatalogListener as a duplicate). The case
+ // branch moved with the retirement, and gains what the one path has:
+ // the subject's register/schema resolved to the SLUGS the trigger
+ // index stores — CaseItemTransitionedEvent::getSubject() answers the
+ // item's numeric ids — and the acting user attributed to the run.
+ $context->registerEventListener(
+ \OCA\OpenRegister\Event\CaseItemTransitionedEvent::class,
+ \OCA\OpenRegister\Listener\FlowTriggerListener::class
+ );
+
+ // Business-timer cancellation propagation (flow-business-timers, design
+ // D-9): the SAME terminal event, and the run-terminal one, also cancel
+ // the subject's open business timers. TaskTerminalEvent fires right
+ // after the terminal write commits (see TaskService::transactional),
+ // FlowRunTerminalEvent inside the run's own write; the listener is
+ // idempotent and never deletes, and the invariant repair step counts
+ // anything a crash window leaves behind.
+ $context->registerEventListener(
+ \OCA\OpenRegister\Event\TaskTerminalEvent::class,
+ \OCA\OpenRegister\Listener\FlowTimerSubjectTerminalListener::class
+ );
+ $context->registerEventListener(
+ \OCA\OpenRegister\Event\FlowRunTerminalEvent::class,
+ \OCA\OpenRegister\Listener\FlowTimerSubjectTerminalListener::class
+ );
+
// Lifecycle annotation listeners — see x-openregister-lifecycle.
// Order matters: initial state runs on creating; validation runs on updating.
$context->registerEventListener(ObjectCreatingEvent::class, LifecycleInitialStateListener::class);
$context->registerEventListener(ObjectUpdatingEvent::class, LifecycleValidationListener::class);
// Approval-chains declarative wiring — see x-openregister-approval-chains.
- // Provisions ApprovalChain rows from the annotation (schema save), then
- // gates any lifecycle transition it names until the provisioned chain's
- // steps are all approved. Registered immediately after
- // LifecycleValidationListener: transition legality must be established
- // before approval-chain gating runs against it.
+ // The annotation is validated at schema save; the gate compiles it into
+ // a task template on demand and blocks any lifecycle transition it
+ // names until the object's approval SEQUENCE completes with an
+ // approving outcome (flow-approval-consolidation). Registered
+ // immediately after LifecycleValidationListener: transition legality
+ // must be established before approval gating runs against it.
// Declared flows (`x-openregister-flows`) are MATERIALISED into the flow
// store on schema save, because a flow lives in its own table rather
// than being read off the schema at runtime like every other
@@ -2544,7 +2730,18 @@ private function registerEventListeners(IRegistrationContext $context): void {
$context->registerEventListener(SchemaCreatedEvent::class, ApprovalChainAnnotationInstaller::class);
$context->registerEventListener(SchemaUpdatedEvent::class, ApprovalChainAnnotationInstaller::class);
$context->registerEventListener(ObjectUpdatingEvent::class, ApprovalChainGateListener::class);
- $context->registerEventListener(ApprovalStepCompletedEvent::class, ApprovalChainAdvanceListener::class);
+ $context->registerEventListener(
+ \OCA\OpenRegister\Event\TaskSequenceCompletedEvent::class,
+ ApprovalChainAdvanceListener::class
+ );
+
+ // Sequence progression (flow-approval-consolidation): a committed
+ // terminal task that belongs to a sequence enables the next position,
+ // or closes the sequence, in the SAME request as the decision.
+ $context->registerEventListener(
+ \OCA\OpenRegister\Event\TaskTerminalEvent::class,
+ \OCA\OpenRegister\Listener\TaskSequenceProgressListener::class
+ );
// Lifecycle action executor — see x-openregister-lifecycle.transitions[*].actions[].
// Runs the declared actions of a matched transition on the save path, so
@@ -2616,22 +2813,18 @@ private function registerEventListeners(IRegistrationContext $context): void {
$context->registerEventListener(ObjectUpdatedEvent::class, AnnotationNotificationListener::class);
$context->registerEventListener(ObjectTransitionedEvent::class, AnnotationNotificationListener::class);
- // Object-CRUD flow triggers. These route through EventCatalogListener
- // like every other catalog event, so there is ONE path from a dispatched
- // event to a queued run — the action-list engine that used to handle
- // create/update/delete separately is gone.
- $context->registerEventListener(ObjectCreatedEvent::class, EventCatalogListener::class);
- $context->registerEventListener(ObjectUpdatedEvent::class, EventCatalogListener::class);
- $context->registerEventListener(ObjectDeletedEvent::class, EventCatalogListener::class);
-
- // Additional flow-catalog triggers beyond CRUD (lock/unlock/revert/state
- // transition). Routed by EventCatalogListener so create/update/delete are
- // not double-handled. Each event carries the object, so its schema's flows
- // run — see EventCatalogService for the trigger ids.
- $context->registerEventListener(ObjectLockedEvent::class, EventCatalogListener::class);
- $context->registerEventListener(ObjectUnlockedEvent::class, EventCatalogListener::class);
- $context->registerEventListener(ObjectRevertedEvent::class, EventCatalogListener::class);
- $context->registerEventListener(ObjectTransitionedEvent::class, EventCatalogListener::class);
+ // Object-lifecycle flow triggers have ONE listener: FlowTriggerListener,
+ // registered above with the other flow triggers. EventCatalogListener
+ // used to be registered here for the SAME seven events, each handler
+ // calling FlowTriggerService::fire() — every object event reached the
+ // trigger service twice. The double-fire was invisible only because both
+ // listeners fired the object's numeric register/schema ids against an
+ // index that holds slugs, so neither ever matched; the moment the
+ // vocabulary was fixed, two registrations would have queued every
+ // matched flow twice per event. FlowTriggerListener is the one kept
+ // because it is the superset: it attributes the acting user to the run
+ // and carries the transition's action/from/to as context, both of which
+ // EventCatalogListener dropped.
// Native Nextcloud Flow (workflowengine) composition — expose OR objects
// as a Flow entity and OR flows as a Flow operation. Guarded by
@@ -4256,6 +4449,7 @@ private function bootObjectSourceProviders($server): void {
CalDavVtodoObjectSourceProvider::class,
UserDirectoryObjectSourceProvider::class,
GroupObjectSourceProvider::class,
+ OrganisationObjectSourceProvider::class,
ContactsObjectSourceProvider::class,
CalendarEventObjectSourceProvider::class,
FilesObjectSourceProvider::class,
diff --git a/lib/BackgroundJob/FlowRunWorker.php b/lib/BackgroundJob/FlowRunWorker.php
index 0d1925824f..7bf365a128 100644
--- a/lib/BackgroundJob/FlowRunWorker.php
+++ b/lib/BackgroundJob/FlowRunWorker.php
@@ -34,11 +34,15 @@
namespace OCA\OpenRegister\BackgroundJob;
use DateTime;
+use OCA\OpenRegister\Db\FlowClaimMapper;
use OCA\OpenRegister\Db\FlowRun;
use OCA\OpenRegister\Db\FlowRunMapper;
+use OCA\OpenRegister\Db\FlowStreamMapper;
use OCA\OpenRegister\Service\Delegation\DelegationService;
use OCA\OpenRegister\Service\Flow\FlowConsentParking;
+use OCA\OpenRegister\Service\Flow\FlowLocator;
use OCA\OpenRegister\Service\Flow\FlowRunAdvancer;
+use OCA\OpenRegister\Service\Flow\FlowTokenRouter;
use OCP\AppFramework\Utility\ITimeFactory;
use OCP\BackgroundJob\TimedJob;
use OCP\IAppConfig;
@@ -50,6 +54,9 @@
*
* @spec openspec/changes/or-flow-runs/specs/flow-runs/spec.md
* @spec openspec/changes/or-flow-queue-fairness/specs/flow-queue-fairness/spec.md
+ *
+ * @SuppressWarnings(PHPMD.CouplingBetweenObjects) The pass owns recovery for runs, claims and
+ * streams alike; each mapper is one table the reaper has to read.
*/
class FlowRunWorker extends TimedJob {
@@ -61,7 +68,7 @@ class FlowRunWorker extends TimedJob {
*
* @var int
*/
- private const BATCH = 25;
+ public const BATCH = 25;
/**
* Default retention for terminal runs, in days.
@@ -165,6 +172,9 @@ class FlowRunWorker extends TimedJob {
* runs are actually parked, because
* a sweep that skips looks exactly
* like one that found nothing.
+ * @param FlowClaimMapper|null $claims Place claims, for the abandoned-claim reaper.
+ * @param FlowStreamMapper|null $streams Run streams, for failing an abandoned branch.
+ * @param FlowLocator|null $flows Resolves the run's flow, for the abandoned step's `onError` policy.
*/
public function __construct(
ITimeFactory $time,
@@ -173,6 +183,9 @@ public function __construct(
private readonly IAppConfig $appConfig,
private readonly LoggerInterface $logger,
private readonly ?DelegationService $delegation = null,
+ private readonly ?FlowClaimMapper $claims = null,
+ private readonly ?FlowStreamMapper $streams = null,
+ private readonly ?FlowLocator $flows = null,
) {
parent::__construct(time: $time);
// A FLOOR, not a schedule. `setInterval` says "not more often than
@@ -276,6 +289,8 @@ private function reapStale(DateTime $now): void {
$cutoff = (clone $now)->modify('-' . $minutes . ' minutes');
+ $this->reapAbandonedClaims(cutoff: $cutoff, now: $now, minutes: $minutes);
+
foreach ($this->mapper->findStale(before: $cutoff, limit: self::BATCH) as $run) {
$run->setStatus(FlowRun::STATUS_FAILED);
$run->setError(
@@ -302,6 +317,139 @@ private function reapStale(DateTime $now): void {
}//end reapStale()
+ /**
+ * Release claims a dead worker left behind, and FAIL the branch they held.
+ *
+ * Uses the SAME cutoff as the run reaper — one expression, not a second
+ * constant — so the two can never contradict each other. A reaped branch
+ * is failed, never re-dispatched: it may already have written an object,
+ * sent a message or called a remote system, and re-running it would repeat
+ * those without saying so. The run's error policy for the abandoned step
+ * decides the siblings' fate: `continue` keeps them (the run is re-armed
+ * as queued), anything else stops the run.
+ *
+ * @param DateTime $cutoff Claims taken before this moment are abandoned.
+ * @param DateTime $now Now.
+ * @param int $minutes The cutoff in minutes, for the message.
+ *
+ * @return void
+ *
+ * @spec openspec/changes/flow-parallel-streams/specs/flow-parallel-streams/spec.md#requirement-a-branch-abandoned-by-a-crashed-worker-must-be-recovered-and-must-not-be-silently-re-run
+ */
+ private function reapAbandonedClaims(DateTime $cutoff, DateTime $now, int $minutes): void {
+ if ($this->claims === null || $this->streams === null) {
+ return;
+ }
+
+ foreach ($this->claims->findOlderThan(before: $cutoff, limit: self::BATCH) as $claim) {
+ $runUuid = (string)$claim->getRunUuid();
+ $branch = (string)($claim->getStreamId() ?? '');
+ $transition = (string)($claim->getTransition() ?? '');
+
+ try {
+ $this->claims->releaseByOwner(runUuid: $runUuid, owner: (string)$claim->getOwner());
+
+ $error = sprintf(
+ 'Abandoned branch: worker pass "%s" took stream "%s" at step "%s" and never finished it '
+ . '(no commit for over %d minutes). The step may have performed its side effect; '
+ . 'it was NOT re-run.',
+ (string)$claim->getOwner(),
+ $branch,
+ $transition,
+ $minutes
+ );
+
+ $stream = $this->streams->findByRunAndStream(runUuid: $runUuid, streamId: $branch);
+ if ($stream !== null) {
+ $stream->setStatus(FlowRun::STATUS_FAILED);
+ $stream->setError($error);
+ $stream->setUpdated($now);
+ $this->streams->update($stream);
+ }
+
+ $run = $this->mapper->findByUuid(uuid: $runUuid);
+ // The abandoned step's policy decides the siblings' fate: the
+ // default fails the run; `continue` with a live sibling re-arms
+ // the run for the next pass instead.
+ $run->setStatus(FlowRun::STATUS_FAILED);
+ $run->setError($error);
+ $run->setResumeAt(null);
+ $continues = $this->abandonedStepContinues(run: $run, transition: $transition);
+ if ($continues === true && $this->hasLiveSibling(runUuid: $runUuid, failed: $branch) === true) {
+ $run->setStatus(FlowRun::STATUS_QUEUED);
+ $run->setError(null);
+ }
+
+ $run->setUpdated($now);
+ $this->mapper->update($run);
+
+ $this->logger->warning(
+ message: '[FlowRunWorker] Released an abandoned place claim and failed its branch',
+ context: [
+ 'file' => __FILE__,
+ 'line' => __LINE__,
+ 'run' => $runUuid,
+ 'stream' => $branch,
+ 'transition' => $transition,
+ 'owner' => $claim->getOwner(),
+ ]
+ );
+ } catch (Throwable $e) {
+ $this->logger->error(
+ message: '[FlowRunWorker] Could not reap an abandoned claim',
+ context: ['file' => __FILE__, 'line' => __LINE__, 'run' => $runUuid, 'error' => $e->getMessage()]
+ );
+ }//end try
+ }//end foreach
+ }//end reapAbandonedClaims()
+
+ /**
+ * Whether the abandoned step's `onError` policy lets the run's siblings
+ * continue. Unknown flow or step reads as the default policy, `stop`.
+ *
+ * @param FlowRun $run The run.
+ * @param string $transition The abandoned transition.
+ *
+ * @return bool True when the policy is `continue`.
+ */
+ private function abandonedStepContinues(FlowRun $run, string $transition): bool {
+ if ($this->flows === null || $transition === '') {
+ return false;
+ }
+
+ try {
+ $flow = $this->flows->resolveFlow((string)$run->getFlowId());
+ } catch (Throwable $e) {
+ return false;
+ }
+
+ if ($flow === null) {
+ return false;
+ }
+
+ $step = (new FlowTokenRouter())->stepFor(flow: $flow, transitionName: $transition);
+
+ return ((string)($step['onError'] ?? 'stop')) === 'continue';
+ }//end abandonedStepContinues()
+
+ /**
+ * Whether any stream of the run other than the failed one is still live.
+ *
+ * @param string $runUuid The run.
+ * @param string $failed The failed stream id.
+ *
+ * @return bool True when a sibling can still advance.
+ */
+ private function hasLiveSibling(string $runUuid, string $failed): bool {
+ foreach ($this->streams->findByRun(runUuid: $runUuid) as $stream) {
+ if ((string)$stream->getStreamId() !== $failed && $stream->isTerminal() === false) {
+ return true;
+ }
+ }
+
+ return false;
+ }//end hasLiveSibling()
+
/**
* Fail runs suspended on a signal that never arrived.
*
@@ -552,6 +700,9 @@ private function prune(DateTime $now): void {
try {
$before = (clone $now)->modify(sprintf('-%d days', $days));
$deleted = $this->mapper->pruneBefore(before: $before);
+ // Stream and claim rows go with their runs.
+ $this->streams?->deleteOrphans();
+ $this->claims?->deleteOrphans();
if ($deleted > 0) {
$this->logger->info(
message: '[FlowRunWorker] Pruned old flow runs',
diff --git a/lib/BackgroundJob/FlowTimerWorker.php b/lib/BackgroundJob/FlowTimerWorker.php
new file mode 100644
index 0000000000..f9d1519958
--- /dev/null
+++ b/lib/BackgroundJob/FlowTimerWorker.php
@@ -0,0 +1,140 @@
+
+ * SPDX-License-Identifier: EUPL-1.2
+ *
+ * @category Cron
+ * @package OCA\OpenRegister\BackgroundJob
+ *
+ * @author Conduction Development Team
+ * @copyright 2026 Conduction B.V.
+ * @license EUPL-1.2 https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
+ *
+ * @link https://OpenRegister.app
+ *
+ * @spec openspec/changes/flow-business-timers/specs/flow-business-timers/spec.md#requirement-the-sweep-is-bounded-to-due-work-by-index-not-by-a-page-of-candidates
+ */
+
+declare(strict_types=1);
+
+namespace OCA\OpenRegister\BackgroundJob;
+
+use DateTimeImmutable;
+use OCA\OpenRegister\Service\Flow\Timer\FlowTimerSweep;
+use OCP\AppFramework\Utility\ITimeFactory;
+use OCP\BackgroundJob\TimedJob;
+use OCP\IAppConfig;
+use Psr\Log\LoggerInterface;
+use Throwable;
+
+/**
+ * Runs one bounded sweep pass per tick.
+ *
+ * @SuppressWarnings(PHPMD.StaticAccess) DateTimeImmutable::createFromInterface
+ * is PHP's own conversion of the job clock.
+ */
+class FlowTimerWorker extends TimedJob {
+
+ /**
+ * The sweep interval, matching FlowScheduleWorker. A business timer's
+ * resolution is days; 300s is already finer than anything it measures.
+ *
+ * @var int
+ */
+ public const INTERVAL_SECONDS = 300;
+
+ /**
+ * App-config key for the per-pass batch limit, and its default.
+ */
+ public const CONFIG_BATCH = 'flow_timer_batch';
+
+ public const DEFAULT_BATCH = 200;
+
+ /**
+ * Constructor.
+ *
+ * @param ITimeFactory $time Job scheduling clock (kept by the base Job as $this->time).
+ * @param FlowTimerSweep $sweep The two range scans and what they fire.
+ * @param IAppConfig $appConfig Holds the batch limit override.
+ * @param LoggerInterface $logger The logger.
+ */
+ public function __construct(
+ ITimeFactory $time,
+ private readonly FlowTimerSweep $sweep,
+ private readonly IAppConfig $appConfig,
+ private readonly LoggerInterface $logger,
+ ) {
+ parent::__construct(time: $time);
+ $this->setInterval(seconds: self::INTERVAL_SECONDS);
+
+ }//end __construct()
+
+ /**
+ * Run one sweep pass.
+ *
+ * Counts logged are work PERFORMED (timers fired, rungs raised), not rows
+ * examined, and a pass that hit the batch limit says `truncated: true` so
+ * a backlog is visible instead of looking like a clean sweep.
+ *
+ * @param mixed $argument The job argument (unused).
+ *
+ * @return void
+ *
+ * @SuppressWarnings(PHPMD.UnusedFormalParameter) `$argument` is TimedJob's signature.
+ *
+ * @spec openspec/changes/flow-business-timers/specs/flow-business-timers/spec.md#requirement-the-sweep-is-bounded-to-due-work-by-index-not-by-a-page-of-candidates
+ */
+ protected function run($argument): void {
+ try {
+ $now = DateTimeImmutable::createFromInterface($this->time->getDateTime());
+ $result = $this->sweep->run(now: $now, batch: $this->batchLimit());
+
+ $quiet = ($result['expiriesFired'] === 0 && $result['rungsFired'] === 0 && $result['taskTimeouts'] === 0);
+ if ($quiet === false || $result['truncated'] === true || $result['errors'] > 0) {
+ $this->logger->info(
+ message: sprintf(
+ '[FlowTimerWorker] Fired %d expiry timer(s), %d escalation rung(s) and %d task timeout(s); truncated: %s; errors: %d',
+ $result['expiriesFired'],
+ $result['rungsFired'],
+ $result['taskTimeouts'],
+ var_export($result['truncated'], true),
+ $result['errors']
+ ),
+ context: ['file' => __FILE__, 'line' => __LINE__] + $result
+ );
+ }
+ } catch (Throwable $e) {
+ $this->logger->error(
+ message: '[FlowTimerWorker] Sweep pass failed: ' . $e->getMessage(),
+ context: ['file' => __FILE__, 'line' => __LINE__, 'exception' => $e]
+ );
+ }//end try
+
+ }//end run()
+
+ /**
+ * The batch limit: configured, else the default; never below one.
+ *
+ * @return int The limit.
+ */
+ private function batchLimit(): int {
+ $configured = (int)$this->appConfig->getValueString(
+ app: 'openregister',
+ key: self::CONFIG_BATCH,
+ default: (string)self::DEFAULT_BATCH
+ );
+
+ return max(1, $configured);
+ }//end batchLimit()
+}//end class
diff --git a/lib/BackgroundJob/TaskScheduledNotificationJob.php b/lib/BackgroundJob/TaskScheduledNotificationJob.php
new file mode 100644
index 0000000000..44e8104284
--- /dev/null
+++ b/lib/BackgroundJob/TaskScheduledNotificationJob.php
@@ -0,0 +1,348 @@
+
+ * SPDX-License-Identifier: EUPL-1.2
+ *
+ * @category BackgroundJob
+ * @package OCA\OpenRegister\BackgroundJob
+ *
+ * @author Conduction Development Team
+ * @copyright 2026 Conduction B.V.
+ * @license EUPL-1.2 https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
+ *
+ * @link https://OpenRegister.app
+ *
+ * @spec openspec/changes/flow-task-inbox-projections/specs/flow-task-projections/spec.md#requirement-deadline-notifications-filter-on-the-derived-predicate
+ */
+
+declare(strict_types=1);
+
+namespace OCA\OpenRegister\BackgroundJob;
+
+use DateTime;
+use DateTimeImmutable;
+use OCA\OpenRegister\Db\NotificationDedupeStateMapper;
+use OCA\OpenRegister\Db\Schema;
+use OCA\OpenRegister\Db\Task;
+use OCA\OpenRegister\Db\TaskInboxCriteria;
+use OCA\OpenRegister\Db\TaskMapper;
+use OCA\OpenRegister\Service\Notification\AnnotationNotificationDispatcher;
+use OCA\OpenRegister\Service\Notification\ScheduledFilterEvaluator;
+use OCA\OpenRegister\Service\Notification\TaskNotificationRules;
+use OCA\OpenRegister\Service\Notification\TaskObjectAdapter;
+use OCA\OpenRegister\Service\Task\TaskInboxService;
+use OCP\AppFramework\Utility\ITimeFactory;
+use OCP\BackgroundJob\TimedJob;
+use OCP\IAppConfig;
+use Psr\Log\LoggerInterface;
+use Throwable;
+
+/**
+ * The task-side scheduled sweep.
+ *
+ * @SuppressWarnings(PHPMD.CouplingBetweenObjects) The sweep joins the rule
+ * registry, the inbox query, the filter evaluator, the dedupe state and the
+ * dispatcher; each is the platform's one implementation of that concern.
+ * @SuppressWarnings(PHPMD.StaticAccess) DateTime conversions between the
+ * mutable clock the inbox takes and the immutable one the evaluator takes.
+ *
+ * @spec openspec/changes/flow-task-inbox-projections/specs/flow-task-projections/spec.md#requirement-deadline-notifications-filter-on-the-derived-predicate
+ */
+class TaskScheduledNotificationJob extends TimedJob {
+
+ /**
+ * Page size of the candidate sweep.
+ */
+ private const PAGE = 200;
+
+ /**
+ * Upper bound on tasks inspected per run.
+ */
+ private const MAX_PER_RUN = 5000;
+
+ /**
+ * The synthetic schema id the dedupe rows are keyed under. Tasks have no
+ * stored schema; this constant is the registry's stand-in.
+ */
+ public const DEDUPE_SCHEMA_ID = -1;
+
+ /**
+ * The uid the sweep queries as: an administrator's view, which the inbox
+ * does not narrow. It is never a recipient.
+ */
+ private const SWEEP_UID = '__openregister_task_sweep__';
+
+ /**
+ * Constructor.
+ *
+ * @param ITimeFactory $time The clock.
+ * @param TaskNotificationRules $rules The task rule registry.
+ * @param TaskMapper $tasks The candidate query.
+ * @param TaskInboxService $inbox The row the adapter is built from.
+ * @param ScheduledFilterEvaluator $filters The operator-object filter evaluator.
+ * @param NotificationDedupeStateMapper $dedupe Per-(rule, task) fire state.
+ * @param AnnotationNotificationDispatcher $dispatcher The one dispatcher.
+ * @param IAppConfig $appConfig Last-fire timestamps per rule.
+ * @param LoggerInterface $logger Failure reporting.
+ */
+ public function __construct(
+ ITimeFactory $time,
+ private readonly TaskNotificationRules $rules,
+ private readonly TaskMapper $tasks,
+ private readonly TaskInboxService $inbox,
+ private readonly ScheduledFilterEvaluator $filters,
+ private readonly NotificationDedupeStateMapper $dedupe,
+ private readonly AnnotationNotificationDispatcher $dispatcher,
+ private readonly IAppConfig $appConfig,
+ private readonly LoggerInterface $logger,
+ ) {
+ parent::__construct(time: $time);
+ $this->setInterval(seconds: 3600);
+
+ }//end __construct()
+
+ /**
+ * Fire every due scheduled task rule.
+ *
+ * @param mixed $argument Unused job argument.
+ *
+ * @return void
+ *
+ * @SuppressWarnings(PHPMD.UnusedFormalParameter) The signature is Nextcloud's.
+ *
+ * @spec openspec/changes/flow-task-inbox-projections/specs/flow-task-projections/spec.md#requirement-deadline-notifications-filter-on-the-derived-predicate
+ */
+ protected function run($argument): void {
+ $now = $this->time->getTime();
+
+ foreach ($this->rules->getRules() as $name => $rule) {
+ $trigger = ($rule['trigger'] ?? null);
+ if (is_array($trigger) === false || (string)($trigger['type'] ?? '') !== 'scheduled') {
+ continue;
+ }
+
+ if (($rule['enabled'] ?? true) === false) {
+ continue;
+ }
+
+ $interval = max(60, (int)($trigger['intervalSec'] ?? 86400));
+ if ($this->isDue(name: (string)$name, intervalSec: $interval, now: $now) === false) {
+ continue;
+ }
+
+ $this->fire(name: (string)$name, rule: $rule, trigger: $trigger);
+ $this->appConfig->setValueString('openregister', $this->stateKey(name: (string)$name), (string)$now);
+ }//end foreach
+ }//end run()
+
+ /**
+ * Evaluate one scheduled rule over the open, past-due tasks.
+ *
+ * @param string $name The rule name.
+ * @param array $rule The rule.
+ * @param array $trigger Its trigger block.
+ *
+ * @return void
+ *
+ * @spec openspec/changes/flow-task-inbox-projections/specs/flow-task-projections/spec.md#requirement-deadline-notifications-filter-on-the-derived-predicate
+ */
+ private function fire(string $name, array $rule, array $trigger): void {
+ $filter = (array)($trigger['filter'] ?? []);
+ // One clock instant for the whole sweep: the candidate query's
+ // derived-overdue filter and the rule's declared filter read the same
+ // "now", so the two derivations cannot disagree within a run.
+ $nowMutable = $this->time->getDateTime();
+ $nowDt = DateTimeImmutable::createFromMutable($nowMutable);
+ $schema = $this->schemaFor(name: $name, rule: $rule);
+ $watched = $this->watchedFields(trigger: $trigger);
+
+ $matched = 0;
+ $dispatched = 0;
+ $offset = 0;
+ while ($offset < self::MAX_PER_RUN) {
+ $page = $this->candidates(now: $nowMutable, offset: $offset);
+ if ($page === []) {
+ break;
+ }
+
+ $offset += count($page);
+
+ foreach ($page as $task) {
+ $row = $this->inbox->enrich(task: $task);
+ $adapter = new TaskObjectAdapter(task: $task, row: $row);
+ $payload = ($adapter->getObject() ?? []);
+
+ if ($this->filters->matches(objectData: $payload, filter: $filter, now: $nowDt) === false) {
+ continue;
+ }
+
+ $matched++;
+ $uuid = (string)$task->getUuid();
+ $fingerprint = $this->fingerprint(payload: $payload, watched: $watched);
+ $existing = $this->dedupe->findOne(schemaId: self::DEDUPE_SCHEMA_ID, ruleKey: $name, objectUuid: $uuid);
+ if ($existing !== null && (string)$existing->getFingerprint() === $fingerprint) {
+ continue;
+ }
+
+ try {
+ $this->dispatcher->dispatchWithSchema(
+ object: $adapter,
+ trigger: 'scheduled',
+ context: ['notificationName' => $name],
+ schema: $schema
+ );
+ $this->dedupe->upsert(
+ schemaId: self::DEDUPE_SCHEMA_ID,
+ ruleKey: $name,
+ objectUuid: $uuid,
+ fingerprint: $fingerprint,
+ now: $nowMutable,
+ dispatched: true
+ );
+ $dispatched++;
+ } catch (Throwable $failure) {
+ $this->logger->warning(
+ sprintf('[TaskScheduledNotificationJob] Rule "%s" failed for task %s: %s', $name, $uuid, $failure->getMessage())
+ );
+ }
+ }//end foreach
+
+ if (count($page) < self::PAGE) {
+ break;
+ }
+ }//end while
+
+ $this->logger->info(
+ sprintf('[TaskScheduledNotificationJob] Rule "%s": matched=%d dispatched=%d', $name, $matched, $dispatched)
+ );
+ }//end fire()
+
+ /**
+ * The candidate page: open tasks whose deadline lies before now, through
+ * the inbox query's derived-overdue filter.
+ *
+ * @param DateTime $now The clock instant.
+ * @param int $offset Page offset.
+ *
+ * @return array The page.
+ *
+ * @spec openspec/changes/flow-task-inbox-projections/specs/flow-task-projections/spec.md#requirement-deadline-notifications-filter-on-the-derived-predicate
+ */
+ private function candidates(DateTime $now, int $offset): array {
+ $criteria = new TaskInboxCriteria(
+ uid: self::SWEEP_UID,
+ isAdmin: true,
+ scope: TaskInboxCriteria::SCOPE_ALL,
+ isTerminal: false,
+ overdueAt: $now,
+ sort: TaskInboxCriteria::SORT_CREATED
+ );
+
+ try {
+ return $this->tasks->findInbox(criteria: $criteria, limit: self::PAGE, offset: $offset);
+ } catch (Throwable $failure) {
+ $this->logger->warning('[TaskScheduledNotificationJob] Candidate query failed: ' . $failure->getMessage());
+
+ return [];
+ }
+ }//end candidates()
+
+ /**
+ * A synthetic schema carrying ONLY the named rule, so the dispatcher's
+ * `scheduled` trigger fires exactly that rule.
+ *
+ * @param string $name The rule name.
+ * @param array $rule The rule.
+ *
+ * @return Schema The one-rule schema.
+ *
+ * @spec openspec/changes/flow-task-inbox-projections/specs/flow-task-projections/spec.md#requirement-deadline-notifications-filter-on-the-derived-predicate
+ */
+ private function schemaFor(string $name, array $rule): Schema {
+ $schema = $this->rules->buildSchema();
+ $schema->setConfiguration(['x-openregister-notifications' => [$name => $rule]]);
+
+ return $schema;
+ }//end schemaFor()
+
+ /**
+ * Whether a rule's interval has elapsed since it last fired.
+ *
+ * @param string $name The rule name.
+ * @param int $intervalSec The declared interval.
+ * @param int $now The clock.
+ *
+ * @return bool True when due.
+ *
+ * @spec openspec/changes/flow-task-inbox-projections/specs/flow-task-projections/spec.md#requirement-deadline-notifications-filter-on-the-derived-predicate
+ */
+ private function isDue(string $name, int $intervalSec, int $now): bool {
+ $last = (int)$this->appConfig->getValueString('openregister', $this->stateKey(name: $name), '0');
+
+ return ($now - $last) >= $intervalSec;
+ }//end isDue()
+
+ /**
+ * The app-config key holding a rule's last fire time.
+ *
+ * @param string $name The rule name.
+ *
+ * @return string The key.
+ */
+ private function stateKey(string $name): string {
+ return 'sched_task:' . $name;
+ }//end stateKey()
+
+ /**
+ * The payload fields whose values re-arm the rule when they change.
+ *
+ * @param array $trigger The trigger block.
+ *
+ * @return array Sorted field names; empty means fire once per task.
+ */
+ private function watchedFields(array $trigger): array {
+ $fields = [];
+ foreach ((array)($trigger['dedupeFields'] ?? []) as $field) {
+ if (is_string($field) === true && $field !== '') {
+ $fields[] = $field;
+ }
+ }
+
+ $fields = array_values(array_unique($fields));
+ sort($fields);
+
+ return $fields;
+ }//end watchedFields()
+
+ /**
+ * The dedupe fingerprint over the watched fields.
+ *
+ * @param array $payload The adapter payload.
+ * @param array $watched The watched field names.
+ *
+ * @return string SHA-1 of the watched values.
+ */
+ private function fingerprint(array $payload, array $watched): string {
+ $values = [];
+ foreach ($watched as $field) {
+ $values[$field] = ($payload[$field] ?? null);
+ }
+
+ return sha1((string)json_encode($values));
+ }//end fingerprint()
+}//end class
diff --git a/lib/Calendar/CalendarEventTransformer.php b/lib/Calendar/CalendarEventTransformer.php
index 91cc7d8559..b9ff0b62f3 100644
--- a/lib/Calendar/CalendarEventTransformer.php
+++ b/lib/Calendar/CalendarEventTransformer.php
@@ -139,7 +139,7 @@ public function transform(
// URL to OpenRegister object.
$register = $object->getRegister();
- $url = '/apps/openregister/#/objects/' . $register . '/' . $schemaId . '/' . $objectUuid;
+ $url = '/apps/openregister/objects/' . $register . '/' . $schemaId . '/' . $objectUuid;
$veventProperties['URL'] = [$url, []];
return [
diff --git a/lib/Command/AdoptLeafOrganisationsCommand.php b/lib/Command/AdoptLeafOrganisationsCommand.php
new file mode 100644
index 0000000000..53d2aa4d1e
--- /dev/null
+++ b/lib/Command/AdoptLeafOrganisationsCommand.php
@@ -0,0 +1,591 @@
+
+ * @copyright 2026 Conduction B.V.
+ * @license EUPL-1.2 https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
+ *
+ * @version GIT:
+ *
+ * @link https://OpenRegister.app
+ *
+ * SPDX-License-Identifier: EUPL-1.2
+ * SPDX-FileCopyrightText: 2026 Conduction B.V.
+ */
+
+declare(strict_types=1);
+
+namespace OCA\OpenRegister\Command;
+
+use DateTime;
+use OCA\OpenRegister\Db\Organisation;
+use OCA\OpenRegister\Db\OrganisationMapper;
+use OCA\OpenRegister\Service\ObjectService;
+use Psr\Log\LoggerInterface;
+use Symfony\Component\Console\Command\Command;
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Input\InputOption;
+use Symfony\Component\Console\Output\OutputInterface;
+use Throwable;
+
+/**
+ * Adopt a leaf app's organisation objects into OpenRegister's Organisation.
+ *
+ * @spec openspec/changes/consolidate-organisation-on-or/tasks.md#5-leaf-app-consolidation
+ *
+ * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
+ * @SuppressWarnings(PHPMD.ExcessiveClassComplexity) The spread is the point: each
+ * branch is one rule about what an adoption keeps, merges or drops, and the
+ * class is at 53 against a threshold of 50. Collapsing branches to satisfy the
+ * number would hide the rules rather than simplify them, and every one of them
+ * is pinned by its own test.
+ */
+class AdoptLeafOrganisationsCommand extends Command {
+ /**
+ * The legal identifiers a match may be made on, in precedence order.
+ *
+ * A name is deliberately absent. Two organisations sharing a name are
+ * routine; two sharing an OIN are the same body.
+ *
+ * @var array
+ */
+ private const LEGAL_IDENTIFIERS = ['oin', 'rsin', 'kvk'];
+
+ /**
+ * Leaf property name to Organisation setter suffix.
+ *
+ * Only properties Organisation actually declares are listed. Anything the
+ * leaf schema carries beyond these is reported rather than dropped quietly,
+ * because a property OR does not declare is a property OR discards.
+ *
+ * @var array
+ */
+ private const FIELD_MAP = [
+ 'name' => 'Name',
+ 'summary' => 'Summary',
+ 'description' => 'Description',
+ 'oin' => 'Oin',
+ 'tooi' => 'Tooi',
+ 'rsin' => 'Rsin',
+ 'kvk' => 'Kvk',
+ 'pki' => 'Pki',
+ 'image' => 'Image',
+ 'type' => 'Type',
+ 'status' => 'Status',
+ 'registrationStatus' => 'RegistrationStatus',
+ ];
+
+ /**
+ * Wire the mappers and the object reader.
+ *
+ * @param OrganisationMapper $organisationMapper The Organisation mapper.
+ * @param ObjectService $objectService Reader for the leaf objects.
+ * @param LoggerInterface $logger Logger.
+ *
+ * @return void
+ *
+ * @spec openspec/changes/consolidate-organisation-on-or/specs/consolidated-organisation/spec.md#requirement-a-leaf-apps-organisations-are-adopted-not-re-created-req-org-106
+ */
+ public function __construct(
+ private readonly OrganisationMapper $organisationMapper,
+ private readonly ObjectService $objectService,
+ private readonly LoggerInterface $logger,
+ ) {
+ parent::__construct();
+ }//end __construct()
+
+ /**
+ * Define command name, description, and options.
+ *
+ * @return void
+ *
+ * @spec openspec/changes/consolidate-organisation-on-or/specs/consolidated-organisation/spec.md#requirement-a-leaf-apps-organisations-are-adopted-not-re-created-req-org-106
+ */
+ protected function configure(): void {
+ $this->setName(name: 'openregister:organisations:adopt')
+ ->setDescription(
+ 'Adopt a leaf app\'s own organisation objects into OpenRegister\'s Organisation, '
+ . 'preserving each uuid and recording a merge where the same legal entity already exists.'
+ )
+ ->addOption(
+ 'register',
+ null,
+ InputOption::VALUE_REQUIRED,
+ 'The register slug holding the leaf organisation objects (for example `publication`).'
+ )
+ ->addOption(
+ 'schema',
+ null,
+ InputOption::VALUE_REQUIRED,
+ 'The leaf schema slug to adopt from. Defaults to `organization`.',
+ 'organization'
+ )
+ ->addOption(
+ 'apply',
+ null,
+ InputOption::VALUE_NONE,
+ 'Actually write. Without this flag the command reports what it WOULD do.'
+ );
+ }//end configure()
+
+ /**
+ * Read the leaf rows and adopt each one.
+ *
+ * @param InputInterface $input Console input.
+ * @param OutputInterface $output Console output stream.
+ *
+ * @return int Symfony command exit code.
+ *
+ * @SuppressWarnings(PHPMD.CyclomaticComplexity)
+ * @SuppressWarnings(PHPMD.NPathComplexity)
+ *
+ * @spec openspec/changes/consolidate-organisation-on-or/specs/consolidated-organisation/spec.md#requirement-a-leaf-apps-organisations-are-adopted-not-re-created-req-org-106
+ */
+ protected function execute(InputInterface $input, OutputInterface $output): int {
+ $registerSlug = (string)$input->getOption('register');
+ $schemaSlug = (string)$input->getOption('schema');
+ $dryRun = ((bool)$input->getOption('apply') === false);
+
+ if ($registerSlug === '') {
+ $output->writeln('--register is required.');
+ return Command::FAILURE;
+ }
+
+ if ($dryRun === true) {
+ $output->writeln(
+ 'Running in DRY-RUN mode — nothing will be written. '
+ . 'Re-run with --apply to adopt.'
+ );
+ }
+
+ try {
+ $rows = $this->objectService->searchObjectsBySlug(
+ $registerSlug,
+ $schemaSlug,
+ ['_limit' => 5000],
+ false,
+ false
+ );
+ } catch (Throwable $e) {
+ $output->writeln(sprintf('Could not read %s/%s: %s', $registerSlug, $schemaSlug, $e->getMessage()));
+ return Command::FAILURE;
+ }
+
+ if (is_array($rows) === false) {
+ $output->writeln('The object reader returned a count rather than rows.');
+ return Command::FAILURE;
+ }
+
+ $existing = $this->existingOrganisations();
+ $adopted = 0;
+ $merged = 0;
+ $skipped = 0;
+ $failed = 0;
+
+ foreach ($rows as $row) {
+ $outcome = $this->adoptRow(
+ row: $row,
+ existing: $existing,
+ dryRun: $dryRun,
+ output: $output
+ );
+
+ $adopted += $outcome['adopted'];
+ $merged += $outcome['merged'];
+ $skipped += $outcome['skipped'];
+ $failed += $outcome['failed'];
+ }//end foreach
+
+ $suffix = '';
+ if ($dryRun === true) {
+ $suffix = ' (dry run — nothing written)';
+ }
+
+ $output->writeln(
+ sprintf(
+ 'Done. Adopted=%d (of which merged=%d), skipped=%d, failed=%d%s',
+ $adopted,
+ $merged,
+ $skipped,
+ $failed,
+ $suffix
+ )
+ );
+
+ $this->logger->info(
+ 'OpenRegister: adopted leaf organisations',
+ [
+ 'register' => $registerSlug,
+ 'schema' => $schemaSlug,
+ 'adopted' => $adopted,
+ 'merged' => $merged,
+ 'skipped' => $skipped,
+ 'failed' => $failed,
+ 'dryRun' => $dryRun,
+ ]
+ );
+
+ if ($failed > 0) {
+ return Command::FAILURE;
+ }
+
+ return Command::SUCCESS;
+ }//end execute()
+
+ /**
+ * Adopt one leaf row, reporting what happened to it.
+ *
+ * @param mixed $row The row as the reader returned it.
+ * @param array> $existing Organisations already on the instance,
+ * keyed by uuid. It grows as rows are
+ * adopted, so a legal identifier appearing
+ * twice within one run merges the second
+ * occurrence too.
+ * @param bool $dryRun Whether to report rather than write.
+ * @param OutputInterface $output Console output stream.
+ *
+ * @return array{adopted:int, merged:int, skipped:int, failed:int} The tally for this row.
+ *
+ * @spec openspec/changes/consolidate-organisation-on-or/specs/consolidated-organisation/spec.md#requirement-a-leaf-apps-organisations-are-adopted-not-re-created-req-org-106
+ */
+ private function adoptRow(mixed $row, array &$existing, bool $dryRun, OutputInterface $output): array {
+ $none = ['adopted' => 0, 'merged' => 0, 'skipped' => 0, 'failed' => 0];
+
+ $fields = self::toFields(row: $row);
+ $uuid = (string)($fields['uuid'] ?? '');
+
+ if ($uuid === '') {
+ $output->writeln(' SKIP a row with no uuid: it has no idempotency key.');
+ return array_merge($none, ['skipped' => 1]);
+ }
+
+ if (isset($existing[$uuid]) === true) {
+ $output->writeln(sprintf(' SKIP %s: already adopted.', $uuid));
+ return array_merge($none, ['skipped' => 1]);
+ }
+
+ $target = self::findMergeTarget(row: $fields, existing: array_values($existing));
+
+ $mergeNote = '';
+ $mergedCount = 0;
+ if ($target !== null) {
+ $mergeNote = sprintf(' -> merges into %s', $target['uuid']);
+ $mergedCount = 1;
+ }
+
+ $output->writeln(
+ sprintf('%s (%s)%s', $uuid, (string)($fields['name'] ?? 'unnamed'), $mergeNote)
+ );
+
+ $this->reportUndeclared(fields: $fields, output: $output);
+
+ if ($dryRun === true) {
+ $output->writeln(' WOULD ADOPT');
+ return $none;
+ }
+
+ try {
+ $saved = $this->organisationMapper->insert(
+ self::buildOrganisation(fields: $fields, mergeTarget: $target)
+ );
+ } catch (Throwable $e) {
+ $output->writeln(sprintf(' FAILED: %s', $e->getMessage()));
+ return array_merge($none, ['failed' => 1]);
+ }
+
+ $existing[$uuid] = self::toCandidate(organisation: $saved);
+ $output->writeln(' ADOPTED');
+
+ return array_merge($none, ['adopted' => 1, 'merged' => $mergedCount]);
+ }//end adoptRow()
+
+ /**
+ * Name the properties this adoption will not carry over.
+ *
+ * @param array $fields The leaf row's fields.
+ * @param OutputInterface $output Console output stream.
+ *
+ * @return void
+ *
+ * @spec openspec/changes/consolidate-organisation-on-or/specs/consolidated-organisation/spec.md#requirement-a-leaf-apps-organisations-are-adopted-not-re-created-req-org-106
+ */
+ private function reportUndeclared(array $fields, OutputInterface $output): void {
+ $dropped = self::undeclaredProperties(row: $fields);
+ if ($dropped === []) {
+ return;
+ }
+
+ $phrase = sprintf('%d properties have', count($dropped));
+ if (count($dropped) === 1) {
+ $phrase = '1 property has';
+ }
+
+ $output->writeln(
+ sprintf(
+ ' %s no column on Organisation and will NOT be carried over: %s',
+ $phrase,
+ implode(', ', $dropped)
+ )
+ );
+ }//end reportUndeclared()
+
+ /**
+ * Normalise a legal identifier for comparison.
+ *
+ * The same OIN is written with and without spaces and dots depending on who
+ * typed it, so a literal comparison misses matches that are plainly the same
+ * body. Everything that is not a letter or a digit is dropped.
+ *
+ * @param mixed $value The stored identifier.
+ *
+ * @return string The comparable form, or '' when there is nothing to compare.
+ *
+ * @spec openspec/changes/consolidate-organisation-on-or/specs/consolidated-organisation/spec.md#requirement-a-leaf-apps-organisations-are-adopted-not-re-created-req-org-106
+ */
+ public static function normaliseIdentifier(mixed $value): string {
+ if (is_string($value) === false && is_int($value) === false) {
+ return '';
+ }
+
+ $stripped = preg_replace('/[^a-z0-9]/i', '', (string)$value);
+ if (is_string($stripped) === false) {
+ return '';
+ }
+
+ return strtolower($stripped);
+ }//end normaliseIdentifier()
+
+ /**
+ * Find the organisation this row is the same legal entity as, if any.
+ *
+ * Matching runs on OIN, then RSIN, then KVK, and stops at the first
+ * identifier the row actually carries. A name is never matched on: two
+ * organisations sharing a name are routine, and collapsing them would
+ * destroy data that no later step can recover.
+ *
+ * Among several matches the LOWEST id is canonical, so a repeated run
+ * chooses the same survivor. A candidate that was itself merged away is
+ * deprioritised rather than excluded: pointing at it still resolves,
+ * because the resolver walks the chain.
+ *
+ * @param array $row The leaf row's fields.
+ * @param array> $existing Candidate organisations.
+ *
+ * @return array|null The organisation to merge into, or null.
+ *
+ * @spec openspec/changes/consolidate-organisation-on-or/specs/consolidated-organisation/spec.md#requirement-a-leaf-apps-organisations-are-adopted-not-re-created-req-org-106
+ */
+ public static function findMergeTarget(array $row, array $existing): ?array {
+ foreach (self::LEGAL_IDENTIFIERS as $field) {
+ $needle = self::normaliseIdentifier(value: ($row[$field] ?? null));
+ if ($needle === '') {
+ continue;
+ }
+
+ $matches = [];
+ foreach ($existing as $candidate) {
+ if (self::normaliseIdentifier(value: ($candidate[$field] ?? null)) === $needle) {
+ $matches[] = $candidate;
+ }
+ }
+
+ if ($matches === []) {
+ continue;
+ }
+
+ usort(
+ $matches,
+ static function (array $a, array $b) {
+ $aMerged = 0;
+ if (($a['mergedInto'] ?? null) !== null) {
+ $aMerged = 1;
+ }
+
+ $bMerged = 0;
+ if (($b['mergedInto'] ?? null) !== null) {
+ $bMerged = 1;
+ }
+
+ if ($aMerged !== $bMerged) {
+ return ($aMerged <=> $bMerged);
+ }
+
+ return ((int)($a['id'] ?? 0) <=> (int)($b['id'] ?? 0));
+ }
+ );
+
+ return $matches[0];
+ }//end foreach
+
+ return null;
+ }//end findMergeTarget()
+
+ /**
+ * The leaf properties Organisation has nowhere to put.
+ *
+ * OpenRegister discards a property its schema does not declare, and it does
+ * so with a 200 and the object back, so an adoption that loses fields looks
+ * exactly like one that did not. Naming them is the whole point.
+ *
+ * @param array $row The leaf row's fields.
+ *
+ * @return array The property names that will not be carried over.
+ *
+ * @spec openspec/changes/consolidate-organisation-on-or/specs/consolidated-organisation/spec.md#requirement-a-leaf-apps-organisations-are-adopted-not-re-created-req-org-106
+ */
+ public static function undeclaredProperties(array $row): array {
+ $dropped = [];
+ foreach (array_keys($row) as $property) {
+ if (str_starts_with($property, '@') === true || $property === 'id' || $property === 'uuid') {
+ continue;
+ }
+
+ if (isset(self::FIELD_MAP[$property]) === true) {
+ continue;
+ }
+
+ $dropped[] = $property;
+ }
+
+ sort($dropped);
+
+ return $dropped;
+ }//end undeclaredProperties()
+
+ /**
+ * Flatten an object row into a plain field map.
+ *
+ * @param mixed $row The row as the object reader returned it.
+ *
+ * @return array The fields, with the uuid resolved.
+ *
+ * @spec openspec/changes/consolidate-organisation-on-or/specs/consolidated-organisation/spec.md#requirement-a-leaf-apps-organisations-are-adopted-not-re-created-req-org-106
+ */
+ public static function toFields(mixed $row): array {
+ if (is_object($row) === true && method_exists($row, 'jsonSerialize') === true) {
+ $row = $row->jsonSerialize();
+ }
+
+ if (is_array($row) === false) {
+ return [];
+ }
+
+ $self = ($row['@self'] ?? []);
+ $uuid = '';
+ if (is_array($self) === true) {
+ $uuid = (string)($self['uuid'] ?? ($self['id'] ?? ''));
+ }
+
+ if ($uuid === '') {
+ $uuid = (string)($row['uuid'] ?? ($row['id'] ?? ''));
+ }
+
+ $row['uuid'] = $uuid;
+
+ return $row;
+ }//end toFields()
+
+ /**
+ * Build the Organisation to insert for one leaf row.
+ *
+ * @param array $fields The leaf row's fields.
+ * @param array|null $mergeTarget The organisation to merge into, if any.
+ *
+ * @return Organisation The organisation, not yet persisted.
+ *
+ * @spec openspec/changes/consolidate-organisation-on-or/specs/consolidated-organisation/spec.md#requirement-a-leaf-apps-organisations-are-adopted-not-re-created-req-org-106
+ */
+ public static function buildOrganisation(array $fields, ?array $mergeTarget = null): Organisation {
+ $organisation = new Organisation();
+ $organisation->setUuid((string)$fields['uuid']);
+
+ foreach (self::FIELD_MAP as $property => $suffix) {
+ $value = ($fields[$property] ?? null);
+ if ($value === null || $value === '') {
+ continue;
+ }
+
+ if (is_scalar($value) === false) {
+ continue;
+ }
+
+ $organisation->{'set' . $suffix}((string)$value);
+ }
+
+ // A slug is derived from the uuid rather than the name. Two adopted rows
+ // can legitimately share a name, and a name-derived slug would collide.
+ $organisation->setSlug('adopted-' . substr((string)$fields['uuid'], 0, 36));
+
+ if ($mergeTarget !== null) {
+ $organisation->setMergedInto((string)$mergeTarget['uuid']);
+ $organisation->setMergedAt(new DateTime());
+ }
+
+ return $organisation;
+ }//end buildOrganisation()
+
+ /**
+ * Reduce an Organisation to the fields matching needs.
+ *
+ * @param Organisation $organisation The organisation.
+ *
+ * @return array The candidate record.
+ *
+ * @spec openspec/changes/consolidate-organisation-on-or/specs/consolidated-organisation/spec.md#requirement-a-leaf-apps-organisations-are-adopted-not-re-created-req-org-106
+ */
+ public static function toCandidate(Organisation $organisation): array {
+ return [
+ 'id' => (int)$organisation->getId(),
+ 'uuid' => (string)$organisation->getUuid(),
+ 'oin' => $organisation->getOin(),
+ 'rsin' => $organisation->getRsin(),
+ 'kvk' => $organisation->getKvk(),
+ 'mergedInto' => $organisation->getMergedInto(),
+ ];
+ }//end toCandidate()
+
+ /**
+ * Every organisation already on the instance, keyed by uuid.
+ *
+ * @return array> The candidates.
+ */
+ private function existingOrganisations(): array {
+ $candidates = [];
+ foreach ($this->organisationMapper->findAll(limit: 10000, offset: 0, filters: []) as $organisation) {
+ $candidates[(string)$organisation->getUuid()] = self::toCandidate(organisation: $organisation);
+ }
+
+ return $candidates;
+ }//end existingOrganisations()
+}//end class
diff --git a/lib/Command/PruneRetiredSchemasCommand.php b/lib/Command/PruneRetiredSchemasCommand.php
new file mode 100644
index 0000000000..53a18d8570
--- /dev/null
+++ b/lib/Command/PruneRetiredSchemasCommand.php
@@ -0,0 +1,358 @@
+
+ * @copyright 2026 Conduction B.V.
+ * @license EUPL-1.2 https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
+ *
+ * @version GIT:
+ *
+ * @link https://OpenRegister.app
+ *
+ * SPDX-License-Identifier: EUPL-1.2
+ * SPDX-FileCopyrightText: 2026 Conduction B.V.
+ */
+
+declare(strict_types=1);
+
+namespace OCA\OpenRegister\Command;
+
+use OCA\OpenRegister\Db\MagicMapper;
+use OCA\OpenRegister\Db\Register;
+use OCA\OpenRegister\Db\RegisterMapper;
+use OCA\OpenRegister\Db\Schema;
+use OCA\OpenRegister\Db\SchemaMapper;
+use OCA\OpenRegister\Service\SchemaDeletionService;
+use Symfony\Component\Console\Command\Command;
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Input\InputOption;
+use Symfony\Component\Console\Output\OutputInterface;
+
+/**
+ * Remove schemas an app has retired from its descriptor.
+ *
+ * @spec openspec/specs/schema-import/spec.md#requirement-a-schema-retired-from-a-descriptor-must-be-removable-from-the-instance
+ *
+ * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
+ */
+class PruneRetiredSchemasCommand extends Command {
+ /**
+ * Wire the mappers and the cascade service.
+ *
+ * @param SchemaMapper $schemaMapper Schema lookup mapper (app-scoped resolution).
+ * @param RegisterMapper $registerMapper Register mapper, to unlink the retired id.
+ * @param MagicMapper $magicMapper Magic table resolver, for the object-count guard.
+ * @param SchemaDeletionService $deletionService Cascade teardown (objects, tables, row).
+ *
+ * @return void
+ *
+ * @spec openspec/specs/schema-import/spec.md#requirement-a-schema-retired-from-a-descriptor-must-be-removable-from-the-instance
+ */
+ public function __construct(
+ private readonly SchemaMapper $schemaMapper,
+ private readonly RegisterMapper $registerMapper,
+ private readonly MagicMapper $magicMapper,
+ private readonly SchemaDeletionService $deletionService,
+ ) {
+ parent::__construct();
+ }//end __construct()
+
+ /**
+ * Define command name, description, and options.
+ *
+ * @return void
+ *
+ * @spec openspec/specs/schema-import/spec.md#requirement-a-schema-retired-from-a-descriptor-must-be-removable-from-the-instance
+ */
+ protected function configure(): void {
+ $this->setName(name: 'openregister:schemas:prune-retired')
+ ->setDescription(
+ 'Remove schemas an app has retired from its register descriptor '
+ . '(the import unions ids, so it never removes them itself).'
+ )
+ ->addOption(
+ 'app',
+ null,
+ InputOption::VALUE_REQUIRED,
+ 'The owning application id, exactly as it appears in the schema\'s `application` column '
+ . '(for example `filinq`). Scoping is mandatory: it is what stops this command reaching '
+ . 'a same-slug schema another app owns.'
+ )
+ ->addOption(
+ 'slug',
+ null,
+ (InputOption::VALUE_REQUIRED | InputOption::VALUE_IS_ARRAY),
+ 'A retired schema slug. Repeat the option to prune several.'
+ )
+ ->addOption(
+ 'apply',
+ null,
+ InputOption::VALUE_NONE,
+ 'Actually delete. Without this flag the command reports what it WOULD delete.'
+ )
+ ->addOption(
+ 'force',
+ null,
+ InputOption::VALUE_NONE,
+ 'Also delete a schema that still owns objects (DANGEROUS — drops those objects). '
+ . 'Has no effect without --apply.'
+ );
+ }//end configure()
+
+ /**
+ * Resolve each named slug within the app, then cascade-delete it.
+ *
+ * @param InputInterface $input Console input.
+ * @param OutputInterface $output Console output stream.
+ *
+ * @return int Symfony command exit code.
+ *
+ * @SuppressWarnings(PHPMD.CyclomaticComplexity)
+ * @SuppressWarnings(PHPMD.NPathComplexity)
+ * @SuppressWarnings(PHPMD.ExcessiveMethodLength)
+ *
+ * @spec openspec/specs/schema-import/spec.md#requirement-a-schema-retired-from-a-descriptor-must-be-removable-from-the-instance
+ */
+ protected function execute(InputInterface $input, OutputInterface $output): int {
+ $appId = (string)$input->getOption('app');
+ $slugs = (array)$input->getOption('slug');
+ $apply = (bool)$input->getOption('apply');
+ $force = (bool)$input->getOption('force');
+ $dryRun = ($apply === false);
+
+ if ($appId === '') {
+ $output->writeln('--app is required.');
+ return Command::FAILURE;
+ }
+
+ if ($slugs === []) {
+ $output->writeln('At least one --slug is required.');
+ return Command::FAILURE;
+ }
+
+ if ($dryRun === true) {
+ $output->writeln(
+ 'Running in DRY-RUN mode — nothing will be deleted. '
+ . 'Re-run with --apply to perform deletions.'
+ );
+ }
+
+ $pruned = 0;
+ $skipped = 0;
+ $missing = 0;
+
+ foreach ($slugs as $slug) {
+ $slug = (string)$slug;
+ $schema = $this->schemaMapper->findByApplicationAndSlug(slug: $slug, application: $appId);
+
+ if ($schema === null) {
+ $missing++;
+ $output->writeln(
+ sprintf(
+ 'SKIP "%s": app "%s" owns no schema with that slug (already pruned, or never imported).',
+ $slug,
+ $appId
+ )
+ );
+ continue;
+ }
+
+ $schemaId = (int)$schema->getId();
+ $objectCount = $this->countObjectsForSchema(schema: $schema);
+ $linkedRegisters = $this->registersReferencing(schemaId: $schemaId);
+
+ $output->writeln(
+ sprintf(
+ '%s (id=%d, app=%s): %d object(s), referenced by %d register(s)',
+ $slug,
+ $schemaId,
+ $appId,
+ $objectCount,
+ count($linkedRegisters)
+ )
+ );
+
+ if ($objectCount > 0 && $force === false) {
+ $skipped++;
+ $output->writeln(
+ ' SKIP — still owns objects. Re-run with --force to drop them, '
+ . 'or migrate them first.'
+ );
+ continue;
+ }
+
+ if ($dryRun === true) {
+ $output->writeln(sprintf(' WOULD DELETE (objects=%d)', $objectCount));
+ continue;
+ }
+
+ // Unlink first. cascadeDeleteSchema() removes the row, and a register
+ // left pointing at a missing id makes every later slug resolution in
+ // that register scan a dangling reference.
+ foreach ($linkedRegisters as $register) {
+ $remaining = self::unlinkSchemaId(schemaRefs: $register->getSchemas(), schemaId: $schemaId);
+ $register->setSchemas($remaining);
+ $this->registerMapper->update($register);
+ $output->writeln(
+ sprintf(' unlinked from register id=%d (%s)', (int)$register->getId(), (string)$register->getSlug())
+ );
+ }
+
+ try {
+ $result = $this->deletionService->cascadeDeleteSchema(schema: $schema);
+ } catch (\Throwable $e) {
+ $skipped++;
+ $output->writeln(sprintf(' FAILED: %s', $e->getMessage()));
+ continue;
+ }
+
+ $pruned++;
+ $tableDropped = 'no';
+ if ($result['tableDropped'] === true) {
+ $tableDropped = 'yes';
+ }
+
+ $output->writeln(
+ sprintf(
+ ' DELETED (objects removed=%d, table dropped=%s)',
+ (int)$result['deletedCount'],
+ $tableDropped
+ )
+ );
+ }//end foreach
+
+ $suffix = '';
+ if ($dryRun === true) {
+ $suffix = ' (dry run — no writes performed)';
+ }
+
+ $output->writeln(
+ sprintf(
+ 'Done. Pruned=%d, skipped=%d, not-found=%d%s',
+ $pruned,
+ $skipped,
+ $missing,
+ $suffix
+ )
+ );
+
+ return Command::SUCCESS;
+ }//end execute()
+
+ /**
+ * Drop one schema id from a register's stored schema list.
+ *
+ * The stored list holds ids as ints or as strings depending on which import
+ * era wrote it, so `"74"` and `74` are the same reference and both have to
+ * go. A strict comparison here would leave the string form behind and the
+ * register would keep pointing at a row that no longer exists.
+ *
+ * Entries that are not numeric at all are preserved untouched: they are not
+ * this id, and silently dropping them would corrupt the register.
+ *
+ * @param array $schemaRefs The register's stored schema list.
+ * @param int $schemaId The schema id to remove.
+ *
+ * @return array The list with every form of that id removed.
+ *
+ * @spec openspec/specs/schema-import/spec.md#requirement-a-schema-retired-from-a-descriptor-must-be-removable-from-the-instance
+ */
+ public static function unlinkSchemaId(array $schemaRefs, int $schemaId): array {
+ return array_values(
+ array_filter(
+ $schemaRefs,
+ static function ($ref) use ($schemaId) {
+ if (is_int($ref) === false && is_string($ref) === false) {
+ return true;
+ }
+
+ if (is_string($ref) === true && is_numeric($ref) === false) {
+ return true;
+ }
+
+ return ((int)$ref !== $schemaId);
+ }
+ )
+ );
+ }//end unlinkSchemaId()
+
+ /**
+ * Count objects a schema owns across every register that references it.
+ *
+ * @param Schema $schema The schema to count objects for.
+ *
+ * @return int Total object count across the schema's magic tables.
+ *
+ * @spec openspec/specs/schema-import/spec.md#requirement-a-schema-retired-from-a-descriptor-must-be-removable-from-the-instance
+ */
+ private function countObjectsForSchema(Schema $schema): int {
+ $total = 0;
+
+ foreach ($this->registersReferencing(schemaId: (int)$schema->getId()) as $register) {
+ if ($this->magicMapper->tableExistsForRegisterSchema(register: $register, schema: $schema) === false) {
+ continue;
+ }
+
+ try {
+ $total += $this->magicMapper->countObjectsInRegisterSchemaTable(
+ query: [],
+ register: $register,
+ schema: $schema
+ );
+ } catch (\Throwable $e) {
+ // An unreadable magic table cannot be counted. Treat it as
+ // non-empty so the guard errs towards keeping data.
+ $total++;
+ }
+ }
+
+ return $total;
+ }//end countObjectsForSchema()
+
+ /**
+ * Every register whose schema list references this schema id.
+ *
+ * @param int $schemaId The schema id to look for.
+ *
+ * @return Register[] The referencing registers.
+ *
+ * @spec openspec/specs/schema-import/spec.md#requirement-a-schema-retired-from-a-descriptor-must-be-removable-from-the-instance
+ */
+ private function registersReferencing(int $schemaId): array {
+ $matches = [];
+
+ foreach ($this->registerMapper->findAll(_rbac: false, _multitenancy: false) as $register) {
+ foreach ($register->getSchemas() as $ref) {
+ if ((int)$ref === $schemaId) {
+ $matches[] = $register;
+ break;
+ }
+ }
+ }
+
+ return $matches;
+ }//end registersReferencing()
+}//end class
diff --git a/lib/Command/RollbackApprovalMigrationCommand.php b/lib/Command/RollbackApprovalMigrationCommand.php
new file mode 100644
index 0000000000..f056ebe08c
--- /dev/null
+++ b/lib/Command/RollbackApprovalMigrationCommand.php
@@ -0,0 +1,234 @@
+
+ * @copyright 2026 Conduction B.V.
+ * @license EUPL-1.2 https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
+ *
+ * @version GIT:
+ *
+ * @link https://www.OpenRegister.nl
+ *
+ * @spec openspec/changes/flow-approval-consolidation/specs/flow-approval-consolidation/spec.md#requirement-every-in-flight-approval-survives-the-migration-at-the-same-position
+ */
+
+declare(strict_types=1);
+
+namespace OCA\OpenRegister\Command;
+
+use OCA\OpenRegister\Db\Task;
+use OCA\OpenRegister\Db\TaskMapper;
+use OCA\OpenRegister\Service\Task\TaskState;
+use OCP\IDBConnection;
+use Symfony\Component\Console\Command\Command;
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Input\InputOption;
+use Symfony\Component\Console\Output\OutputInterface;
+use Throwable;
+
+/**
+ * Write migrated decisions back onto the kept approval-step rows.
+ *
+ * @spec openspec/changes/flow-approval-consolidation/specs/flow-approval-consolidation/spec.md#requirement-every-in-flight-approval-survives-the-migration-at-the-same-position
+ *
+ * @SuppressWarnings(PHPMD.StaticAccess) TaskState is the published,
+ * stateless state vocabulary; calling it statically is the point.
+ */
+class RollbackApprovalMigrationCommand extends Command {
+
+ /**
+ * Constructor.
+ *
+ * @param IDBConnection $db Reads the step rows and writes the decisions back.
+ * @param TaskMapper $tasks Reads the migrated tasks.
+ */
+ public function __construct(
+ private readonly IDBConnection $db,
+ private readonly TaskMapper $tasks,
+ ) {
+ parent::__construct();
+ }//end __construct()
+
+ /**
+ * Configure the command.
+ *
+ * @return void
+ *
+ * @spec openspec/changes/flow-approval-consolidation/specs/flow-approval-consolidation/spec.md#requirement-every-in-flight-approval-survives-the-migration-at-the-same-position
+ */
+ protected function configure(): void {
+ $this->setName(name: 'openregister:approval:rollback-to-steps')
+ ->setDescription(
+ description: 'Write decisions taken on migrated approval tasks back onto the legacy step rows, and report what the legacy schema cannot hold'
+ )
+ ->addOption(
+ name: 'dry-run',
+ shortcut: null,
+ mode: InputOption::VALUE_NONE,
+ description: 'Report what would be written back without changing any row'
+ );
+ }//end configure()
+
+ /**
+ * Execute the reverse repair.
+ *
+ * @param InputInterface $input Command input.
+ * @param OutputInterface $output Command output.
+ *
+ * @return int Zero on success.
+ *
+ * @spec openspec/changes/flow-approval-consolidation/specs/flow-approval-consolidation/spec.md#requirement-every-in-flight-approval-survives-the-migration-at-the-same-position
+ */
+ protected function execute(InputInterface $input, OutputInterface $output): int {
+ $dryRun = ((bool)$input->getOption('dry-run') === true);
+
+ try {
+ $result = $this->db->executeQuery(
+ 'SELECT * FROM `*PREFIX*openregister_approval_steps` WHERE `migrated_task_uuid` IS NOT NULL'
+ );
+ $steps = $result->fetchAll();
+ $result->closeCursor();
+ } catch (Throwable $absent) {
+ $output->writeln('The legacy approval tables are gone; there is nothing to roll back onto.');
+
+ return Command::FAILURE;
+ }
+
+ $written = 0;
+ $notCarriable = [];
+ foreach ($steps as $step) {
+ $written += $this->carryBack(step: $step, dryRun: $dryRun, output: $output, notCarriable: $notCarriable);
+ }
+
+ $mode = 'written back';
+ if ($dryRun === true) {
+ $mode = 'would be written back';
+ }
+
+ $output->writeln(sprintf('%d decision(s) %s onto legacy step rows.', $written, $mode));
+
+ if ($notCarriable !== []) {
+ $output->writeln('The legacy schema cannot hold the following facts; they stay ONLY on the task side:');
+ foreach ($notCarriable as $line) {
+ $output->writeln(' - ' . $line);
+ }
+ }
+
+ $output->writeln('The legacy tables were not dropped, and dropping them is not part of any rollback path.');
+
+ return Command::SUCCESS;
+ }//end execute()
+
+ /**
+ * Carry ONE step's task-side decision back, when there is one.
+ *
+ * @param array $step The legacy step row.
+ * @param bool $dryRun Whether to report without writing.
+ * @param OutputInterface $output Command output.
+ * @param array $notCarriable Collects the facts left behind.
+ *
+ * @return int One when a decision was carried back, zero otherwise.
+ */
+ private function carryBack(array $step, bool $dryRun, OutputInterface $output, array &$notCarriable): int {
+ $taskUuid = trim((string)$step['migrated_task_uuid']);
+ try {
+ $task = $this->tasks->findByUuid(uuid: $taskUuid);
+ } catch (Throwable $gone) {
+ $output->writeln(sprintf('Step %d: migrated task %s no longer exists; row left as it is.', (int)$step['id'], $taskUuid));
+
+ return 0;
+ }
+
+ if ($task->isInTerminalState() === false || (string)$task->getState() !== Task::STATE_COMPLETED) {
+ // No decision was taken on the task side; the step keeps
+ // whatever it already recorded.
+ return 0;
+ }
+
+ $status = 'approved';
+ if (TaskState::isRejectingOutcome(outcome: $task->getOutcome()) === true) {
+ $status = 'rejected';
+ }
+
+ if ((string)$step['status'] === $status && trim((string)($step['decided_by'] ?? '')) !== '') {
+ // Already decided identically before migration; nothing new to
+ // carry back.
+ return 0;
+ }
+
+ if ($dryRun === false) {
+ $this->writeDecision(step: $step, task: $task, status: $status);
+ }
+
+ foreach ($this->lostFacts(task: $task) as $lost) {
+ $notCarriable[] = sprintf('step %d (task %s): %s', (int)$step['id'], $taskUuid, $lost);
+ }
+
+ return 1;
+ }//end carryBack()
+
+ /**
+ * Write one decision onto its legacy step row.
+ *
+ * @param array $step The legacy step row.
+ * @param Task $task The decided task.
+ * @param string $status The legacy status to record.
+ *
+ * @return void
+ */
+ private function writeDecision(array $step, Task $task, string $status): void {
+ $update = $this->db->getQueryBuilder();
+ $update->update('openregister_approval_steps')
+ ->set('status', $update->createNamedParameter($status))
+ ->set('decided_by', $update->createNamedParameter((string)($task->getCompletedBy() ?? '')))
+ ->set('comment', $update->createNamedParameter((string)($task->getComment() ?? '')))
+ ->set('decided_at', $update->createNamedParameter($task->getCompletedAt()?->format('Y-m-d H:i:s')))
+ ->where($update->expr()->eq('id', $update->createNamedParameter((int)$step['id'])));
+ $update->executeStatement();
+ }//end writeDecision()
+
+ /**
+ * The facts about a decision the legacy step schema cannot express.
+ *
+ * @param Task $task The migrated, decided task.
+ *
+ * @return array One line per fact that stays behind.
+ */
+ private function lostFacts(Task $task): array {
+ $lost = ['the per-entry audit trail'];
+ if ((string)$task->getPerformerType() !== '' && (string)$task->getPerformerType() !== Task::PERFORMER_GROUP) {
+ $lost[] = sprintf("performer type '%s'", (string)$task->getPerformerType());
+ }
+
+ if (trim((string)$task->getOnBehalfOf()) !== '') {
+ $lost[] = sprintf("on-behalf-of identity '%s'", (string)$task->getOnBehalfOf());
+ }
+
+ if (trim((string)$task->getMandate()) !== '') {
+ $lost[] = sprintf("mandate '%s'", (string)$task->getMandate());
+ }
+
+ return $lost;
+ }//end lostFacts()
+}//end class
diff --git a/lib/Controller/ActivityLinksController.php b/lib/Controller/ActivityLinksController.php
index 74a0099be3..09419dc77a 100644
--- a/lib/Controller/ActivityLinksController.php
+++ b/lib/Controller/ActivityLinksController.php
@@ -248,8 +248,8 @@ private function nullableInt(string $name): ?int {
* returns for other reasons, which the caller could no longer tell apart.
*/
private function validateObject(string $register, string $schema, string $id): ?ObjectEntity {
- $this->objectService->setSchema($schema);
$this->objectService->setRegister($register);
+ $this->objectService->setSchema($schema);
$this->objectService->setObject($id);
return $this->objectService->getObject();
diff --git a/lib/Controller/AnalyticsLinksController.php b/lib/Controller/AnalyticsLinksController.php
index ec212a7427..a96572ed05 100644
--- a/lib/Controller/AnalyticsLinksController.php
+++ b/lib/Controller/AnalyticsLinksController.php
@@ -305,8 +305,8 @@ public function available(): JSONResponse {
* returns for other reasons, which the caller could no longer tell apart.
*/
private function validateObject(string $register, string $schema, string $id): ?ObjectEntity {
- $this->objectService->setSchema($schema);
$this->objectService->setRegister($register);
+ $this->objectService->setSchema($schema);
$this->objectService->setObject($id);
return $this->objectService->getObject();
diff --git a/lib/Controller/ApprovalController.php b/lib/Controller/ApprovalController.php
deleted file mode 100644
index 9f53fe7244..0000000000
--- a/lib/Controller/ApprovalController.php
+++ /dev/null
@@ -1,361 +0,0 @@
-
- * @copyright 2024 Conduction B.V.
- * @license EUPL-1.2 https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
- *
- * @version GIT:
- *
- * @link https://OpenRegister.app
- *
- * @spec openspec/specs/approval-workflow/spec.md
- * @spec openspec/specs/approval-workflow/spec.md
- * @spec openspec/specs/approval-workflow/spec.md
- * @spec openspec/specs/approval-workflow/spec.md
- */
-
-declare(strict_types=1);
-
-namespace OCA\OpenRegister\Controller;
-
-use Exception;
-use OCA\OpenRegister\Db\ApprovalChainMapper;
-use OCA\OpenRegister\Db\ApprovalStepMapper;
-use OCA\OpenRegister\Service\ApprovalService;
-use OCP\AppFramework\Controller;
-use OCP\AppFramework\Http\JSONResponse;
-use OCP\IGroupManager;
-use OCP\IRequest;
-use OCP\IUserSession;
-use Psr\Log\LoggerInterface;
-
-/**
- * Controller for approval chain CRUD and step approve/reject.
- *
- * @psalm-suppress UnusedClass
- *
- * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
- */
-class ApprovalController extends Controller {
- /**
- * Constructor for ApprovalController.
- *
- * @param string $appName App name
- * @param IRequest $request Request
- * @param ApprovalChainMapper $chainMapper Chain mapper
- * @param ApprovalStepMapper $stepMapper Step mapper
- * @param ApprovalService $approvalService Approval service
- * @param IUserSession $userSession User session
- * @param LoggerInterface $logger Logger
- * @param IGroupManager $groupManager Group manager for admin checks
- */
- public function __construct(
- string $appName,
- IRequest $request,
- private readonly ApprovalChainMapper $chainMapper,
- private readonly ApprovalStepMapper $stepMapper,
- private readonly ApprovalService $approvalService,
- private readonly IUserSession $userSession,
- private readonly LoggerInterface $logger,
- private readonly IGroupManager $groupManager,
- ) {
- parent::__construct(appName: $appName, request: $request);
- }//end __construct()
-
- /**
- * Determine whether the current user is a Nextcloud admin.
- *
- * @return bool True when the active session user belongs to the admin group.
- */
- private function isCurrentUserAdmin(): bool {
- $user = $this->userSession->getUser();
- if ($user === null) {
- return false;
- }
-
- return $this->groupManager->isAdmin($user->getUID());
- }//end isCurrentUserAdmin()
-
- /**
- * List all approval chains.
- *
- * @NoAdminRequired
- *
- * @return JSONResponse
- *
- * @spec openspec/specs/approval-workflow/spec.md
- */
- public function index(): JSONResponse {
- $chains = $this->chainMapper->findAll();
-
- return new JSONResponse(
- array_map(fn ($c) => $c->jsonSerialize(), $chains)
- );
- }//end index()
-
- /**
- * Get a single approval chain.
- *
- * @param int $id Chain ID
- *
- * @NoAdminRequired
- *
- * @return JSONResponse
- *
- * @spec openspec/specs/approval-workflow/spec.md
- */
- public function show(int $id): JSONResponse {
- try {
- $chain = $this->chainMapper->find($id);
-
- return new JSONResponse($chain->jsonSerialize());
- } catch (\OCP\AppFramework\Db\DoesNotExistException $e) {
- return new JSONResponse(['error' => 'Approval chain not found'], 404);
- }
- }//end show()
-
- /**
- * Create a new approval chain.
- *
- * @return JSONResponse
- *
- * @spec openspec/specs/approval-workflow/spec.md
- *
- * @NoAdminRequired
- */
- public function create(): JSONResponse {
- // SECURITY (M1): approval chain writes are admin-only.
- if ($this->isCurrentUserAdmin() === false) {
- return new JSONResponse(['error' => 'Admin privileges required'], 403);
- }
-
- $data = $this->request->getParams();
-
- try {
- $chain = $this->chainMapper->createFromArray($data);
-
- return new JSONResponse($chain->jsonSerialize(), 201);
- } catch (Exception $e) {
- return new JSONResponse(['error' => $e->getMessage()], 500);
- }
- }//end create()
-
- /**
- * Update an approval chain.
- *
- * @param int $id Chain ID
- *
- * @return JSONResponse
- *
- * @spec openspec/specs/approval-workflow/spec.md
- *
- * @NoAdminRequired
- */
- public function update(int $id): JSONResponse {
- // SECURITY (M1): approval chain writes are admin-only.
- if ($this->isCurrentUserAdmin() === false) {
- return new JSONResponse(['error' => 'Admin privileges required'], 403);
- }
-
- try {
- $data = $this->request->getParams();
- $chain = $this->chainMapper->updateFromArray($id, $data);
-
- return new JSONResponse($chain->jsonSerialize());
- } catch (\OCP\AppFramework\Db\DoesNotExistException $e) {
- return new JSONResponse(['error' => 'Approval chain not found'], 404);
- } catch (Exception $e) {
- return new JSONResponse(['error' => $e->getMessage()], 500);
- }
- }//end update()
-
- /**
- * Delete an approval chain.
- *
- * @param int $id Chain ID
- *
- * @return JSONResponse
- *
- * @spec openspec/specs/approval-workflow/spec.md
- *
- * @NoAdminRequired
- */
- public function destroy(int $id): JSONResponse {
- // SECURITY (M1): approval chain writes are admin-only.
- if ($this->isCurrentUserAdmin() === false) {
- return new JSONResponse(['error' => 'Admin privileges required'], 403);
- }
-
- try {
- $chain = $this->chainMapper->find($id);
- $this->chainMapper->delete($chain);
-
- return new JSONResponse($chain->jsonSerialize());
- } catch (\OCP\AppFramework\Db\DoesNotExistException $e) {
- return new JSONResponse(['error' => 'Approval chain not found'], 404);
- }
- }//end destroy()
-
- /**
- * List objects in an approval chain with their progress.
- *
- * @param int $id Chain ID
- *
- * @NoAdminRequired
- *
- * @return JSONResponse
- *
- * @spec openspec/specs/approval-workflow/spec.md
- */
- public function objects(int $id): JSONResponse {
- try {
- $this->chainMapper->find($id);
- } catch (\OCP\AppFramework\Db\DoesNotExistException $e) {
- return new JSONResponse(['error' => 'Approval chain not found'], 404);
- }
-
- $steps = $this->stepMapper->findByChain($id);
-
- // Group steps by object UUID.
- $objectProgress = [];
- foreach ($steps as $step) {
- $uuid = $step->getObjectUuid();
- if (isset($objectProgress[$uuid]) === false) {
- $objectProgress[$uuid] = [
- 'objectUuid' => $uuid,
- 'steps' => [],
- 'approved' => 0,
- 'total' => 0,
- ];
- }
-
- $objectProgress[$uuid]['steps'][] = $step->jsonSerialize();
- $objectProgress[$uuid]['total']++;
- if ($step->getStatus() === 'approved') {
- $objectProgress[$uuid]['approved']++;
- }
- }
-
- return new JSONResponse(array_values($objectProgress));
- }//end objects()
-
- /**
- * List approval steps with optional filters.
- *
- * @NoAdminRequired
- *
- * @return JSONResponse
- *
- * @spec openspec/specs/approval-workflow/spec.md
- * @spec openspec/specs/approval-workflow/spec.md
- */
- public function steps(): JSONResponse {
- $filters = [];
-
- $status = $this->request->getParam('status');
- if ($status !== null) {
- $filters['status'] = $status;
- }
-
- $role = $this->request->getParam('role');
- if ($role !== null) {
- $filters['role'] = $role;
- }
-
- $chainId = $this->request->getParam('chainId');
- if ($chainId !== null) {
- $filters['chainId'] = (int)$chainId;
- }
-
- $objectUuid = $this->request->getParam('objectUuid');
- if ($objectUuid !== null) {
- $filters['objectUuid'] = $objectUuid;
- }
-
- $steps = $this->stepMapper->findAllFiltered($filters);
-
- return new JSONResponse(
- array_map(fn ($step) => $step->jsonSerialize(), $steps)
- );
- }//end steps()
-
- /**
- * Approve a pending approval step.
- *
- * @param int $id Step ID
- *
- * @NoAdminRequired
- *
- * @return JSONResponse
- *
- * @spec openspec/specs/approval-workflow/spec.md
- */
- public function approve(int $id): JSONResponse {
- $user = $this->userSession->getUser();
- if ($user === null) {
- return new JSONResponse(['error' => 'Not authenticated'], 401);
- }
-
- $comment = (string)($this->request->getParam('comment', ''));
-
- try {
- $result = $this->approvalService->approveStep($id, $user->getUID(), $comment);
- $step = $result['step'];
-
- $response = $step->jsonSerialize();
- if ($result['nextStep'] !== null) {
- $response['nextStep'] = $result['nextStep']->jsonSerialize();
- }
-
- return new JSONResponse($response);
- } catch (Exception $e) {
- if (str_contains($e->getMessage(), 'not authorised') === true) {
- return new JSONResponse(['error' => $e->getMessage()], 403);
- }
-
- return new JSONResponse(['error' => $e->getMessage()], 400);
- }
- }//end approve()
-
- /**
- * Reject a pending approval step.
- *
- * @param int $id Step ID
- *
- * @NoAdminRequired
- *
- * @return JSONResponse
- *
- * @spec openspec/specs/approval-workflow/spec.md
- */
- public function reject(int $id): JSONResponse {
- $user = $this->userSession->getUser();
- if ($user === null) {
- return new JSONResponse(['error' => 'Not authenticated'], 401);
- }
-
- $comment = (string)($this->request->getParam('comment', ''));
-
- try {
- $result = $this->approvalService->rejectStep($id, $user->getUID(), $comment);
- $step = $result['step'];
-
- return new JSONResponse($step->jsonSerialize());
- } catch (Exception $e) {
- if (str_contains($e->getMessage(), 'not authorised') === true) {
- return new JSONResponse(['error' => $e->getMessage()], 403);
- }
-
- return new JSONResponse(['error' => $e->getMessage()], 400);
- }
- }//end reject()
-}//end class
diff --git a/lib/Controller/ArchivalController.php b/lib/Controller/ArchivalController.php
index 0f64b4c2f3..e771b4c529 100644
--- a/lib/Controller/ArchivalController.php
+++ b/lib/Controller/ArchivalController.php
@@ -184,7 +184,7 @@ public function getDestructionList(string $id): JSONResponse {
}
try {
- $object = $this->objectMapper->findByUuid($id);
+ $object = $this->objectMapper->find($id);
return new JSONResponse(
data: $object->jsonSerialize(),
statusCode: Http::STATUS_OK
@@ -221,7 +221,7 @@ public function approveDestructionList(string $id): JSONResponse {
$exclusionReasons = $params['exclusionReasons'] ?? [];
try {
- $object = $this->objectMapper->findByUuid($id);
+ $object = $this->objectMapper->find($id);
$destructionList = $object->getObject() ?? [];
// Check for dual-approval requirement based on schema config.
@@ -304,7 +304,7 @@ public function rejectDestructionList(string $id): JSONResponse {
}
try {
- $object = $this->objectMapper->findByUuid($id);
+ $object = $this->objectMapper->find($id);
$destructionList = $object->getObject() ?? [];
$result = $this->destructionService->rejectList($destructionList, $reason);
@@ -389,7 +389,7 @@ public function createLegalHold(): JSONResponse {
);
}
- $object = $this->objectMapper->findByUuid($objectId);
+ $object = $this->objectMapper->find($objectId);
$result = $this->legalHoldService->placeHold($object, $reason);
return new JSONResponse(
@@ -445,7 +445,7 @@ public function releaseLegalHold(string $id): JSONResponse {
}
try {
- $object = $this->objectMapper->findByUuid($id);
+ $object = $this->objectMapper->find($id);
$result = $this->legalHoldService->releaseHold($object, $reason);
return new JSONResponse(
diff --git a/lib/Controller/BookmarkLinksController.php b/lib/Controller/BookmarkLinksController.php
index 7a32b31501..0c1b5962f9 100644
--- a/lib/Controller/BookmarkLinksController.php
+++ b/lib/Controller/BookmarkLinksController.php
@@ -320,8 +320,8 @@ static function (string $tag): bool {
* returns for other reasons, which the caller could no longer tell apart.
*/
private function validateObject(string $register, string $schema, string $id): ?ObjectEntity {
- $this->objectService->setSchema($schema);
$this->objectService->setRegister($register);
+ $this->objectService->setSchema($schema);
$this->objectService->setObject($id);
return $this->objectService->getObject();
diff --git a/lib/Controller/CalendarEventsController.php b/lib/Controller/CalendarEventsController.php
index a7c009ff52..cd424290e5 100644
--- a/lib/Controller/CalendarEventsController.php
+++ b/lib/Controller/CalendarEventsController.php
@@ -411,8 +411,8 @@ private function validateObject(
string $schema,
string $id,
): ?\OCA\OpenRegister\Db\ObjectEntity {
- $this->objectService->setSchema($schema);
$this->objectService->setRegister($register);
+ $this->objectService->setSchema($schema);
$this->objectService->setObject($id);
return $this->objectService->getObject();
diff --git a/lib/Controller/CaseController.php b/lib/Controller/CaseController.php
new file mode 100644
index 0000000000..05428832f9
--- /dev/null
+++ b/lib/Controller/CaseController.php
@@ -0,0 +1,425 @@
+
+ * SPDX-License-Identifier: EUPL-1.2
+ *
+ * @category Controller
+ * @package OCA\OpenRegister\Controller
+ *
+ * @author Conduction Development Team
+ * @copyright 2026 Conduction B.V.
+ * @license EUPL-1.2 https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
+ *
+ * @link https://OpenRegister.app
+ *
+ * @spec openspec/changes/flow-cmmn-case-semantics/specs/flow-cases/spec.md#requirement-the-case-is-the-openregister-object
+ */
+
+declare(strict_types=1);
+
+namespace OCA\OpenRegister\Controller;
+
+use OCA\OpenRegister\Exception\CaseAccessDeniedException;
+use OCA\OpenRegister\Exception\CaseCascadeBoundException;
+use OCA\OpenRegister\Exception\CaseTransitionException;
+use OCA\OpenRegister\Exception\CaseValidationException;
+use OCA\OpenRegister\Service\Case\CasePlanAuthorizationService;
+use OCA\OpenRegister\Service\Case\CasePlanService;
+use OCA\OpenRegister\Service\Case\ZaaktypeCaseSkeletonMapper;
+use OCP\AppFramework\Controller;
+use OCP\AppFramework\Db\DoesNotExistException;
+use OCP\AppFramework\Http;
+use OCP\AppFramework\Http\Attribute\NoAdminRequired;
+use OCP\AppFramework\Http\Attribute\NoCSRFRequired;
+use OCP\AppFramework\Http\JSONResponse;
+use OCP\IRequest;
+use OCP\IUserSession;
+use Psr\Log\LoggerInterface;
+use Throwable;
+
+/**
+ * REST surface for case plans.
+ *
+ * @SuppressWarnings(PHPMD.TooManyPublicMethods) One route method per verb
+ * the spec names plus the reads. Folding verbs into a mode parameter is how
+ * per-verb authorization rules get lost.
+ * @SuppressWarnings(PHPMD.CouplingBetweenObjects) The controller mediates
+ * between HTTP, the service, the mapper and four exception shapes; that is
+ * the whole of its job.
+ *
+ * @spec openspec/changes/flow-cmmn-case-semantics/specs/flow-cases/spec.md#requirement-the-case-is-the-openregister-object
+ */
+class CaseController extends Controller {
+
+ /**
+ * Constructor.
+ *
+ * @param string $appName The app id.
+ * @param IRequest $request The request.
+ * @param CasePlanService $plans The authorized case layer.
+ * @param ZaaktypeCaseSkeletonMapper $zaaktypes The pure zaaktype mapping.
+ * @param CasePlanAuthorizationService $authorization Identity checks for the anchorless route.
+ * @param IUserSession $userSession Names the acting identity.
+ * @param LoggerInterface|null $logger Where an unexpected failure's detail goes, INSTEAD of the response.
+ */
+ public function __construct(
+ string $appName,
+ IRequest $request,
+ private readonly CasePlanService $plans,
+ private readonly ZaaktypeCaseSkeletonMapper $zaaktypes,
+ private readonly CasePlanAuthorizationService $authorization,
+ private readonly IUserSession $userSession,
+ private readonly ?LoggerInterface $logger = null,
+ ) {
+ parent::__construct(appName: $appName, request: $request);
+
+ }//end __construct()
+
+ /**
+ * Items across cases by type and state: "which cases are stuck where".
+ *
+ * @param string|null $type Plan-item type filter.
+ * @param string|null $state State filter.
+ * @param int $limit Page size.
+ * @param int $offset Page offset.
+ *
+ * @return JSONResponse results, total, limit, offset.
+ *
+ * @spec openspec/changes/flow-cmmn-case-semantics/specs/flow-cases/spec.md#requirement-plan-item-state-is-stored-as-rows-never-as-an-encoded-blob
+ */
+ #[NoAdminRequired]
+ #[NoCSRFRequired]
+ public function items(?string $type = null, ?string $state = null, int $limit = 25, int $offset = 0): JSONResponse {
+ return $this->guard(action: fn (): array => $this->plans->findStuck(type: $type, state: $state, limit: $limit, offset: $offset, uid: $this->uid()));
+ }//end items()
+
+ /**
+ * A zaaktype document becomes a draft skeleton plus a report. Pure; writes nothing.
+ *
+ * @param array|null $zaaktype The zaaktype document.
+ *
+ * @return JSONResponse draft, definition, report.
+ *
+ * @spec openspec/changes/flow-cmmn-case-semantics/specs/flow-cases/spec.md#requirement-a-zaaktype-maps-to-a-case-skeleton-and-reports-what-it-could-not-map
+ */
+ #[NoAdminRequired]
+ #[NoCSRFRequired]
+ public function skeletonFromZaaktype(?array $zaaktype = null): JSONResponse {
+ return $this->guard(
+ action: function () use ($zaaktype): array {
+ $this->authorization->assertIdentified(uid: $this->uid(), verb: 'skeleton-from-zaaktype');
+ if (is_array($zaaktype) === false || $zaaktype === []) {
+ throw new CaseValidationException(message: 'A `zaaktype` document is required.');
+ }
+
+ return $this->zaaktypes->map(zaaktype: $zaaktype);
+ }
+ );
+ }//end skeletonFromZaaktype()
+
+ /**
+ * The plan of one object.
+ *
+ * @param string $objectUuid The anchoring object.
+ *
+ * @return JSONResponse The plan; 404 when absent OR invisible.
+ *
+ * @spec openspec/changes/flow-cmmn-case-semantics/specs/flow-cases/spec.md#requirement-the-case-is-the-openregister-object
+ */
+ #[NoAdminRequired]
+ #[NoCSRFRequired]
+ public function show(string $objectUuid): JSONResponse {
+ return $this->guard(action: fn (): array => $this->plans->getPlan(objectUuid: $objectUuid, uid: $this->uid()));
+ }//end show()
+
+ /**
+ * Create a plan on an object from a definition.
+ *
+ * @param string $objectUuid The anchoring object.
+ * @param int|null $register Its register id.
+ * @param int|null $schema Its schema id.
+ * @param array|null $definition The definition (`settings`, `items`).
+ * @param string|null $flowUuid Definition provenance, when any.
+ * @param int|null $flowVersion Definition provenance, when any.
+ *
+ * @return JSONResponse The plan, 201.
+ *
+ * @spec openspec/changes/flow-cmmn-case-semantics/specs/flow-cases/spec.md#requirement-sentries-are-entry-and-exit-criteria-over-existing-engine-primitives
+ */
+ #[NoAdminRequired]
+ #[NoCSRFRequired]
+ public function create(
+ string $objectUuid,
+ ?int $register = null,
+ ?int $schema = null,
+ ?array $definition = null,
+ ?string $flowUuid = null,
+ ?int $flowVersion = null,
+ ): JSONResponse {
+ return $this->guard(
+ action: fn (): array => $this->plans->createPlan(
+ objectUuid: $objectUuid,
+ registerId: $register,
+ schemaId: $schema,
+ definition: ($definition ?? []),
+ uid: $this->uid(),
+ flowUuid: $flowUuid,
+ flowVersion: $flowVersion
+ ),
+ status: Http::STATUS_CREATED
+ );
+ }//end create()
+
+ /**
+ * Re-evaluate a plan.
+ *
+ * @param string $objectUuid The anchoring object.
+ *
+ * @return JSONResponse passes, transitions.
+ *
+ * @spec openspec/changes/flow-cmmn-case-semantics/specs/flow-cases/spec.md#requirement-stages-nest-and-complete-by-a-written-rule
+ */
+ #[NoAdminRequired]
+ #[NoCSRFRequired]
+ public function evaluate(string $objectUuid): JSONResponse {
+ return $this->guard(action: fn (): array => $this->plans->evaluate(objectUuid: $objectUuid, uid: $this->uid()));
+ }//end evaluate()
+
+ /**
+ * Which discretionary items may be enabled now.
+ *
+ * @param string $objectUuid The anchoring object.
+ *
+ * @return JSONResponse results.
+ *
+ * @spec openspec/changes/flow-cmmn-case-semantics/specs/flow-cases/spec.md#requirement-a-caseworker-may-attach-work-no-author-drew
+ */
+ #[NoAdminRequired]
+ #[NoCSRFRequired]
+ public function enableable(string $objectUuid): JSONResponse {
+ return $this->guard(action: fn (): array => ['results' => $this->plans->enableableItems(objectUuid: $objectUuid, uid: $this->uid())]);
+ }//end enableable()
+
+ /**
+ * Attach an ad-hoc item.
+ *
+ * @param string $objectUuid The anchoring object.
+ * @param string|null $key The item key.
+ * @param string|null $type The plan-item type.
+ * @param string|null $name Human name.
+ * @param string|null $description Description.
+ * @param string|null $parent Parent stage uuid or key, or null for the root.
+ * @param array|null $entryCriteria Entry sentries.
+ * @param array|null $exitCriteria Exit sentries.
+ * @param array|null $candidateUsers Candidate uids.
+ * @param array|null $candidateGroups Candidate group ids.
+ * @param string|null $candidateRole Candidate role.
+ * @param string|null $dueAt Advisory deadline.
+ * @param string|null $expiresAt Enforcing deadline.
+ * @param bool $required Whether the parent waits for it.
+ *
+ * @return JSONResponse The item, 201.
+ *
+ * @SuppressWarnings(PHPMD.ExcessiveParameterList) One parameter per
+ * field the route accepts; Nextcloud binds them by name from the body.
+ * @SuppressWarnings(PHPMD.BooleanArgumentFlag) `required` is a stored
+ * boolean field of the item, bound from the body like the others, not a
+ * behaviour switch of this method.
+ *
+ * @spec openspec/changes/flow-cmmn-case-semantics/specs/flow-cases/spec.md#requirement-a-caseworker-may-attach-work-no-author-drew
+ */
+ #[NoAdminRequired]
+ #[NoCSRFRequired]
+ public function attach(
+ string $objectUuid,
+ ?string $key = null,
+ ?string $type = null,
+ ?string $name = null,
+ ?string $description = null,
+ ?string $parent = null,
+ ?array $entryCriteria = null,
+ ?array $exitCriteria = null,
+ ?array $candidateUsers = null,
+ ?array $candidateGroups = null,
+ ?string $candidateRole = null,
+ ?string $dueAt = null,
+ ?string $expiresAt = null,
+ bool $required = true,
+ ): JSONResponse {
+ $data = array_filter(
+ [
+ 'key' => $key,
+ 'type' => $type,
+ 'name' => $name,
+ 'description' => $description,
+ 'parent' => $parent,
+ 'entryCriteria' => $entryCriteria,
+ 'exitCriteria' => $exitCriteria,
+ 'candidateUsers' => $candidateUsers,
+ 'candidateGroups' => $candidateGroups,
+ 'candidateRole' => $candidateRole,
+ 'dueAt' => $dueAt,
+ 'expiresAt' => $expiresAt,
+ ],
+ static fn (mixed $value): bool => $value !== null
+ );
+ $data['required'] = $required;
+ // An ad-hoc item may not declare its own authorization; the body key,
+ // if sent, is refused inside the service, so it is forwarded as-is.
+ $body = $this->request->getParams();
+ if (array_key_exists('authorization', $body) === true) {
+ $data['authorization'] = $body['authorization'];
+ }
+
+ return $this->guard(
+ action: fn (): array => $this->plans->attachAdHoc(objectUuid: $objectUuid, data: $data, uid: $this->uid())->jsonSerialize(),
+ status: Http::STATUS_CREATED
+ );
+ }//end attach()
+
+ /**
+ * Finish the case with a result.
+ *
+ * @param string $objectUuid The anchoring object.
+ * @param string|null $result The result.
+ *
+ * @return JSONResponse The plan plus `result`.
+ *
+ * @spec openspec/changes/flow-cmmn-case-semantics/specs/flow-cases/spec.md#requirement-a-zaaktype-maps-to-a-case-skeleton-and-reports-what-it-could-not-map
+ */
+ #[NoAdminRequired]
+ #[NoCSRFRequired]
+ public function complete(string $objectUuid, ?string $result = null): JSONResponse {
+ return $this->guard(
+ action: function () use ($objectUuid, $result): array {
+ if ($result === null || trim($result) === '') {
+ throw new CaseValidationException(message: 'A `result` is required to finish a case.');
+ }
+
+ return $this->plans->completeCase(objectUuid: $objectUuid, result: $result, uid: $this->uid());
+ }
+ );
+ }//end complete()
+
+ /**
+ * Delete a plan's items. The audit and the mirrored business state stay.
+ *
+ * @param string $objectUuid The anchoring object.
+ *
+ * @return JSONResponse deleted.
+ *
+ * @spec openspec/changes/flow-cmmn-case-semantics/specs/flow-cases/spec.md#requirement-business-state-is-written-through-to-the-register-never-owned-by-the-engine
+ */
+ #[NoAdminRequired]
+ #[NoCSRFRequired]
+ public function destroy(string $objectUuid): JSONResponse {
+ return $this->guard(action: fn (): array => ['deleted' => $this->plans->deletePlan(objectUuid: $objectUuid, uid: $this->uid())]);
+ }//end destroy()
+
+ /**
+ * Transition one item by hand.
+ *
+ * @param string $uuid The item.
+ * @param string|null $to The target state.
+ * @param string|null $reason Free text.
+ *
+ * @return JSONResponse The item.
+ *
+ * @spec openspec/changes/flow-cmmn-case-semantics/specs/flow-cases/spec.md#requirement-one-lifecycle-table-governs-every-plan-item
+ */
+ #[NoAdminRequired]
+ #[NoCSRFRequired]
+ public function transition(string $uuid, ?string $to = null, ?string $reason = null): JSONResponse {
+ return $this->guard(
+ action: function () use ($uuid, $to, $reason): array {
+ if ($to === null || trim($to) === '') {
+ throw new CaseValidationException(message: 'A target state `to` is required.');
+ }
+
+ return $this->plans->transition(itemUuid: $uuid, to: $to, uid: $this->uid(), reason: $reason)->jsonSerialize();
+ }
+ );
+ }//end transition()
+
+ /**
+ * Enable a discretionary item.
+ *
+ * @param string $uuid The item.
+ *
+ * @return JSONResponse The item.
+ *
+ * @spec openspec/changes/flow-cmmn-case-semantics/specs/flow-cases/spec.md#requirement-a-caseworker-may-attach-work-no-author-drew
+ */
+ #[NoAdminRequired]
+ #[NoCSRFRequired]
+ public function enable(string $uuid): JSONResponse {
+ return $this->guard(action: fn (): array => $this->plans->enableDiscretionary(itemUuid: $uuid, uid: $this->uid())->jsonSerialize());
+ }//end enable()
+
+ /**
+ * The acting identity, or null without a session.
+ *
+ * @return string|null The uid.
+ *
+ * @spec openspec/changes/flow-cmmn-case-semantics/specs/flow-cases/spec.md#requirement-a-caseworker-may-attach-work-no-author-drew
+ */
+ private function uid(): ?string {
+ return $this->userSession->getUser()?->getUID();
+ }//end uid()
+
+ /**
+ * Translate the service's exceptions to HTTP, once.
+ *
+ * Absent and invisible are the same 404; a denial is 403 only when the
+ * plan itself was visible (the service throws DoesNotExist otherwise);
+ * a refused value is 400; an illegal transition or a lost race is 409;
+ * the cascade bound is 422; anything else is 500 with the detail logged
+ * and NOT echoed.
+ *
+ * @param callable(): array $action The work.
+ * @param int $status The success status.
+ *
+ * @return JSONResponse The response.
+ *
+ * @spec openspec/changes/flow-cmmn-case-semantics/specs/flow-cases/spec.md#requirement-a-caseworker-may-attach-work-no-author-drew
+ */
+ private function guard(callable $action, int $status = Http::STATUS_OK): JSONResponse {
+ try {
+ return new JSONResponse($action(), $status);
+ } catch (DoesNotExistException) {
+ return new JSONResponse(['error' => 'Not found'], Http::STATUS_NOT_FOUND);
+ } catch (CaseAccessDeniedException $denied) {
+ return new JSONResponse(['error' => $denied->getMessage()], Http::STATUS_FORBIDDEN);
+ } catch (CaseValidationException $refused) {
+ return new JSONResponse(['error' => $refused->getMessage()], Http::STATUS_BAD_REQUEST);
+ } catch (CaseTransitionException $conflict) {
+ return new JSONResponse(['error' => $conflict->getMessage()], Http::STATUS_CONFLICT);
+ } catch (CaseCascadeBoundException $bound) {
+ return new JSONResponse(['error' => $bound->getMessage()], Http::STATUS_UNPROCESSABLE_ENTITY);
+ } catch (Throwable $failure) {
+ $this->logger?->error('[CaseController] ' . $failure->getMessage(), ['exception' => $failure]);
+
+ return new JSONResponse(['error' => 'Internal error'], Http::STATUS_INTERNAL_SERVER_ERROR);
+ }
+ }//end guard()
+}//end class
diff --git a/lib/Controller/CollectiveLinksController.php b/lib/Controller/CollectiveLinksController.php
index 0e34f2feaf..c6ecf87b8f 100644
--- a/lib/Controller/CollectiveLinksController.php
+++ b/lib/Controller/CollectiveLinksController.php
@@ -327,8 +327,8 @@ public function collectives(): JSONResponse {
* returns for other reasons, which the caller could no longer tell apart.
*/
private function validateObject(string $register, string $schema, string $id): ?ObjectEntity {
- $this->objectService->setSchema($schema);
$this->objectService->setRegister($register);
+ $this->objectService->setSchema($schema);
$this->objectService->setObject($id);
return $this->objectService->getObject();
diff --git a/lib/Controller/ContactsController.php b/lib/Controller/ContactsController.php
index 661921fa43..8663cb702f 100644
--- a/lib/Controller/ContactsController.php
+++ b/lib/Controller/ContactsController.php
@@ -462,8 +462,8 @@ private function validateObject(
string $schema,
string $id,
): ?\OCA\OpenRegister\Db\ObjectEntity {
- $this->objectService->setSchema($schema);
$this->objectService->setRegister($register);
+ $this->objectService->setSchema($schema);
$this->objectService->setObject($id);
return $this->objectService->getObject();
diff --git a/lib/Controller/CospendLinksController.php b/lib/Controller/CospendLinksController.php
index aac3bd509a..176c9dd2a7 100644
--- a/lib/Controller/CospendLinksController.php
+++ b/lib/Controller/CospendLinksController.php
@@ -329,8 +329,8 @@ public function available(): JSONResponse {
* returns for other reasons, which the caller could no longer tell apart.
*/
private function validateObject(string $register, string $schema, string $id): ?ObjectEntity {
- $this->objectService->setSchema($schema);
$this->objectService->setRegister($register);
+ $this->objectService->setSchema($schema);
$this->objectService->setObject($id);
return $this->objectService->getObject();
diff --git a/lib/Controller/DashboardController.php b/lib/Controller/DashboardController.php
index cdca0b78cc..a8244db3b9 100644
--- a/lib/Controller/DashboardController.php
+++ b/lib/Controller/DashboardController.php
@@ -173,6 +173,32 @@ public function page(): TemplateResponse {
}//end try
}//end page()
+ /**
+ * Serve the SPA for deep links (Vue history mode). Delegates to {@see page()}.
+ *
+ * THIS IS THE FIX FOR #133. This app registered exactly one frontend route —
+ * `dashboard#page` at `/` — and nothing that served the SPA shell for a deep
+ * sub-path like /registers or /schemas. A bookmark or full-page load to one
+ * of those therefore never reached the SPA, the router resolved the base
+ * path instead, and the grouped index pages rendered empty (no Add button,
+ * no list). The app was moved back to hash routing to work around it; with
+ * this route the workaround is no longer needed.
+ *
+ * ⚠️ Probing an enumerated path does NOT prove a catch-all exists — probe a
+ * nonsense one. /apps/openregister/zzz-nonsense returned 404 before this and
+ * 401 after.
+ *
+ * @NoAdminRequired
+ * @NoCSRFRequired
+ *
+ * @return TemplateResponse
+ *
+ * @spec exclude Vue history-mode fallback — delegates to page(); pure framework plumbing, no domain logic.
+ */
+ public function catchAll(): TemplateResponse {
+ return $this->page();
+ }//end catchAll()
+
/**
* Retrieves dashboard data including registers with their schemas
*
diff --git a/lib/Controller/DeckController.php b/lib/Controller/DeckController.php
index 76bf8ebc57..63de86f097 100644
--- a/lib/Controller/DeckController.php
+++ b/lib/Controller/DeckController.php
@@ -219,8 +219,8 @@ private function validateObject(
string $schema,
string $id,
): ?\OCA\OpenRegister\Db\ObjectEntity {
- $this->objectService->setSchema($schema);
$this->objectService->setRegister($register);
+ $this->objectService->setSchema($schema);
$this->objectService->setObject($id);
return $this->objectService->getObject();
diff --git a/lib/Controller/DeckLinksController.php b/lib/Controller/DeckLinksController.php
index 128fe8044d..dd29d55029 100644
--- a/lib/Controller/DeckLinksController.php
+++ b/lib/Controller/DeckLinksController.php
@@ -407,8 +407,8 @@ public function setDefault(string $schema): JSONResponse {
* returns for other reasons, which the caller could no longer tell apart.
*/
private function validateObject(string $register, string $schema, string $id): ?ObjectEntity {
- $this->objectService->setSchema($schema);
$this->objectService->setRegister($register);
+ $this->objectService->setSchema($schema);
$this->objectService->setObject($id);
return $this->objectService->getObject();
diff --git a/lib/Controller/DsarCaseController.php b/lib/Controller/DsarCaseController.php
index 8594d9b658..dcc1b39a5e 100644
--- a/lib/Controller/DsarCaseController.php
+++ b/lib/Controller/DsarCaseController.php
@@ -117,8 +117,17 @@ public function create(): JSONResponse {
}
$body = (array)$this->request->getParams();
- // Strip framework-injected keys so only the case payload is saved.
- unset($body['_route']);
+ // Strip framework-injected keys so only the case payload is saved, and
+ // the caller's IDENTITY with them. `saveObject()` resolves its target
+ // from the payload (`@self.id` first, then `id`) and the write is
+ // PUT-semantic, so a create carrying either would overwrite an existing
+ // case and null every field it omitted. This endpoint creates.
+ $self = (array)($body['@self'] ?? []);
+ unset($self['id'], $self['uuid']);
+ unset($body['_route'], $body['id'], $body['uuid'], $body['@self']);
+ if ($self !== []) {
+ $body['@self'] = $self;
+ }
try {
$saved = $this->objectService->saveObject(
diff --git a/lib/Controller/EmailLinksController.php b/lib/Controller/EmailLinksController.php
index 58de7edd10..f803490dcc 100644
--- a/lib/Controller/EmailLinksController.php
+++ b/lib/Controller/EmailLinksController.php
@@ -322,8 +322,8 @@ public function messages(string $accountId): JSONResponse {
* returns for other reasons, which the caller could no longer tell apart.
*/
private function validateObject(string $register, string $schema, string $id): ?ObjectEntity {
- $this->objectService->setSchema($schema);
$this->objectService->setRegister($register);
+ $this->objectService->setSchema($schema);
$this->objectService->setObject($id);
return $this->objectService->getObject();
diff --git a/lib/Controller/EmailsController.php b/lib/Controller/EmailsController.php
index a13bc4459c..bef379557b 100644
--- a/lib/Controller/EmailsController.php
+++ b/lib/Controller/EmailsController.php
@@ -321,8 +321,8 @@ private function validateObject(
string $schema,
string $id,
): ?\OCA\OpenRegister\Db\ObjectEntity {
- $this->objectService->setSchema($schema);
$this->objectService->setRegister($register);
+ $this->objectService->setSchema($schema);
$this->objectService->setObject($id);
return $this->objectService->getObject();
diff --git a/lib/Controller/FederationController.php b/lib/Controller/FederationController.php
index 82ac171210..5d84176f4d 100644
--- a/lib/Controller/FederationController.php
+++ b/lib/Controller/FederationController.php
@@ -319,6 +319,8 @@ public function object(string $shareToken, string $id): JSONResponse {
* @param string $shareToken The scoped bearer share token.
*
* @return JSONResponse The created object, or an error.
+ *
+ * @spec openspec/changes/federation-scope-enforcement/specs/federation-scope-enforcement/spec.md
*/
#[PublicPage]
#[NoCSRFRequired]
@@ -332,9 +334,37 @@ public function createObject(string $shareToken): JSONResponse {
$data = (array)$this->request->getParams();
unset($data['shareToken'], $data['_route']);
+
+ // 🔴 STRIP THE CALLER'S IDENTITY. This endpoint CREATES.
+ //
+ // `saveObject()` resolves its target from the payload:
+ // `extractUuidAndNormalizeObject()` reads `@self.id` first, then `id`,
+ // and treats a match as the uuid to UPDATE — PUT-semantically, so every
+ // field the payload omits is NULLED.
+ //
+ // This path is `#[PublicPage]` and runs `_rbac: false`, so nothing
+ // downstream would have refused it. A share grants the holder the right
+ // to ADD objects; without this it also granted the right to overwrite
+ // every existing object in the shared register/schema.
+ //
+ // The organisation pin below was already guarding the sibling half of
+ // this — "a federated writer can never plant an object into another
+ // organisation" — but `+` preserves the LEFT operand's keys, so a
+ // caller-supplied `@self: {id: …}` survived the merge untouched.
+ unset($data['id'], $data['uuid']);
+ $self = (array)($data['@self'] ?? []);
+ unset($self['id'], $self['uuid']);
+
// Pin the object to the sharing organisation — a federated writer can
// never plant an object into another organisation.
- $data['@self'] = (($data['@self'] ?? []) + ['organisation' => $share->getOrganisation()]);
+ //
+ // ASSIGNED, not merged. This was `$self + ['organisation' => …]`, and
+ // `+` keeps the LEFT operand's keys: a caller who supplied
+ // `@self: {organisation: 'somebody-else'}` kept it, so the pin this
+ // comment describes did not hold. The same `+` is what let a supplied
+ // `@self.id` through. A pin has to overwrite, or it is a default.
+ $self['organisation'] = $share->getOrganisation();
+ $data['@self'] = $self;
try {
$saved = $this->objectService->saveObject(
diff --git a/lib/Controller/FlowController.php b/lib/Controller/FlowController.php
index b63836d845..4c8a89f5dd 100644
--- a/lib/Controller/FlowController.php
+++ b/lib/Controller/FlowController.php
@@ -41,6 +41,7 @@
use OCA\OpenRegister\Db\FlowStateMapper;
use OCA\OpenRegister\Service\Flow\EventCatalogService;
use OCA\OpenRegister\Service\Flow\FlowAccess;
+use OCA\OpenRegister\Service\Flow\FlowAdoptionRefused;
use OCA\OpenRegister\Service\Flow\FlowDeadEnd;
use OCA\OpenRegister\Service\Flow\FlowLifecycleRefused;
use OCA\OpenRegister\Service\Flow\FlowNodePreflight;
@@ -92,6 +93,19 @@
*
* @SuppressWarnings(PHPMD.ExcessiveClassComplexity)
*
+ * Length (1,012 lines against 1,000) and method count (26 against 25) tripped
+ * together when `adopt()` was added — the fourth and fifth instances of the
+ * same trade. Adoption is one more verb on the same `/api/flows/{id}` resource
+ * the other lifecycle verbs (publish, draft, deprecate) live on; a controller
+ * of its own would be the two-controllers-behind-one-prefix split every
+ * suppression above declines, this time for a single method. The lines are
+ * mostly documentation, and trimming the explanations to duck a line counter
+ * is the corrosive direction. Revisit alongside the complexity note above if a
+ * genuinely separable second concern appears.
+ *
+ * @SuppressWarnings(PHPMD.ExcessiveClassLength)
+ * @SuppressWarnings(PHPMD.TooManyMethods)
+ *
* @spec openspec/changes/flow-engine-unification/specs/flow-storage/spec.md
*/
class FlowController extends Controller {
@@ -1027,6 +1041,64 @@ public function deprecate(string $id): JSONResponse {
return new JSONResponse($version->jsonSerialize());
}//end deprecate()
+ /**
+ * Adopt a flow: the CALLING user becomes its owner.
+ *
+ * The missing half of the shipped-flow lifecycle. An imported flow arrives
+ * `enabled=false, owner=null` and `Flow::canDispatch()` fails closed on
+ * the missing owner — correct — but no endpoint could supply one: `owner`
+ * is deliberately not an editable field, so "until somebody adopts it" had
+ * no mechanism and the only route on a live instance was raw SQL.
+ *
+ * The body is IGNORED. The new owner is the session's user, never a uid a
+ * request names — an endpoint that accepted one would let any caller with
+ * `flow.update` volunteer a colleague's identity for unattended execution.
+ * Enabling stays separate: adoption answers "whose flow", the `enabled`
+ * flag answers "may it run", and the flow becomes dispatchable only when
+ * both are true.
+ *
+ * @param string $id The flow uuid.
+ *
+ * @return JSONResponse The adopted flow, 401, 404, or 409 when it already
+ * belongs to someone else.
+ *
+ * @NoAdminRequired
+ *
+ * @no-admin-idor-exempt Guarded downstream: `FlowService::find()` applies
+ * the organisation scope (a foreign flow answers the same 404 as a missing
+ * one), and `adopt()` writes only the CALLER's uid — there is no
+ * caller-chosen object state to abuse.
+ *
+ * @spec openspec/changes/flow-adoption/specs/flow-storage/spec.md
+ */
+ #[NoAdminRequired]
+ public function adopt(string $id): JSONResponse {
+ $denied = $this->denyUnless(action: 'flow.update');
+ if ($denied !== null) {
+ return $denied;
+ }
+
+ try {
+ $flow = $this->flows->find(uuid: $id);
+ } catch (DoesNotExistException $e) {
+ return new JSONResponse(['error' => 'No such flow'], Http::STATUS_NOT_FOUND);
+ }
+
+ try {
+ $adopted = $this->flows->adopt(flow: $flow);
+ } catch (FlowAdoptionRefused $e) {
+ return new JSONResponse(
+ [
+ 'error' => $e->getMessage(),
+ 'reason' => $e->getReason(),
+ ],
+ Http::STATUS_CONFLICT
+ );
+ }
+
+ return new JSONResponse($adopted->jsonSerialize());
+ }//end adopt()
+
/**
* The flow fields carried on a create or update request.
*
diff --git a/lib/Controller/FlowLinksController.php b/lib/Controller/FlowLinksController.php
index e71f3db46d..b5450f5283 100644
--- a/lib/Controller/FlowLinksController.php
+++ b/lib/Controller/FlowLinksController.php
@@ -261,8 +261,8 @@ public function available(): JSONResponse {
* returns for other reasons, which the caller could no longer tell apart.
*/
private function validateObject(string $register, string $schema, string $id): ?ObjectEntity {
- $this->objectService->setSchema($schema);
$this->objectService->setRegister($register);
+ $this->objectService->setSchema($schema);
$this->objectService->setObject($id);
return $this->objectService->getObject();
diff --git a/lib/Controller/FlowRunController.php b/lib/Controller/FlowRunController.php
index e6902d8118..acaea69b1d 100644
--- a/lib/Controller/FlowRunController.php
+++ b/lib/Controller/FlowRunController.php
@@ -35,8 +35,9 @@
use OCA\OpenRegister\Service\Flow\FlowDeadEnd;
use OCA\OpenRegister\Service\Flow\FlowLifecycleRefused;
use OCA\OpenRegister\Service\Flow\FlowLocator;
-use OCA\OpenRegister\Service\Flow\FlowRunAssignee;
+use OCA\OpenRegister\Exception\FlowSignalRefused;
use OCA\OpenRegister\Service\Flow\FlowRunService;
+use OCA\OpenRegister\Service\Flow\FlowRunSignalService;
use OCA\OpenRegister\Service\Flow\FlowService;
use OCA\OpenRegister\Service\OrganisationService;
use OCP\AppFramework\Controller;
@@ -97,6 +98,14 @@ class FlowRunController extends Controller {
* caller; absent, the endpoint
* reports the surface unavailable
* rather than an empty run.
+ * @param FlowRunSignalService|null $signalService The guarded signal seam the
+ * resume endpoints delegate to.
+ * Nullable and appended so no
+ * construction site shifts;
+ * absent, one is built on
+ * demand from this
+ * controller's own
+ * collaborators.
*/
public function __construct(
string $appName,
@@ -112,6 +121,7 @@ public function __construct(
// inserted anywhere else shifts every positional caller, and the
// resulting TypeError names the argument AFTER the one that moved.
private readonly ?AuditFlowAttribution $auditTrails = null,
+ private readonly ?FlowRunSignalService $signalService = null,
) {
parent::__construct(appName: $appName, request: $request);
@@ -213,26 +223,142 @@ public function index(): JSONResponse {
* `shared-credentials-and-flows`. Until that landed `index()` was unscoped and
* returned every run on the instance to any authenticated user.
*
+ * An optional `subject` (a subject object uuid) narrows the list to the
+ * runs anchored to that one object: a case detail page's view of the
+ * engine. It narrows INSIDE the organisation scope and can never widen it;
+ * the mapper applies both predicates, and the total counts the filtered
+ * set. Without `subject` the read is bit-identical to what it was.
+ *
* @return JSONResponse `{results, total, limit}` — the live runs.
*
* @NoAdminRequired
* @NoCSRFRequired
*
* @spec openspec/changes/or-flow-active-runs/specs/flow-active-runs/spec.md
+ * @spec openspec/changes/flow-runs-subject-scope/specs/flow-runs-subject-scope/spec.md
*/
#[NoAdminRequired]
#[NoCSRFRequired]
public function active(): JSONResponse {
- $limit = min(50, max(1, (int)$this->request->getParam('limit', 10)));
+ $limit = $this->pageLimit();
+ $subject = $this->subjectFilter();
+ $organisation = $this->activeOrganisation();
+
+ if ($organisation === null) {
+ return new JSONResponse(['results' => [], 'total' => 0, 'limit' => $limit]);
+ }
+
+ $runs = $this->mapper->findActive(organisation: $organisation, limit: $limit, subject: $subject);
+ $total = $this->mapper->countActive(organisation: $organisation, subject: $subject);
+
+ return $this->page(runs: $runs, total: $total, limit: $limit);
+
+ }//end active()
+
+ /**
+ * The finished runs on ONE subject object: a case page's run history.
+ *
+ * The other half of the case view. A flow that completed on a case must
+ * not look like nothing ever happened, so this returns the terminal runs
+ * (`FlowRun::TERMINAL`: completed, stopped, dead_letter, failed) anchored
+ * to the given subject, newest first, bounded, with an honest total.
+ *
+ * The subject is REQUIRED. There is no org-wide "everything that ever
+ * finished" here: `or-flow-active-runs` requires the history surface
+ * (`index()`, with its per-caller visibility rule) to stay unchanged, and
+ * this read exists beside it rather than as a loosening of it. A request
+ * without a subject is refused, not answered widely.
+ *
+ * Authorization is the organisation scope, exactly as on `active()`: the
+ * mapper's organisation predicate is unconditional, a caller with no
+ * resolvable organisation reads nothing without a query being issued, and
+ * a subject uuid from another tenant matches zero rows. Rows are the same
+ * summarised shape as the live read, so a widget renders one list.
+ *
+ * @return JSONResponse `{results, total, limit}`, or 400 when no subject was given.
+ *
+ * @NoAdminRequired
+ * @NoCSRFRequired
+ *
+ * @spec openspec/changes/flow-runs-subject-scope/specs/flow-runs-subject-scope/spec.md
+ */
+ #[NoAdminRequired]
+ #[NoCSRFRequired]
+ public function completedForSubject(): JSONResponse {
+ $subject = $this->subjectFilter();
+ if ($subject === null) {
+ return new JSONResponse(
+ ['error' => 'The completed-runs read needs a subject: pass the subject object uuid as `subject`.'],
+ Http::STATUS_BAD_REQUEST
+ );
+ }
+
+ $limit = $this->pageLimit();
$organisation = $this->activeOrganisation();
if ($organisation === null) {
return new JSONResponse(['results' => [], 'total' => 0, 'limit' => $limit]);
}
- $runs = $this->mapper->findActive(organisation: $organisation, limit: $limit);
- $total = $this->mapper->countActive(organisation: $organisation);
+ $runs = $this->mapper->findCompletedForSubject(organisation: $organisation, subject: $subject, limit: $limit);
+ $total = $this->mapper->countCompletedForSubject(organisation: $organisation, subject: $subject);
+
+ return $this->page(runs: $runs, total: $total, limit: $limit);
+ }//end completedForSubject()
+
+ /**
+ * The bounded page size for the two case-widget reads, capped at 50.
+ *
+ * @return integer The limit.
+ *
+ * @spec openspec/changes/flow-runs-subject-scope/specs/flow-runs-subject-scope/spec.md
+ */
+ private function pageLimit(): int {
+ return min(50, max(1, (int)$this->request->getParam('limit', 10)));
+ }//end pageLimit()
+
+ /**
+ * The `subject` request parameter as a uuid, or null when none was given.
+ *
+ * Blank and non-string values count as absent: a filter that is not a
+ * uuid cannot name a subject, and treating it as one would either match
+ * nothing (misleading) or be coerced into something the caller did not
+ * send (worse).
+ *
+ * @return string|null The subject object uuid.
+ *
+ * @spec openspec/changes/flow-runs-subject-scope/specs/flow-runs-subject-scope/spec.md
+ */
+ private function subjectFilter(): ?string {
+ $subject = $this->request->getParam('subject');
+ if (is_string($subject) === false) {
+ return null;
+ }
+
+ $subject = trim($subject);
+ if ($subject === '') {
+ return null;
+ }
+
+ return $subject;
+ }//end subjectFilter()
+
+ /**
+ * A bounded list of summarised runs plus its honest total.
+ *
+ * Shared by the live read and the completed read so the two cannot drift
+ * apart on shape: the spec makes one row contract a requirement.
+ *
+ * @param array $runs The page of runs.
+ * @param integer $total How many runs matched in all.
+ * @param integer $limit The page size that was applied.
+ *
+ * @return JSONResponse `{results, total, limit}`.
+ *
+ * @spec openspec/changes/flow-runs-subject-scope/specs/flow-runs-subject-scope/spec.md
+ */
+ private function page(array $runs, int $total, int $limit): JSONResponse {
return new JSONResponse(
[
'results' => array_map(fn (FlowRun $run): array => $this->summarise(run: $run), $runs),
@@ -240,8 +366,7 @@ public function active(): JSONResponse {
'limit' => $limit,
]
);
-
- }//end active()
+ }//end page()
/**
* The caller's active organisation uuid, or null when none resolves.
@@ -566,25 +691,95 @@ public function resume(string $uuid): JSONResponse {
return $refusal;
}
- $refusal = $this->refuseUnlessAssignee(run: $run);
- if ($refusal !== null) {
- return $refusal;
- }
-
$payload = $this->request->getParams();
// Routing artefacts, not part of what the signaller is telling the run.
unset($payload['uuid'], $payload['_route']);
- $signalled = $this->runner->signal(run: $run, payload: $payload);
- if ($signalled === null) {
+ // The guard and the delivery are ONE seam — the same one a PHP consumer
+ // calls — so who may answer is decided in exactly one place.
+ try {
+ $signalled = $this->signals()->signalRunAs(run: $run, payload: $payload, actorUid: $this->callerUid());
+ } catch (FlowSignalRefused $refused) {
+ return $this->refusalResponse(refused: $refused, run: $run, verb: 'resumed');
+ }
+
+ return new JSONResponse($signalled->jsonSerialize());
+ }//end resume()
+
+ /**
+ * Deliver a signal addressed by BUSINESS KEY instead of run uuid.
+ *
+ * The caller that knows "the vote on proposal X closed" does not know a
+ * run uuid; an await-signal step that declared a `correlationKey` made
+ * its suspension addressable by that key. Resolution is FAIL-CLOSED in
+ * both directions (flow-approval-consolidation design D-7):
+ *
+ * - zero matches is a 404 and the signal is NOT buffered: a run that
+ * suspends with that key later was never the addressee
+ * - more than one match is a 409 and wakes NOTHING: picking one is
+ * picking wrong half the time, silently
+ *
+ * The authority is exactly {@see resume()}'s — the same flow-level check
+ * and the same recorded-assignee check, on the resolved run. A
+ * correlated signal cannot complete, claim or advance a user task: a run
+ * suspended on a user-task node treats any signal as a nudge, and a
+ * nudge is not an answer.
+ *
+ * @param string $key The business key.
+ *
+ * @return JSONResponse The signalled run, 404 when unmatched, 409 when
+ * ambiguous or not suspended.
+ *
+ * @NoAdminRequired
+ * @NoCSRFRequired
+ *
+ * @contract tests/integration/openregister-integrations.postman_collection.json
+ *
+ * @spec openspec/changes/flow-approval-consolidation/specs/flow-approval-consolidation/spec.md#requirement-the-signal-node-keeps-machine-to-machine-work-and-gains-a-correlation-key
+ */
+ #[NoAdminRequired]
+ #[NoCSRFRequired]
+ public function signalByKey(string $key): JSONResponse {
+ $key = trim($key);
+ $matches = [];
+ if ($key !== '') {
+ $matches = $this->mapper->findSuspendedByCorrelationKey(correlationKey: $key);
+ }
+
+ if ($matches === []) {
return new JSONResponse(
- ['error' => 'Only a suspended run can be resumed; this one is ' . $run->getStatus() . '.'],
+ ['error' => 'No suspended run is waiting for this key. The signal was not stored.'],
+ Http::STATUS_NOT_FOUND
+ );
+ }
+
+ if (count($matches) > 1) {
+ return new JSONResponse(
+ ['error' => 'More than one suspended run carries this key. Nothing was signalled; address the run by its uuid instead.'],
Http::STATUS_CONFLICT
);
}
+ $run = $matches[0];
+
+ $refusal = $this->refuseUnlessRunnable(flowId: (string)$run->getFlowId());
+ if ($refusal !== null) {
+ return $refusal;
+ }
+
+ $payload = $this->request->getParams();
+ // Routing artefacts, not part of what the signaller is telling the run.
+ unset($payload['key'], $payload['_route']);
+
+ // Same seam as resume() and as every PHP consumer: one guard.
+ try {
+ $signalled = $this->signals()->signalRunAs(run: $run, payload: $payload, actorUid: $this->callerUid());
+ } catch (FlowSignalRefused $refused) {
+ return $this->refusalResponse(refused: $refused, run: $run, verb: 'signalled');
+ }
+
return new JSONResponse($signalled->jsonSerialize());
- }//end resume()
+ }//end signalByKey()
/**
* Refuse unless the caller may RUN this flow.
@@ -627,70 +822,66 @@ private function refuseUnlessRunnable(string $flowId): ?JSONResponse {
}//end refuseUnlessRunnable()
/**
- * Refuse when the awaiting step names an assignee and the caller is not it.
+ * Translate the seam's typed refusal into this endpoint's HTTP contract.
*
- * WHY THIS EXISTS. `AwaitSignalNode` has always RECORDED an `assignee` on
- * the suspension, and nothing ever read it back. The run-level check above
- * asks "may you run this flow?", which is a different question from "is
- * this decision yours to make": everyone who could run the flow could
- * approve a step assigned to someone else, and the recorded assignee made
- * it look otherwise. ADR-098 names this gap — "no task authz — anyone
- * reaching the resume endpoint can decide".
+ * The GUARD lives in {@see FlowRunSignalService} — the same seam a PHP
+ * consumer calls, so who may answer is decided in one place (ADR-098 named
+ * the gap this closes: "no task authz — anyone reaching the resume endpoint
+ * can decide"). What stays here is only the WORDING, which differs per
+ * endpoint and is part of the existing HTTP contract.
*
- * Scope, stated honestly: this closes the WHO of an already-recorded
- * assignment. It is not the task entity, inbox or definition versioning
- * ADR-098 describes, and a step with no assignee is unchanged — silence
- * still means anyone, because tightening that would break every existing
- * webhook and child-run signal, which are not human decisions at all.
+ * A step with no assignee is unchanged — silence still means anyone,
+ * because tightening that would break every existing webhook and child-run
+ * signal, which are not human decisions at all.
*
- * @param FlowRun $run The suspended run.
+ * @param FlowSignalRefused $refused The seam's refusal.
+ * @param FlowRun $run The run the signal addressed.
+ * @param string $verb This endpoint's verb for the 409 wording ('resumed' or 'signalled').
*
- * @return JSONResponse|null A 403 when the caller is not the assignee.
+ * @return JSONResponse The 403 or 409 the refusal maps to.
+ *
+ * @spec openspec/changes/flow-engine-consumer-seams/specs/flow-engine-consumer-seams/spec.md#requirement-a-server-side-signal-passes-the-same-guard-as-the-http-resume
*/
- private function refuseUnlessAssignee(FlowRun $run): ?JSONResponse {
- // The rule itself lives in FlowRunAssignee, because HTTP is no longer
- // the only way to answer a step: a leaf app whose object completes a
- // task resumes the run in-process through FlowRunService::signal(),
- // which never passes this controller. One implementation, so the two
- // paths cannot drift into disagreeing about who may answer.
- $assignee = $this->assignees()->recordedFor(run: $run);
- if ($assignee === '') {
- return null;
- }
-
- $uid = $this->callerUid();
-
- if ($this->assignees()->mayAnswer(run: $run, uid: $uid) === true) {
- return null;
- }
+ private function refusalResponse(FlowSignalRefused $refused, FlowRun $run, string $verb): JSONResponse {
+ if ($refused->getReason() === FlowSignalRefused::NOT_ASSIGNEE) {
+ if ($refused->getActorUid() === null) {
+ return new JSONResponse(
+ ['error' => 'This step is assigned; sign in as the assignee to answer it.'],
+ Http::STATUS_FORBIDDEN
+ );
+ }
- if ($uid === null) {
return new JSONResponse(
- ['error' => 'This step is assigned; sign in as the assignee to answer it.'],
+ ['error' => 'This step is assigned to someone else.'],
Http::STATUS_FORBIDDEN
);
}
return new JSONResponse(
- ['error' => 'This step is assigned to someone else.'],
- Http::STATUS_FORBIDDEN
+ ['error' => 'Only a suspended run can be ' . $verb . '; this one is ' . $run->getStatus() . '.'],
+ Http::STATUS_CONFLICT
);
- }//end refuseUnlessAssignee()
+ }//end refusalResponse()
/**
- * The assignee rule, made on demand when none was injected.
+ * The guarded signal seam, made on demand when none was injected.
*
* Built locally rather than required as a constructor argument so adding it
- * breaks no existing construction site; it holds no state, so a locally
- * made one is indistinguishable from an injected one.
+ * breaks no existing construction site. The refusal a locally-built seam
+ * cannot log still reaches the caller as the 403 above, so nothing is
+ * silent; the container-built instance audits too.
*
- * @return FlowRunAssignee The rule.
+ * @return FlowRunSignalService The seam.
*
- * @spec openspec/specs/flow-engine/spec.md#requirement-a-run-suspended-on-an-external-signal-must-be-reachable
+ * @spec openspec/changes/flow-engine-consumer-seams/specs/flow-engine-consumer-seams/spec.md#requirement-a-server-side-signal-passes-the-same-guard-as-the-http-resume
*/
- private function assignees(): FlowRunAssignee {
- return new FlowRunAssignee(groupManager: $this->groupManager);
- }//end assignees()
+ private function signals(): FlowRunSignalService {
+ return ($this->signalService ?? new FlowRunSignalService(
+ mapper: $this->mapper,
+ runner: $this->runner,
+ groupManager: $this->groupManager
+ ));
+ }//end signals()
/**
* The current caller's uid, or null when anonymous.
diff --git a/lib/Controller/FormLinksController.php b/lib/Controller/FormLinksController.php
index 7b2c42fcb9..e1dd8a11b2 100644
--- a/lib/Controller/FormLinksController.php
+++ b/lib/Controller/FormLinksController.php
@@ -424,8 +424,8 @@ private function validateObject(
string $schema,
string $id,
): ?\OCA\OpenRegister\Db\ObjectEntity {
- $this->objectService->setSchema($schema);
$this->objectService->setRegister($register);
+ $this->objectService->setSchema($schema);
$this->objectService->setObject($id);
return $this->objectService->getObject();
diff --git a/lib/Controller/MapLinksController.php b/lib/Controller/MapLinksController.php
index d1298ae7ba..a2368f6ff7 100644
--- a/lib/Controller/MapLinksController.php
+++ b/lib/Controller/MapLinksController.php
@@ -336,8 +336,8 @@ public function available(): JSONResponse {
* returns for other reasons, which the caller could no longer tell apart.
*/
private function validateObject(string $register, string $schema, string $id): ?ObjectEntity {
- $this->objectService->setSchema($schema);
$this->objectService->setRegister($register);
+ $this->objectService->setSchema($schema);
$this->objectService->setObject($id);
return $this->objectService->getObject();
diff --git a/lib/Controller/NotesController.php b/lib/Controller/NotesController.php
index c2610a07cf..6d79b8680d 100644
--- a/lib/Controller/NotesController.php
+++ b/lib/Controller/NotesController.php
@@ -279,8 +279,15 @@ private function validateObject(
string $schema,
string $id,
): ?\OCA\OpenRegister\Db\ObjectEntity {
- $this->objectService->setSchema($schema);
+ // REGISTER FIRST. `setSchema()` scopes its slug lookup to whatever
+ // register is currently set, and ObjectService is reused across many
+ // operations in one process — so setting the schema first resolves it
+ // against a register LEFT BEHIND by an unrelated call. Measured here:
+ // `/objects/dossiq/case/{id}/notes` threw `Schema slug "case" is not
+ // carried by register "buildiq"`, an app this request never mentioned.
+ // Naming the register first makes the boundary the caller's own.
$this->objectService->setRegister($register);
+ $this->objectService->setSchema($schema);
$this->objectService->setObject($id);
return $this->objectService->getObject();
diff --git a/lib/Controller/ObjectsController.php b/lib/Controller/ObjectsController.php
index 0eac9b04db..7e82eeeffa 100644
--- a/lib/Controller/ObjectsController.php
+++ b/lib/Controller/ObjectsController.php
@@ -3538,9 +3538,12 @@ public function canDelete(
* @spec openspec/archive/retrofit-annotate-openregister-2026-04-23/tasks.md
*/
public function contracts(string $id, string $register, string $schema, ObjectService $objectService): JSONResponse {
- // Set the schema and register to the object service.
- $objectService->setSchema(schema: $schema);
+ // REGISTER FIRST. `setSchema()` scopes its slug lookup to whatever
+ // register is currently set, and ObjectService is reused across many
+ // operations in one process, so naming the schema first resolves it
+ // against a register an unrelated call left behind.
$objectService->setRegister(register: $register);
+ $objectService->setSchema(schema: $schema);
// Get request parameters for filtering.
$requestParams = $this->request->getParams();
@@ -3753,9 +3756,12 @@ public function uses(string $id, string $register, string $schema, ObjectService
* @spec openspec/archive/retrofit-annotate-openregister-2026-04-23/tasks.md
*/
public function used(string $id, string $register, string $schema, ObjectService $objectService): JSONResponse {
- // Set the schema and register to the object service.
- $objectService->setSchema(schema: $schema);
+ // REGISTER FIRST. `setSchema()` scopes its slug lookup to whatever
+ // register is currently set, and ObjectService is reused across many
+ // operations in one process, so naming the schema first resolves it
+ // against a register an unrelated call left behind.
$objectService->setRegister(register: $register);
+ $objectService->setSchema(schema: $schema);
// Build search query from request parameters.
$queryParams = $this->request->getParams();
@@ -3911,8 +3917,8 @@ public function logs(string $id, string $register, string $schema, ObjectService
public function lock(string $register, string $schema, string $id): JSONResponse {
try {
// Set the schema and register to the object service.
- $this->objectService->setSchema(schema: $schema);
$this->objectService->setRegister(register: $register);
+ $this->objectService->setSchema(schema: $schema);
$data = $this->request->getParams();
$process = ($data['process'] ?? null);
diff --git a/lib/Controller/OpenProjectLinksController.php b/lib/Controller/OpenProjectLinksController.php
index 6a1d072f9e..1ca08b2866 100644
--- a/lib/Controller/OpenProjectLinksController.php
+++ b/lib/Controller/OpenProjectLinksController.php
@@ -312,8 +312,8 @@ public function available(): JSONResponse {
* returns for other reasons, which the caller could no longer tell apart.
*/
private function validateObject(string $register, string $schema, string $id): ?ObjectEntity {
- $this->objectService->setSchema($schema);
$this->objectService->setRegister($register);
+ $this->objectService->setSchema($schema);
$this->objectService->setObject($id);
return $this->objectService->getObject();
diff --git a/lib/Controller/PhotoLinksController.php b/lib/Controller/PhotoLinksController.php
index c539cc9538..27c9ac6138 100644
--- a/lib/Controller/PhotoLinksController.php
+++ b/lib/Controller/PhotoLinksController.php
@@ -293,8 +293,8 @@ public function available(): JSONResponse {
* returns for other reasons, which the caller could no longer tell apart.
*/
private function validateObject(string $register, string $schema, string $id): ?ObjectEntity {
- $this->objectService->setSchema($schema);
$this->objectService->setRegister($register);
+ $this->objectService->setSchema($schema);
$this->objectService->setObject($id);
return $this->objectService->getObject();
diff --git a/lib/Controller/PollLinksController.php b/lib/Controller/PollLinksController.php
index b2004a230f..5f8c969538 100644
--- a/lib/Controller/PollLinksController.php
+++ b/lib/Controller/PollLinksController.php
@@ -319,8 +319,8 @@ public function available(): JSONResponse {
* returns for other reasons, which the caller could no longer tell apart.
*/
private function validateObject(string $register, string $schema, string $id): ?ObjectEntity {
- $this->objectService->setSchema($schema);
$this->objectService->setRegister($register);
+ $this->objectService->setSchema($schema);
$this->objectService->setObject($id);
return $this->objectService->getObject();
diff --git a/lib/Controller/PortalTaskController.php b/lib/Controller/PortalTaskController.php
new file mode 100644
index 0000000000..664d316143
--- /dev/null
+++ b/lib/Controller/PortalTaskController.php
@@ -0,0 +1,406 @@
+
+ * SPDX-License-Identifier: EUPL-1.2
+ *
+ * @category Controller
+ * @package OCA\OpenRegister\Controller
+ *
+ * @author Conduction Development Team
+ * @copyright 2026 Conduction B.V.
+ * @license EUPL-1.2 https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
+ *
+ * @link https://OpenRegister.app
+ *
+ * @spec openspec/changes/flow-portal-task/specs/flow-portal-task/spec.md#requirement-only-the-matched-party-completes-fail-closed
+ */
+
+declare(strict_types=1);
+
+namespace OCA\OpenRegister\Controller;
+
+use OCA\OpenRegister\Db\PortalTaskDelivery;
+use OCA\OpenRegister\Exception\PortalSubjectException;
+use OCA\OpenRegister\Exception\TaskAccessDeniedException;
+use OCA\OpenRegister\Exception\TaskConflictException;
+use OCA\OpenRegister\Exception\TaskValidationException;
+use OCA\OpenRegister\Service\Portal\PortalSubject;
+use OCA\OpenRegister\Service\Portal\PortalSubjectAssertion;
+use OCA\OpenRegister\Service\Portal\PortalTaskDeliveryService;
+use OCA\OpenRegister\Service\Portal\PortalTaskService;
+use OCP\AppFramework\Controller;
+use OCP\AppFramework\Db\DoesNotExistException;
+use OCP\AppFramework\Http;
+use OCP\AppFramework\Http\Attribute\AnonRateLimit;
+use OCP\AppFramework\Http\Attribute\NoCSRFRequired;
+use OCP\AppFramework\Http\Attribute\PublicPage;
+use OCP\AppFramework\Http\JSONResponse;
+use OCP\IGroupManager;
+use OCP\IRequest;
+use OCP\IUserSession;
+use Psr\Log\LoggerInterface;
+use Throwable;
+
+/**
+ * REST surface of the portal task seam.
+ *
+ * @SuppressWarnings(PHPMD.CouplingBetweenObjects) The controller mediates
+ * between HTTP and the seam's three services plus their exception shapes;
+ * that is the whole of its job.
+ *
+ * @spec openspec/changes/flow-portal-task/specs/flow-portal-task/spec.md#requirement-only-the-matched-party-completes-fail-closed
+ */
+class PortalTaskController extends Controller {
+
+ /**
+ * Constructor.
+ *
+ * @param string $appName The app id.
+ * @param IRequest $request The request.
+ * @param PortalSubjectAssertion $assertion Verifies the acting subject.
+ * @param PortalTaskService $portal The subject-scoped read and completion.
+ * @param PortalTaskDeliveryService $delivery The delivery ledger.
+ * @param IUserSession $userSession Names the operator on the delivery routes.
+ * @param IGroupManager|null $groupManager Decides administrator status;
+ * absent, nobody is one.
+ * @param LoggerInterface|null $logger Where an unexpected failure's detail
+ * goes, INSTEAD of the response.
+ */
+ public function __construct(
+ string $appName,
+ IRequest $request,
+ private readonly PortalSubjectAssertion $assertion,
+ private readonly PortalTaskService $portal,
+ private readonly PortalTaskDeliveryService $delivery,
+ private readonly IUserSession $userSession,
+ private readonly ?IGroupManager $groupManager = null,
+ private readonly ?LoggerInterface $logger = null,
+ ) {
+ parent::__construct(appName: $appName, request: $request);
+
+ }//end __construct()
+
+ /**
+ * The acting subject's open portal tasks, with case context.
+ *
+ * @param int $limit Page size.
+ * @param int $offset Page offset.
+ *
+ * @return JSONResponse The page: results, total, limit, offset.
+ *
+ * @spec openspec/changes/flow-portal-task/specs/flow-portal-task/spec.md#requirement-delivery-rides-the-portal-contribution-surface-and-nothing-else
+ */
+ #[PublicPage]
+ #[NoCSRFRequired]
+ #[AnonRateLimit(limit: 120, period: 60)]
+ public function index(int $limit = 25, int $offset = 0): JSONResponse {
+ return $this->asSubject(
+ action: fn (PortalSubject $subject): JSONResponse => new JSONResponse(
+ $this->portal->listForSubject(subject: $subject, limit: $limit, offset: $offset)
+ )
+ );
+ }//end index()
+
+ /**
+ * One portal task, if it is the acting subject's.
+ *
+ * @param string $uuid The task uuid.
+ *
+ * @return JSONResponse The row; 404 when absent or not this subject's.
+ *
+ * @spec openspec/changes/flow-portal-task/specs/flow-portal-task/spec.md#requirement-delivery-rides-the-portal-contribution-surface-and-nothing-else
+ */
+ #[PublicPage]
+ #[NoCSRFRequired]
+ #[AnonRateLimit(limit: 120, period: 60)]
+ public function show(string $uuid): JSONResponse {
+ return $this->asSubject(
+ action: fn (PortalSubject $subject): JSONResponse => new JSONResponse(
+ $this->portal->row(task: $this->portal->show(subject: $subject, uuid: $uuid))
+ )
+ );
+ }//end show()
+
+ /**
+ * Complete a portal task as the acting subject, with answers and uploads.
+ *
+ * Multipart or JSON: files arrive under `files[]` or `file`; `answers` is
+ * an object (or a JSON string of one); `comment` and `outcome` are plain.
+ *
+ * @param string $uuid The task uuid.
+ * @param string $outcome The outcome to record; `submitted` by default.
+ * @param string|null $comment The party's comment.
+ *
+ * @return JSONResponse The completed task row, or a named refusal.
+ *
+ * @spec openspec/changes/flow-portal-task/specs/flow-portal-task/spec.md#requirement-an-upload-completion-lands-as-a-file-attachment-on-the-case-object
+ */
+ #[PublicPage]
+ #[NoCSRFRequired]
+ #[AnonRateLimit(limit: 30, period: 60)]
+ public function complete(string $uuid, string $outcome = PortalTaskService::DEFAULT_OUTCOME, ?string $comment = null): JSONResponse {
+ return $this->asSubject(
+ action: fn (PortalSubject $subject): JSONResponse => new JSONResponse(
+ $this->portal->row(
+ task: $this->portal->complete(
+ subject: $subject,
+ uuid: $uuid,
+ answers: $this->answers(),
+ comment: $comment,
+ files: $this->uploads(),
+ outcome: $outcome
+ )
+ )
+ )
+ );
+ }//end complete()
+
+ /**
+ * The delivery requests awaiting settlement: what portaliq renders and sends.
+ *
+ * Administrator only. The route declares no NoAdminRequired, so the
+ * framework already refuses a non-administrator; the explicit check below
+ * makes the posture readable and holds if the attribute set ever changes.
+ *
+ * @param int $limit Page size.
+ *
+ * @return JSONResponse The pending rows.
+ *
+ * @spec openspec/changes/flow-portal-task/specs/flow-portal-task/spec.md#requirement-delivery-rides-the-portal-contribution-surface-and-nothing-else
+ */
+ #[NoCSRFRequired]
+ public function deliveries(int $limit = 100): JSONResponse {
+ $refusal = $this->refuseUnlessAdmin();
+ if ($refusal !== null) {
+ return $refusal;
+ }
+
+ $rows = array_map(
+ static fn (PortalTaskDelivery $row): array => $row->jsonSerialize(),
+ $this->delivery->pending(limit: $limit)
+ );
+
+ return new JSONResponse(['results' => $rows, 'total' => count($rows)]);
+ }//end deliveries()
+
+ /**
+ * Portaliq reports a delivery request as sent.
+ *
+ * @param string $uuid The delivery uuid.
+ *
+ * @return JSONResponse The settled row; 404 when no such request exists.
+ *
+ * @spec openspec/changes/flow-portal-task/specs/flow-portal-task/spec.md#requirement-delivery-rides-the-portal-contribution-surface-and-nothing-else
+ */
+ #[NoCSRFRequired]
+ public function deliveryDelivered(string $uuid): JSONResponse {
+ $refusal = $this->refuseUnlessAdmin();
+ if ($refusal !== null) {
+ return $refusal;
+ }
+
+ try {
+ return new JSONResponse($this->delivery->markDelivered(uuid: $uuid)->jsonSerialize());
+ } catch (DoesNotExistException) {
+ return new JSONResponse(['error' => 'No such delivery request', 'code' => 'no-such-delivery'], Http::STATUS_NOT_FOUND);
+ }
+ }//end deliveryDelivered()
+
+ /**
+ * Portaliq reports a delivery request as failed, and why.
+ *
+ * @param string $uuid The delivery uuid.
+ * @param string $error The failure.
+ *
+ * @return JSONResponse The settled row; 404 when no such request exists.
+ *
+ * @spec openspec/changes/flow-portal-task/specs/flow-portal-task/spec.md#requirement-delivery-rides-the-portal-contribution-surface-and-nothing-else
+ */
+ #[NoCSRFRequired]
+ public function deliveryFailed(string $uuid, string $error = ''): JSONResponse {
+ $refusal = $this->refuseUnlessAdmin();
+ if ($refusal !== null) {
+ return $refusal;
+ }
+
+ if (trim($error) === '') {
+ return new JSONResponse(['error' => 'A failed delivery needs an error naming why.', 'code' => 'error-required'], Http::STATUS_BAD_REQUEST);
+ }
+
+ try {
+ return new JSONResponse($this->delivery->markFailed(uuid: $uuid, error: $error)->jsonSerialize());
+ } catch (DoesNotExistException) {
+ return new JSONResponse(['error' => 'No such delivery request', 'code' => 'no-such-delivery'], Http::STATUS_NOT_FOUND);
+ }
+ }//end deliveryFailed()
+
+ /**
+ * Resolve the acting subject, run the action as them, and translate every
+ * refusal to the wire, uniformly.
+ *
+ * @param callable(PortalSubject): JSONResponse $action The action.
+ *
+ * @return JSONResponse The action's response, or the refusal.
+ *
+ * @spec openspec/changes/flow-portal-task/specs/flow-portal-task/spec.md#requirement-only-the-matched-party-completes-fail-closed
+ */
+ private function asSubject(callable $action): JSONResponse {
+ try {
+ $subject = $this->assertion->resolve(request: $this->request);
+ } catch (PortalSubjectException $refused) {
+ // No subject, no answer. The code says which class of defect; the
+ // verifier's own message stays in the log.
+ $this->logger?->info('[PortalTaskController] Refused a portal request: ' . $refused->getMessage(), ['code' => $refused->refusal()]);
+
+ return new JSONResponse(['error' => 'No acting portal subject', 'code' => $refused->refusal()], Http::STATUS_UNAUTHORIZED);
+ }
+
+ try {
+ return $action($subject);
+ } catch (TaskValidationException $refused) {
+ return new JSONResponse(['error' => $refused->getMessage(), 'code' => 'upload-constraint'], Http::STATUS_BAD_REQUEST);
+ } catch (TaskAccessDeniedException) {
+ // Denied reads as absent: another subject who knows the uuid learns
+ // nothing, not even that it exists. The denial is in the audit.
+ return new JSONResponse(['error' => 'No such task', 'code' => 'no-such-task'], Http::STATUS_NOT_FOUND);
+ } catch (DoesNotExistException) {
+ return new JSONResponse(['error' => 'No such task', 'code' => 'no-such-task'], Http::STATUS_NOT_FOUND);
+ } catch (TaskConflictException $conflict) {
+ return new JSONResponse(['error' => $conflict->getMessage(), 'code' => 'task-closed'], Http::STATUS_CONFLICT);
+ } catch (Throwable $failure) {
+ $this->logger?->error('[PortalTaskController] Portal task operation failed: ' . $failure->getMessage(), ['exception' => $failure]);
+
+ return new JSONResponse(
+ ['error' => 'The portal task operation failed. The details are in the server log.', 'code' => 'internal'],
+ Http::STATUS_INTERNAL_SERVER_ERROR
+ );
+ }//end try
+ }//end asSubject()
+
+ /**
+ * The submitted answer fields: an object, or a JSON string of one.
+ *
+ * @return array The answers; empty when none were sent.
+ */
+ private function answers(): array {
+ $raw = $this->request->getParam('answers');
+ if (is_string($raw) === true) {
+ $decoded = json_decode($raw, true);
+ if (is_array($decoded) === true) {
+ return $decoded;
+ }
+
+ return [];
+ }
+
+ if (is_array($raw) === true) {
+ return $raw;
+ }
+
+ return [];
+ }//end answers()
+
+ /**
+ * The uploads, normalised to {name, type, size, tmp_name} regardless of
+ * whether they came as `files[]` or one `file`.
+ *
+ * @return array> The uploads; empty when none.
+ */
+ private function uploads(): array {
+ $uploads = [];
+ foreach (['files', 'file'] as $key) {
+ $raw = $this->request->getUploadedFile($key);
+ if (is_array($raw) === false || $raw === []) {
+ continue;
+ }
+
+ $names = ($raw['name'] ?? null);
+ if (is_array($names) === false) {
+ $uploads[] = $this->oneUpload(raw: $raw);
+ continue;
+ }
+
+ foreach (array_keys($names) as $index) {
+ $uploads[] = $this->oneUpload(
+ raw: [
+ 'name' => ($raw['name'][$index] ?? ''),
+ 'type' => ($raw['type'][$index] ?? ''),
+ 'tmp_name' => ($raw['tmp_name'][$index] ?? ''),
+ 'size' => ($raw['size'][$index] ?? 0),
+ 'error' => ($raw['error'][$index] ?? UPLOAD_ERR_NO_FILE),
+ ]
+ );
+ }
+ }//end foreach
+
+ // A slot that carried no file (UPLOAD_ERR_NO_FILE) is not an upload.
+ return array_values(array_filter($uploads, static fn (array $file): bool => (int)$file['error'] === UPLOAD_ERR_OK));
+ }//end uploads()
+
+ /**
+ * One `$_FILES`-shaped entry, normalised.
+ *
+ * @param array $raw The entry.
+ *
+ * @return array {name, type, size, tmp_name, error}.
+ */
+ private function oneUpload(array $raw): array {
+ return [
+ 'name' => (string)($raw['name'] ?? ''),
+ 'type' => (string)($raw['type'] ?? ''),
+ 'size' => (int)($raw['size'] ?? 0),
+ 'tmp_name' => (string)($raw['tmp_name'] ?? ''),
+ 'error' => (int)($raw['error'] ?? UPLOAD_ERR_NO_FILE),
+ ];
+ }//end oneUpload()
+
+ /**
+ * Refuse the delivery routes to anyone but an authenticated administrator.
+ *
+ * @return JSONResponse|null The refusal, or null to proceed.
+ */
+ private function refuseUnlessAdmin(): ?JSONResponse {
+ $user = $this->userSession->getUser();
+ if ($user === null) {
+ return new JSONResponse(['error' => 'No session', 'code' => 'no-session'], Http::STATUS_UNAUTHORIZED);
+ }
+
+ $isAdmin = false;
+ try {
+ $isAdmin = ($this->groupManager?->isAdmin($user->getUID()) === true);
+ } catch (Throwable) {
+ $isAdmin = false;
+ }
+
+ if ($isAdmin === false) {
+ return new JSONResponse(['error' => 'Administrators only', 'code' => 'admin-required'], Http::STATUS_FORBIDDEN);
+ }
+
+ return null;
+ }//end refuseUnlessAdmin()
+}//end class
diff --git a/lib/Controller/RelationsController.php b/lib/Controller/RelationsController.php
index 2175a9afef..df430eef47 100644
--- a/lib/Controller/RelationsController.php
+++ b/lib/Controller/RelationsController.php
@@ -531,8 +531,8 @@ private function validateObject(
string $schema,
string $id,
): ?\OCA\OpenRegister\Db\ObjectEntity {
- $this->objectService->setSchema($schema);
$this->objectService->setRegister($register);
+ $this->objectService->setSchema($schema);
$this->objectService->setObject($id);
return $this->objectService->getObject();
diff --git a/lib/Controller/SettingsController.php b/lib/Controller/SettingsController.php
index 0443c1a2fc..96de9fdcf1 100644
--- a/lib/Controller/SettingsController.php
+++ b/lib/Controller/SettingsController.php
@@ -665,7 +665,11 @@ private function getHybridSearchDiagnostics(bool $isPostgres): array {
$row = $result->fetch();
$result->closeCursor();
- if ($row !== false) {
+ // An is_array check, not `!== false`. fetch() can answer NULL
+ // as well as false, which passes a `!== false` guard and then
+ // warns on every offset read. Lines 476 and 644 of this file
+ // already use this idiom; this was the one site that did not.
+ if (is_array($row) === true) {
$diagnostics['vectors']['total'] = (int)$row['total'];
$diagnostics['vectors']['pgvectorPopulated'] = (int)$row['populated'];
}
@@ -876,8 +880,11 @@ function (\OCA\OpenRegister\Db\ObjectEntity $org): array {
// (see RegisterMapper::getAllRegisterIdsWithSchema / MarkerLookupTrait).
$stmt = $qb->executeQuery();
$rows = [];
+ // Same reason as above, and here it matters more: a fetch() that
+ // answers NULL never satisfies `!== false`, so the loop would spin
+ // forever appending nulls rather than ending.
$row = $stmt->fetch();
- while ($row !== false) {
+ while (is_array($row) === true) {
$rows[] = $row;
$row = $stmt->fetch();
}
diff --git a/lib/Controller/ShareLinksController.php b/lib/Controller/ShareLinksController.php
index 0fae0f86ac..12b8e348a6 100644
--- a/lib/Controller/ShareLinksController.php
+++ b/lib/Controller/ShareLinksController.php
@@ -254,8 +254,8 @@ public function files(string $register, string $schema, string $id): JSONRespons
* returns for other reasons, which the caller could no longer tell apart.
*/
private function validateObject(string $register, string $schema, string $id): ?ObjectEntity {
- $this->objectService->setSchema($schema);
$this->objectService->setRegister($register);
+ $this->objectService->setSchema($schema);
$this->objectService->setObject($id);
return $this->objectService->getObject();
diff --git a/lib/Controller/TagsController.php b/lib/Controller/TagsController.php
index 9efa517e4f..a987d0f004 100644
--- a/lib/Controller/TagsController.php
+++ b/lib/Controller/TagsController.php
@@ -155,8 +155,8 @@ public function index(
string $id,
): JSONResponse {
try {
- $this->objectService->setSchema($schema);
$this->objectService->setRegister($register);
+ $this->objectService->setSchema($schema);
$this->objectService->setObject($id);
$object = $this->objectService->getObject();
@@ -194,8 +194,8 @@ public function add(
string $id,
): JSONResponse {
try {
- $this->objectService->setSchema($schema);
$this->objectService->setRegister($register);
+ $this->objectService->setSchema($schema);
$this->objectService->setObject($id);
$object = $this->objectService->getObject();
@@ -245,8 +245,8 @@ public function remove(
string $tag,
): JSONResponse {
try {
- $this->objectService->setSchema($schema);
$this->objectService->setRegister($register);
+ $this->objectService->setSchema($schema);
$this->objectService->setObject($id);
$object = $this->objectService->getObject();
diff --git a/lib/Controller/TalkLinksController.php b/lib/Controller/TalkLinksController.php
index a32a231371..d1ec452471 100644
--- a/lib/Controller/TalkLinksController.php
+++ b/lib/Controller/TalkLinksController.php
@@ -298,8 +298,8 @@ public function rooms(): JSONResponse {
* returns for other reasons, which the caller could no longer tell apart.
*/
private function validateObject(string $register, string $schema, string $id): ?ObjectEntity {
- $this->objectService->setSchema($schema);
$this->objectService->setRegister($register);
+ $this->objectService->setSchema($schema);
$this->objectService->setObject($id);
return $this->objectService->getObject();
diff --git a/lib/Controller/TaskController.php b/lib/Controller/TaskController.php
new file mode 100644
index 0000000000..f16eab994e
--- /dev/null
+++ b/lib/Controller/TaskController.php
@@ -0,0 +1,707 @@
+
+ * SPDX-License-Identifier: EUPL-1.2
+ *
+ * @category Controller
+ * @package OCA\OpenRegister\Controller
+ *
+ * @author Conduction Development Team
+ * @copyright 2026 Conduction B.V.
+ * @license EUPL-1.2 https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
+ *
+ * @link https://OpenRegister.app
+ *
+ * @spec openspec/changes/flow-task-entity/specs/flow-tasks/spec.md#requirement-every-lifecycle-verb-is-authorized-fail-closed
+ */
+
+declare(strict_types=1);
+
+namespace OCA\OpenRegister\Controller;
+
+use OCA\OpenRegister\Db\Task;
+use OCA\OpenRegister\Db\TaskInboxCriteria;
+use OCA\OpenRegister\Exception\TaskAccessDeniedException;
+use OCA\OpenRegister\Exception\TaskConflictException;
+use OCA\OpenRegister\Exception\TaskFormRefusedException;
+use OCA\OpenRegister\Exception\TaskSubjectWriteRefusedException;
+use OCA\OpenRegister\Exception\TaskValidationException;
+use OCA\OpenRegister\Service\Task\TaskAuthorizationService;
+use OCA\OpenRegister\Service\Task\TaskFormCompletion;
+use OCA\OpenRegister\Service\Task\TaskFormResolver;
+use OCA\OpenRegister\Service\Task\TaskInboxService;
+use OCA\OpenRegister\Service\Task\TaskService;
+use OCA\OpenRegister\Service\Task\TaskTemporalProjection;
+use OCP\AppFramework\Controller;
+use OCP\AppFramework\Db\DoesNotExistException;
+use OCP\AppFramework\Http;
+use OCP\AppFramework\Http\Attribute\NoAdminRequired;
+use OCP\AppFramework\Http\Attribute\NoCSRFRequired;
+use OCP\AppFramework\Http\ContentSecurityPolicy;
+use OCP\AppFramework\Http\JSONResponse;
+use OCP\AppFramework\Http\TemplateResponse;
+use OCP\IGroupManager;
+use OCP\IRequest;
+use OCP\IUserSession;
+use Psr\Log\LoggerInterface;
+use Throwable;
+
+/**
+ * REST surface for the fleet-generic task.
+ *
+ * @SuppressWarnings(PHPMD.ExcessiveClassComplexity) The sum of the verb
+ * routes and one catch per refusal shape in {@see respondWith()}; both scale
+ * with the spec, not with entanglement.
+ * @SuppressWarnings(PHPMD.ExcessiveParameterList) One collaborator per
+ * concern, injected: the deep-link builder the projections carry, the form
+ * resolver and the form-aware completion. The controller is the one place
+ * those meet HTTP, and a facade over them would add a class that only
+ * forwards.
+ * @SuppressWarnings(PHPMD.CyclomaticComplexity) respondWith() holds ONE
+ * catch per refusal shape so no verb can drift; folding two shapes into one
+ * catch is how a 400 and a 422 end up indistinguishable.
+ * @SuppressWarnings(PHPMD.TooManyPublicMethods) One route method per
+ * lifecycle verb the spec names, plus the three reads. Folding verbs into a
+ * mode parameter is how per-verb authorization rules get lost.
+ * @SuppressWarnings(PHPMD.CouplingBetweenObjects) The controller mediates
+ * between HTTP and the task services plus their three exception shapes;
+ * that is the whole of its job.
+ *
+ * @spec openspec/changes/flow-task-entity/specs/flow-tasks/spec.md#requirement-every-lifecycle-verb-is-authorized-fail-closed
+ */
+class TaskController extends Controller {
+
+ /**
+ * Constructor.
+ *
+ * @param string $appName The app id.
+ * @param IRequest $request The request.
+ * @param TaskService $tasks The authorized lifecycle.
+ * @param TaskInboxService $inbox The inbox queries.
+ * @param TaskAuthorizationService $authorization Read-visibility decisions.
+ * @param TaskTemporalProjection $temporal The one overdue derivation.
+ * @param IUserSession $userSession Names the acting identity.
+ * @param TaskFormResolver $forms Resolves the form a task presents, per read.
+ * @param TaskFormCompletion $completion Completes a task with a form payload,
+ * writing the subject first.
+ * @param LoggerInterface|null $logger Where an unexpected failure's
+ * detail goes, INSTEAD of the response.
+ * @param IGroupManager|null $groupManager Resolves the caller's groups
+ * and admin status for inbox
+ * visibility. Nullable so the
+ * controller stays constructible
+ * bare; absent means no groups
+ * and not admin, which SCOPES
+ * rather than widens.
+ */
+ public function __construct(
+ string $appName,
+ IRequest $request,
+ private readonly TaskService $tasks,
+ private readonly TaskInboxService $inbox,
+ private readonly TaskAuthorizationService $authorization,
+ private readonly TaskTemporalProjection $temporal,
+ private readonly IUserSession $userSession,
+ private readonly TaskFormResolver $forms,
+ private readonly TaskFormCompletion $completion,
+ private readonly ?LoggerInterface $logger = null,
+ private readonly ?IGroupManager $groupManager = null,
+ ) {
+ parent::__construct(appName: $appName, request: $request);
+
+ }//end __construct()
+
+ /**
+ * The deep link every projection carries: a page route that lands a
+ * person on the task's own surface.
+ *
+ * The notification actions, the VTODO `URL` and the route action in the
+ * task rules all resolve to THIS route, so there is one stable address
+ * for "open this task" however the task reached the person. It serves
+ * the SPA shell directly, exactly like `DashboardController::catchAll()`
+ * serves every other deep sub-path: the router runs in HISTORY mode
+ * (src/main.js), so the path itself is the route and the SPA's
+ * `flow-task-detail` route (`/flow-tasks/:uuid`, src/main.js) renders
+ * the task. It used to redirect to a HASH path instead, which the
+ * history-mode router never resolved: every notification button and
+ * VTODO URL landed on the dashboard.
+ *
+ * @param string $uuid The task uuid, consumed by the SPA route, not here.
+ *
+ * @return TemplateResponse The SPA shell.
+ *
+ * @no-admin-idor-exempt Reads nothing: the shell is identical for every
+ * uuid, and the SPA performs the visibility-checked read
+ * (TaskController::show, 404 for the invisible).
+ *
+ * @SuppressWarnings(PHPMD.UnusedFormalParameter) The route binds {uuid},
+ * the SPA consumes it from the URL; dropping the parameter would
+ * unbind the route.
+ *
+ * @spec openspec/changes/flow-task-inbox-projections/specs/flow-task-projections/spec.md#requirement-an-assigned-task-appears-in-the-assignees-own-calendar
+ */
+ #[NoAdminRequired]
+ #[NoCSRFRequired]
+ public function open(string $uuid): TemplateResponse {
+ $response = new TemplateResponse(
+ appName: $this->appName,
+ templateName: 'index',
+ params: []
+ );
+
+ // The same relaxation the dashboard shell carries: the SPA calls the
+ // API from this page, so the shell's CSP must allow it.
+ $csp = new ContentSecurityPolicy();
+ $csp->addAllowedConnectDomain('*');
+ $response->setContentSecurityPolicy($csp);
+
+ return $response;
+ }//end open()
+
+ /**
+ * The inbox: what is waiting for me, with subject context and a total.
+ *
+ * @param string $scope assigned|pooled|watched|all.
+ * @param string|null $state Restrict to CMMN states (comma-separated).
+ * @param string|null $isTerminal 'true'|'false' to restrict on terminality.
+ * @param string|null $priority Restrict to one priority.
+ * @param string|null $objectUuid Restrict to tasks anchored to this object.
+ * @param string|null $overdue 'true' to restrict to derived-overdue tasks.
+ * @param string $sort dueAt|priority|created. A leading `-` inverts
+ * the order (`-dueAt`), so sort and direction travel
+ * as one parameter.
+ * @param int $limit Page size.
+ * @param int $offset Page offset.
+ *
+ * @return JSONResponse The page: results, total, limit, offset.
+ *
+ * @spec openspec/changes/flow-task-entity/specs/flow-tasks/spec.md#requirement-the-inbox-answers-what-is-waiting-for-me-in-one-query
+ */
+ #[NoAdminRequired]
+ #[NoCSRFRequired]
+ public function index(
+ string $scope = TaskInboxCriteria::SCOPE_ASSIGNED,
+ ?string $state = null,
+ ?string $isTerminal = null,
+ ?string $priority = null,
+ ?string $objectUuid = null,
+ ?string $overdue = null,
+ string $sort = TaskInboxCriteria::SORT_DUE,
+ int $limit = 25,
+ int $offset = 0,
+ ): JSONResponse {
+ $uid = $this->uid();
+ if ($uid === null) {
+ return new JSONResponse(['error' => 'No session'], Http::STATUS_UNAUTHORIZED);
+ }
+
+ $states = [];
+ if ($state !== null && trim($state) !== '') {
+ $states = array_values(array_filter(array_map('trim', explode(',', $state))));
+ }
+
+ $terminalFilter = null;
+ if ($isTerminal !== null) {
+ $terminalFilter = filter_var($isTerminal, FILTER_VALIDATE_BOOLEAN);
+ }
+
+ // The derived-overdue filter takes its clock instant from the one
+ // derivation class, so filter and projection cannot disagree.
+ $overdueAt = null;
+ if ($overdue !== null && filter_var($overdue, FILTER_VALIDATE_BOOLEAN) === true) {
+ $overdueAt = $this->temporal->now();
+ }
+
+ $descending = str_starts_with($sort, '-');
+ $sortKey = ltrim($sort, '-');
+
+ $criteria = new TaskInboxCriteria(
+ uid: $uid,
+ groupIds: $this->groupIds(uid: $uid),
+ isAdmin: $this->isAdmin(uid: $uid),
+ scope: $scope,
+ states: $states,
+ isTerminal: $terminalFilter,
+ priority: $priority,
+ objectUuid: $objectUuid,
+ overdueAt: $overdueAt,
+ sort: $sortKey,
+ sortDescending: $descending,
+ );
+
+ return new JSONResponse($this->inbox->inbox(criteria: $criteria, limit: $limit, offset: $offset));
+ }//end index()
+
+ /**
+ * One task, visibility-checked, with the form it presents.
+ *
+ * The row carries `form` (null when the step declares none, else the
+ * resolved description with each field's `required` and `order` from the
+ * declaration) and `requireChecklist`, so the completion surface needs no
+ * second round-trip. Derived on this read from the pinned declaration
+ * and the live schema; nothing is stored.
+ *
+ * @param string $uuid The task uuid.
+ *
+ * @return JSONResponse The task row; 404 when absent OR invisible.
+ *
+ * @spec openspec/changes/flow-task-entity/specs/flow-tasks/spec.md#requirement-every-lifecycle-verb-is-authorized-fail-closed
+ * @spec openspec/changes/flow-task-forms/specs/flow-task-forms/spec.md#requirement-the-rendered-form-carries-the-declarations-required-flags-and-order
+ */
+ #[NoAdminRequired]
+ #[NoCSRFRequired]
+ public function show(string $uuid): JSONResponse {
+ try {
+ $task = $this->tasks->get(uuid: $uuid);
+ } catch (DoesNotExistException) {
+ return new JSONResponse(['error' => 'No such task'], Http::STATUS_NOT_FOUND);
+ }
+
+ if ($this->authorization->mayRead(task: $task, uid: $this->uid()) === false) {
+ // Not 403: a caller with no relationship to the task learns
+ // nothing, not even that the uuid exists.
+ return new JSONResponse(['error' => 'No such task'], Http::STATUS_NOT_FOUND);
+ }
+
+ return new JSONResponse(
+ array_merge(
+ $this->inbox->row(task: $task, subjects: [], now: $this->temporal->now()),
+ $this->forms->describe(task: $task)
+ )
+ );
+ }//end show()
+
+ /**
+ * A task's audit trail, visibility-checked.
+ *
+ * @param string $uuid The task uuid.
+ *
+ * @return JSONResponse The entries, oldest first.
+ *
+ * @spec openspec/changes/flow-task-entity/specs/flow-tasks/spec.md#requirement-the-task-audit-is-append-only-and-names-the-performer-type
+ */
+ #[NoAdminRequired]
+ #[NoCSRFRequired]
+ public function audit(string $uuid): JSONResponse {
+ try {
+ $task = $this->tasks->get(uuid: $uuid);
+ } catch (DoesNotExistException) {
+ return new JSONResponse(['error' => 'No such task'], Http::STATUS_NOT_FOUND);
+ }
+
+ if ($this->authorization->mayRead(task: $task, uid: $this->uid()) === false) {
+ // Not 403: a caller with no relationship to the task learns
+ // nothing, not even that the uuid exists.
+ return new JSONResponse(['error' => 'No such task'], Http::STATUS_NOT_FOUND);
+ }
+
+ return new JSONResponse(['results' => $this->tasks->auditTrail(uuid: $uuid)]);
+ }//end audit()
+
+ /**
+ * Create a task.
+ *
+ * @return JSONResponse The created task, or a named refusal.
+ *
+ * @spec openspec/changes/flow-task-entity/specs/flow-tasks/spec.md#requirement-a-task-is-a-first-class-record-not-a-flow-artefact
+ */
+ #[NoAdminRequired]
+ #[NoCSRFRequired]
+ public function create(): JSONResponse {
+ return $this->respondWith(
+ verb: fn (): Task => $this->tasks->create(data: $this->body(), actor: $this->uid()),
+ successStatus: Http::STATUS_CREATED
+ );
+ }//end create()
+
+ /**
+ * Offer a task to a candidate pool.
+ *
+ * @param string $uuid The task uuid.
+ *
+ * @return JSONResponse The offered task, or a named refusal.
+ *
+ * @spec openspec/changes/flow-task-entity/specs/flow-tasks/spec.md#requirement-the-performer-model-spans-people-groups-agents-and-workers
+ */
+ #[NoAdminRequired]
+ #[NoCSRFRequired]
+ public function offer(string $uuid): JSONResponse {
+ return $this->respondWith(
+ verb: fn (): Task => $this->tasks->offer(uuid: $uuid, pool: $this->body(), actor: $this->uid()),
+ uuid: $uuid
+ );
+ }//end offer()
+
+ /**
+ * Claim a pooled task.
+ *
+ * @param string $uuid The task uuid.
+ *
+ * @return JSONResponse The claimed task; 409 for the race's loser.
+ *
+ * @spec openspec/changes/flow-task-entity/specs/flow-tasks/spec.md#requirement-every-lifecycle-verb-is-authorized-fail-closed
+ */
+ #[NoAdminRequired]
+ #[NoCSRFRequired]
+ public function claim(string $uuid): JSONResponse {
+ return $this->respondWith(
+ verb: fn (): Task => $this->tasks->claim(uuid: $uuid, actor: $this->uid()),
+ uuid: $uuid
+ );
+ }//end claim()
+
+ /**
+ * Return a claimed task to its pool.
+ *
+ * @param string $uuid The task uuid.
+ *
+ * @return JSONResponse The pooled task, or a named refusal.
+ *
+ * @spec openspec/changes/flow-task-entity/specs/flow-tasks/spec.md#requirement-every-lifecycle-verb-is-authorized-fail-closed
+ */
+ #[NoAdminRequired]
+ #[NoCSRFRequired]
+ public function unclaim(string $uuid): JSONResponse {
+ return $this->respondWith(
+ verb: fn (): Task => $this->tasks->unclaim(uuid: $uuid, actor: $this->uid()),
+ uuid: $uuid
+ );
+ }//end unclaim()
+
+ /**
+ * Assign a task directly.
+ *
+ * @param string $uuid The task uuid.
+ * @param string $assignee The performer reference.
+ *
+ * @return JSONResponse The assigned task, or a named refusal.
+ *
+ * @spec openspec/changes/flow-task-entity/specs/flow-tasks/spec.md#requirement-every-lifecycle-verb-is-authorized-fail-closed
+ */
+ #[NoAdminRequired]
+ #[NoCSRFRequired]
+ public function assign(string $uuid, string $assignee = ''): JSONResponse {
+ return $this->respondWith(
+ verb: fn (): Task => $this->tasks->assign(uuid: $uuid, assignee: $assignee, actor: $this->uid()),
+ uuid: $uuid
+ );
+ }//end assign()
+
+ /**
+ * Reassign a task.
+ *
+ * @param string $uuid The task uuid.
+ * @param string $assignee The new performer reference.
+ *
+ * @return JSONResponse The reassigned task, or a named refusal.
+ *
+ * @spec openspec/changes/flow-task-entity/specs/flow-tasks/spec.md#requirement-every-lifecycle-verb-is-authorized-fail-closed
+ */
+ #[NoAdminRequired]
+ #[NoCSRFRequired]
+ public function reassign(string $uuid, string $assignee = ''): JSONResponse {
+ return $this->respondWith(
+ verb: fn (): Task => $this->tasks->reassign(uuid: $uuid, assignee: $assignee, actor: $this->uid()),
+ uuid: $uuid
+ );
+ }//end reassign()
+
+ /**
+ * Delegate a task, with a mandate.
+ *
+ * @param string $uuid The task uuid.
+ * @param string $delegate The identity taking over.
+ * @param string $mandate The authority relied on.
+ *
+ * @return JSONResponse The delegated task, or a named refusal.
+ *
+ * @spec openspec/changes/flow-task-entity/specs/flow-tasks/spec.md#requirement-the-performer-model-spans-people-groups-agents-and-workers
+ */
+ #[NoAdminRequired]
+ #[NoCSRFRequired]
+ public function delegate(string $uuid, string $delegate = '', string $mandate = ''): JSONResponse {
+ return $this->respondWith(
+ verb: fn (): Task => $this->tasks->delegate(uuid: $uuid, delegate: $delegate, mandate: $mandate, actor: $this->uid()),
+ uuid: $uuid
+ );
+ }//end delegate()
+
+ /**
+ * Resolve a task.
+ *
+ * @param string $uuid The task uuid.
+ * @param string|null $resultText Free-text result.
+ * @param string|null $comment Completion comment.
+ *
+ * @return JSONResponse The resolved task, or a named refusal.
+ *
+ * @spec openspec/changes/flow-task-entity/specs/flow-tasks/spec.md#requirement-every-lifecycle-verb-is-authorized-fail-closed
+ */
+ #[NoAdminRequired]
+ #[NoCSRFRequired]
+ public function resolve(string $uuid, ?string $resultText = null, ?string $comment = null): JSONResponse {
+ return $this->respondWith(
+ verb: fn (): Task => $this->tasks->resolve(uuid: $uuid, resultText: $resultText, comment: $comment, actor: $this->uid()),
+ uuid: $uuid
+ );
+ }//end resolve()
+
+ /**
+ * Complete a task with an explicit outcome.
+ *
+ * @param string $uuid The task uuid.
+ * @param string $outcome The completion outcome.
+ * @param string|null $resultText Free-text result.
+ * @param string|null $comment Completion comment — MANDATORY on a
+ * rejecting or returning outcome.
+ * @param mixed $data The declared form field values, as an object; the
+ * same key the object transition endpoint uses. Absent
+ * for a form-less completion. An undeclared key or a
+ * missing required input is a 400 naming the fields;
+ * a value the subject schema refuses is a 422.
+ *
+ * @return JSONResponse The completed task, or a named refusal.
+ *
+ * @spec openspec/changes/flow-task-entity/specs/flow-tasks/spec.md#requirement-every-lifecycle-verb-is-authorized-fail-closed
+ * @spec openspec/changes/flow-task-forms/specs/flow-task-forms/spec.md#requirement-a-completion-payload-is-validated-by-the-lifecycle-input-allowlist-and-by-nothing-else
+ */
+ #[NoAdminRequired]
+ #[NoCSRFRequired]
+ public function complete(
+ string $uuid,
+ string $outcome = 'done',
+ ?string $resultText = null,
+ ?string $comment = null,
+ mixed $data = null,
+ ): JSONResponse {
+ if ($data !== null && is_array($data) === false) {
+ return new JSONResponse(['error' => 'Field "data" must be an object of field values.'], Http::STATUS_BAD_REQUEST);
+ }
+
+ return $this->respondWith(
+ verb: fn (): Task => $this->completion->complete(
+ uuid: $uuid,
+ outcome: $outcome,
+ resultText: $resultText,
+ comment: $comment,
+ data: ($data ?? []),
+ actor: $this->uid()
+ ),
+ uuid: $uuid
+ );
+ }//end complete()
+
+ /**
+ * Cancel a task.
+ *
+ * @param string $uuid The task uuid.
+ * @param string|null $reason Why, recorded on task and audit.
+ *
+ * @return JSONResponse The terminated task, or a named refusal.
+ *
+ * @spec openspec/changes/flow-task-entity/specs/flow-tasks/spec.md#requirement-every-lifecycle-verb-is-authorized-fail-closed
+ */
+ #[NoAdminRequired]
+ #[NoCSRFRequired]
+ public function cancel(string $uuid, ?string $reason = null): JSONResponse {
+ return $this->respondWith(
+ verb: fn (): Task => $this->tasks->cancel(uuid: $uuid, reason: $reason, actor: $this->uid()),
+ uuid: $uuid
+ );
+ }//end cancel()
+
+ /**
+ * Check or uncheck one checklist item, addressed by id.
+ *
+ * @param string $uuid The task uuid.
+ * @param string $itemId The checklist item id.
+ * @param mixed $checked The new checked value, read as a boolean
+ * ('true'/'false'/1/0 all parse).
+ *
+ * @return JSONResponse The task with the one item changed.
+ *
+ * @spec openspec/changes/flow-task-entity/specs/flow-tasks/spec.md#requirement-a-templated-task-freezes-its-template-at-creation
+ */
+ #[NoAdminRequired]
+ #[NoCSRFRequired]
+ public function checkItem(string $uuid, string $itemId, mixed $checked = 'true'): JSONResponse {
+ $value = filter_var($checked, FILTER_VALIDATE_BOOLEAN);
+
+ return $this->respondWith(
+ verb: fn (): Task => $this->tasks->checkChecklistItem(uuid: $uuid, itemId: $itemId, checked: $value, actor: $this->uid()),
+ uuid: $uuid
+ );
+ }//end checkItem()
+
+ /**
+ * Run a verb and translate its refusals to HTTP, uniformly.
+ *
+ * One translation so no verb can drift: validation 400, with the
+ * offending `fields` and the refusal `kind` beside the message when a
+ * form payload was refused; a subject write the schema or lifecycle
+ * refused 422; denial 403 for a caller who may READ the task and 404 for
+ * one who may not (so a stranger cannot confirm a uuid by probing a
+ * verb); conflict 409 (the current state in the message, per the spec);
+ * absence 404; everything else a LOGGED 500 with a generic message,
+ * never the exception text, which for a database failure carries SQL and
+ * bound parameters.
+ *
+ * @param callable(): Task $verb The service call.
+ * @param int $successStatus The status of the happy path.
+ * @param string|null $uuid The task acted on, for the denial mapping.
+ *
+ * @return JSONResponse The task, or the refusal.
+ *
+ * @spec openspec/changes/flow-task-entity/specs/flow-tasks/spec.md#requirement-every-lifecycle-verb-is-authorized-fail-closed
+ * @spec openspec/changes/flow-task-forms/specs/flow-task-forms/spec.md#requirement-a-validation-failure-names-its-fields-and-completes-nothing
+ */
+ private function respondWith(callable $verb, int $successStatus = Http::STATUS_OK, ?string $uuid = null): JSONResponse {
+ try {
+ $task = $verb();
+
+ return new JSONResponse(
+ $this->inbox->row(task: $task, subjects: [], now: $this->temporal->now()),
+ $successStatus
+ );
+ } catch (TaskFormRefusedException $refused) {
+ // The form contract's refusal: the fields machine-readable next
+ // to the message, and the kind, so a client can flag each field
+ // and tell an undeclared key from a missing required input.
+ return new JSONResponse(
+ [
+ 'error' => $refused->getMessage(),
+ 'fields' => $refused->getFields(),
+ 'kind' => $refused->getKind(),
+ ],
+ Http::STATUS_BAD_REQUEST
+ );
+ } catch (TaskValidationException $refused) {
+ return new JSONResponse(['error' => $refused->getMessage()], Http::STATUS_BAD_REQUEST);
+ } catch (TaskSubjectWriteRefusedException $refused) {
+ // The payload passed the form and the SUBJECT refused it, on the
+ // ordinary save path: not malformed, not completed.
+ return new JSONResponse(['error' => $refused->getMessage()], Http::STATUS_UNPROCESSABLE_ENTITY);
+ } catch (TaskAccessDeniedException $denied) {
+ if ($uuid !== null && $this->mayReadUuid(uuid: $uuid) === false) {
+ return new JSONResponse(['error' => 'No such task'], Http::STATUS_NOT_FOUND);
+ }
+
+ return new JSONResponse(['error' => $denied->getMessage()], Http::STATUS_FORBIDDEN);
+ } catch (TaskConflictException $conflict) {
+ return new JSONResponse(['error' => $conflict->getMessage()], Http::STATUS_CONFLICT);
+ } catch (DoesNotExistException) {
+ return new JSONResponse(['error' => 'No such task'], Http::STATUS_NOT_FOUND);
+ } catch (Throwable $failure) {
+ $this->logger?->error(
+ '[TaskController] Task operation failed: ' . $failure->getMessage(),
+ ['uuid' => $uuid, 'exception' => $failure]
+ );
+
+ return new JSONResponse(['error' => 'The task operation failed. The details are in the server log.'], Http::STATUS_INTERNAL_SERVER_ERROR);
+ }//end try
+ }//end respondWith()
+
+ /**
+ * Whether the caller may read the task with this uuid, fail-closed.
+ *
+ * @param string $uuid The task uuid.
+ *
+ * @return boolean False when absent, invisible or undeterminable.
+ */
+ private function mayReadUuid(string $uuid): bool {
+ try {
+ return $this->authorization->mayRead(task: $this->tasks->get(uuid: $uuid), uid: $this->uid());
+ } catch (Throwable) {
+ return false;
+ }
+ }//end mayReadUuid()
+
+ /**
+ * The acting identity, or null without a session.
+ *
+ * @return string|null The uid.
+ */
+ private function uid(): ?string {
+ $user = $this->userSession->getUser();
+ if ($user === null) {
+ return null;
+ }
+
+ return $user->getUID();
+ }//end uid()
+
+ /**
+ * The caller's group ids — empty without a backend, which scopes.
+ *
+ * @param string $uid The caller.
+ *
+ * @return array The group ids.
+ */
+ private function groupIds(string $uid): array {
+ $user = $this->userSession->getUser();
+ if ($this->groupManager === null || $user === null || $user->getUID() !== $uid) {
+ return [];
+ }
+
+ try {
+ return $this->groupManager->getUserGroupIds($user);
+ } catch (Throwable) {
+ return [];
+ }
+ }//end groupIds()
+
+ /**
+ * Whether the caller is an administrator — false without a backend.
+ *
+ * @param string $uid The caller.
+ *
+ * @return boolean True only when the backend affirms it.
+ */
+ private function isAdmin(string $uid): bool {
+ if ($this->groupManager === null) {
+ return false;
+ }
+
+ try {
+ return $this->groupManager->isAdmin($uid);
+ } catch (Throwable) {
+ return false;
+ }
+ }//end isAdmin()
+
+ /**
+ * The request body, the way the framework already parsed it.
+ *
+ * @return array The parameters.
+ */
+ private function body(): array {
+ $params = $this->request->getParams();
+ // Route bookkeeping is not task data.
+ unset($params['_route'], $params['uuid']);
+
+ return $params;
+ }//end body()
+}//end class
diff --git a/lib/Controller/TasksController.php b/lib/Controller/TasksController.php
index d11e6cdd60..be12bd21a1 100644
--- a/lib/Controller/TasksController.php
+++ b/lib/Controller/TasksController.php
@@ -25,13 +25,22 @@
namespace OCA\OpenRegister\Controller;
use Exception;
+use OCA\OpenRegister\Db\TaskInboxCriteria;
use OCA\OpenRegister\Exception\NoVtodoCalendarException;
+use OCA\OpenRegister\Exception\TaskValidationException;
use OCA\OpenRegister\Service\ObjectService;
+use OCA\OpenRegister\Service\Task\TaskInboxService;
+use OCA\OpenRegister\Service\Task\TaskState;
+use OCA\OpenRegister\Service\Task\TaskTemporalProjection;
use OCA\OpenRegister\Service\TaskService;
use OCP\AppFramework\Controller;
use OCP\AppFramework\Db\DoesNotExistException;
+use OCP\AppFramework\Http;
use OCP\AppFramework\Http\JSONResponse;
+use OCP\IGroupManager;
use OCP\IRequest;
+use OCP\IUserSession;
+use Throwable;
/**
* TasksController handles task operations for objects in registers.
@@ -41,6 +50,12 @@
*
* @category Controller
* @package OCA\OpenRegister\Controller
+ *
+ * @SuppressWarnings(PHPMD.CouplingBetweenObjects) The controller now serves
+ * two stores: the CalDAV leaf for standalone VTODOs and the engine inbox for
+ * the aggregate, plus the three refusal shapes each can produce.
+ * @SuppressWarnings(PHPMD.StaticAccess) TaskState is the stateless published
+ * status mapping.
*/
class TasksController extends Controller {
@@ -65,6 +80,14 @@ class TasksController extends Controller {
* @param IRequest $request HTTP request object
* @param TaskService $taskService Task service for VTODO operations
* @param ObjectService $objectService Object service for object validation
+ * @param TaskInboxService|null $inbox The engine inbox the aggregate answers from;
+ * without it the aggregate refuses (401), never
+ * falls back to walking calendars
+ * @param IUserSession|null $userSession Names the caller for the aggregate
+ * @param TaskTemporalProjection|null $temporal The one overdue derivation's clock
+ * @param IGroupManager|null $groupManager Resolves the caller's groups and admin
+ * status; absent means no groups and not
+ * admin, which scopes rather than widens
*
* @return void
*/
@@ -73,6 +96,10 @@ public function __construct(
IRequest $request,
TaskService $taskService,
ObjectService $objectService,
+ private readonly ?TaskInboxService $inbox = null,
+ private readonly ?IUserSession $userSession = null,
+ private readonly ?TaskTemporalProjection $temporal = null,
+ private readonly ?IGroupManager $groupManager = null,
) {
parent::__construct(appName: $appName, request: $request);
@@ -81,53 +108,154 @@ public function __construct(
}//end __construct()
/**
- * Get all tasks for the current user across all calendars.
+ * The user-wide task aggregate: what the session user owes, from the
+ * engine inbox.
+ *
+ * Answered by TaskInboxService, never by walking calendars: visibility,
+ * filter, sort, page and total are the query's, so the total cannot
+ * reveal a task the caller may not see and a page cannot silently drop
+ * rows. The caller is resolved from the session, never from a request
+ * parameter, so no parameter can widen the read to another user.
*
- * Returns all CalDAV VTODOs from the user's VTODO-supporting calendars,
- * optionally filtered by status or assignee.
+ * `assignee` is NO LONGER accepted as a filter: the aggregate is already
+ * scoped to the caller, and the free-text description prose it used to
+ * match no longer exists. `status` (legacy) and `state` both name a
+ * lifecycle state through the published TaskState mapping; an unmapped
+ * value is refused with 400 rather than silently ignored.
*
- * Authorization: this endpoint is anchored to the current session user.
- * TaskService::getAllUserTasks() resolves the calendar set from
- * IUserSession::getUser()->getUID() (principals/users/); the request
- * never controls which user's calendars are read. The optional `assignee`
- * request parameter is a free-text filter applied to each task's
- * description ATTENDEE field within the caller's own task list — it is
- * NOT an identity claim and cannot be used to read another user's tasks.
- * Per ADR-005 Rule 3, no per-object authorization anchor is needed beyond
- * the session-user binding already enforced in the service.
+ * Authorization: session-scoped (ADR-005 Rule 3), enforced in the inbox
+ * query's WHERE clause.
*
- * @return JSONResponse JSON response with all user tasks
+ * @return JSONResponse The page: results, total, limit, offset
*
* @NoAdminRequired
* @NoCSRFRequired
- * @no-admin-idor-exempt Session-scoped list: TaskService::getAllUserTasks resolves the calendar set from the IUserSession UID;
- * the assignee param filters within the caller's own tasks, not an identity claim.
*
- * @spec openspec/changes/retrofit-2026-05-24-b-ctrl-misc/tasks.md#task-2
+ * @no-admin-idor-exempt Session-scoped list: TaskInboxService::inbox() narrows visibility to the
+ * IUserSession UID inside the query; no request parameter names another user.
+ *
+ * @spec openspec/changes/flow-task-inbox-projections/specs/object-interactions/spec.md#requirement-user-wide-task-aggregate-endpoint
*/
public function allUserTasks(): JSONResponse {
+ $uid = $this->userSession?->getUser()?->getUID();
+ if ($this->inbox === null || $uid === null || trim($uid) === '') {
+ return new JSONResponse(data: ['error' => 'No session'], statusCode: Http::STATUS_UNAUTHORIZED);
+ }
+
+ $limit = min((int)($this->request->getParam('_limit') ?? $this->request->getParam('limit') ?? 50), 200);
+ $offset = (int)($this->request->getParam('_offset') ?? $this->request->getParam('offset') ?? 0);
+ $scope = (string)($this->request->getParam('scope') ?? TaskInboxCriteria::SCOPE_ALL);
+
try {
- $status = $this->request->getParam('status');
- $limit = min((int)($this->request->getParam('_limit') ?? $this->request->getParam('limit') ?? 50), 200);
- $offset = (int)($this->request->getParam('_offset') ?? $this->request->getParam('offset') ?? 0);
- $assignee = $this->request->getParam('assignee');
-
- $result = $this->taskService->getAllUserTasks(
- status: $status,
- limit: $limit,
- offset: $offset,
- assignee: $assignee
+ $states = $this->requestedStates();
+ } catch (TaskValidationException $refused) {
+ return new JSONResponse(data: ['error' => $refused->getMessage()], statusCode: Http::STATUS_BAD_REQUEST);
+ }
+
+ $overdueAt = null;
+ $overdue = $this->request->getParam('overdue');
+ if ($overdue !== null && filter_var($overdue, FILTER_VALIDATE_BOOLEAN) === true) {
+ $overdueAt = ($this->temporal ?? new TaskTemporalProjection())->now();
+ }
+
+ $sort = (string)($this->request->getParam('sort') ?? TaskInboxCriteria::SORT_DUE);
+
+ try {
+ $criteria = new TaskInboxCriteria(
+ uid: $uid,
+ groupIds: $this->groupIds(),
+ isAdmin: $this->isAdmin(uid: $uid),
+ scope: $scope,
+ states: $states,
+ isTerminal: $this->requestedTerminal(),
+ overdueAt: $overdueAt,
+ sort: ltrim($sort, '-'),
+ sortDescending: str_starts_with($sort, '-'),
);
- return new JSONResponse(data: $result);
- } catch (Exception $e) {
+ return new JSONResponse(data: $this->inbox->inbox(criteria: $criteria, limit: $limit, offset: $offset));
+ } catch (Throwable $failure) {
return new JSONResponse(
- data: ['error' => $e->getMessage()],
- statusCode: 500
+ data: ['error' => $failure->getMessage()],
+ statusCode: Http::STATUS_INTERNAL_SERVER_ERROR
);
}//end try
}//end allUserTasks()
+ /**
+ * The lifecycle states the request filters on, through the published mapping.
+ *
+ * @return array Canonical CMMN states; empty means no state filter
+ *
+ * @throws TaskValidationException When a value is in no known vocabulary
+ *
+ * @spec openspec/changes/flow-task-inbox-projections/specs/object-interactions/spec.md#requirement-user-wide-task-aggregate-endpoint
+ */
+ private function requestedStates(): array {
+ $raw = ($this->request->getParam('state') ?? $this->request->getParam('status'));
+ if (is_string($raw) === false || trim($raw) === '') {
+ return [];
+ }
+
+ $states = [];
+ foreach (array_filter(array_map('trim', explode(',', $raw))) as $value) {
+ $states[] = TaskState::normalise(value: $value)['state'];
+ }
+
+ return array_values(array_unique($states));
+ }//end requestedStates()
+
+ /**
+ * The terminality filter, when the request names one.
+ *
+ * @return bool|null True/false to restrict; null for both
+ */
+ private function requestedTerminal(): ?bool {
+ $raw = $this->request->getParam('isTerminal');
+ if ($raw === null) {
+ return null;
+ }
+
+ return filter_var($raw, FILTER_VALIDATE_BOOLEAN);
+ }//end requestedTerminal()
+
+ /**
+ * The caller's group ids, or none without a backend (which scopes).
+ *
+ * @return array The group ids
+ */
+ private function groupIds(): array {
+ $user = $this->userSession?->getUser();
+ if ($this->groupManager === null || $user === null) {
+ return [];
+ }
+
+ try {
+ return $this->groupManager->getUserGroupIds($user);
+ } catch (Throwable) {
+ return [];
+ }
+ }//end groupIds()
+
+ /**
+ * Whether the caller is an administrator; false without a backend.
+ *
+ * @param string $uid The caller
+ *
+ * @return bool True only when the backend affirms it
+ */
+ private function isAdmin(string $uid): bool {
+ if ($this->groupManager === null) {
+ return false;
+ }
+
+ try {
+ return $this->groupManager->isAdmin($uid);
+ } catch (Throwable) {
+ return false;
+ }
+ }//end isAdmin()
+
/**
* List all tasks linked to a specific object.
*
@@ -363,8 +491,8 @@ private function validateObject(
string $schema,
string $id,
): ?\OCA\OpenRegister\Db\ObjectEntity {
- $this->objectService->setSchema($schema);
$this->objectService->setRegister($register);
+ $this->objectService->setSchema($schema);
$this->objectService->setObject($id);
return $this->objectService->getObject();
diff --git a/lib/Controller/TimeTrackerLinksController.php b/lib/Controller/TimeTrackerLinksController.php
index 4a66ea980e..b387f525f1 100644
--- a/lib/Controller/TimeTrackerLinksController.php
+++ b/lib/Controller/TimeTrackerLinksController.php
@@ -314,8 +314,8 @@ public function available(): JSONResponse {
* returns for other reasons, which the caller could no longer tell apart.
*/
private function validateObject(string $register, string $schema, string $id): ?ObjectEntity {
- $this->objectService->setSchema($schema);
$this->objectService->setRegister($register);
+ $this->objectService->setSchema($schema);
$this->objectService->setObject($id);
return $this->objectService->getObject();
diff --git a/lib/Controller/XwikiLinksController.php b/lib/Controller/XwikiLinksController.php
index 6ae0b1e51a..80b2663fda 100644
--- a/lib/Controller/XwikiLinksController.php
+++ b/lib/Controller/XwikiLinksController.php
@@ -355,8 +355,8 @@ public function search(): JSONResponse {
* returns for other reasons, which the caller could no longer tell apart.
*/
private function validateObject(string $register, string $schema, string $id): ?ObjectEntity {
- $this->objectService->setSchema($schema);
$this->objectService->setRegister($register);
+ $this->objectService->setSchema($schema);
$this->objectService->setObject($id);
return $this->objectService->getObject();
diff --git a/lib/Dav/TaskVtodoWriteBackPlugin.php b/lib/Dav/TaskVtodoWriteBackPlugin.php
new file mode 100644
index 0000000000..941b972b02
--- /dev/null
+++ b/lib/Dav/TaskVtodoWriteBackPlugin.php
@@ -0,0 +1,322 @@
+` and loaded
+ * by apps/dav's PluginManager. It acts only on VTODOs carrying
+ * `X-OPENREGISTER-TASK`; every other calendar object passes untouched. What
+ * it does with a projected VTODO is hand the document to the ONE gate: an
+ * accepted verb advances the engine and the stored document becomes the
+ * engine's fresh rendering; a refusal becomes a DAV 403, so there is no
+ * window in which the user's client believes the task is done
+ * (flow-task-inbox-projections, design D-6).
+ *
+ * Creating a VTODO that carries a task identity through DAV is refused: only
+ * the projector creates projected VTODOs, so a VTODO carrying an engine task
+ * identity always corresponds to a task the engine authorized into
+ * existence. Deleting one is refused too, with the reason: a task is not
+ * cancelled by removing the reminder of it.
+ *
+ * SPDX-FileCopyrightText: 2026 Conduction B.V.
+ * SPDX-License-Identifier: EUPL-1.2
+ *
+ * @category Dav
+ * @package OCA\OpenRegister\Dav
+ *
+ * @author Conduction Development Team
+ * @copyright 2026 Conduction B.V.
+ * @license EUPL-1.2 https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
+ *
+ * @link https://OpenRegister.app
+ *
+ * @spec openspec/changes/flow-task-inbox-projections/specs/flow-task-projections/spec.md#requirement-an-unauthorized-write-back-is-undone-and-explained
+ */
+
+declare(strict_types=1);
+
+namespace OCA\OpenRegister\Dav;
+
+use OCA\OpenRegister\Exception\TaskAccessDeniedException;
+use OCA\OpenRegister\Exception\TaskConflictException;
+use OCA\OpenRegister\Exception\TaskValidationException;
+use OCA\OpenRegister\Service\Task\TaskVtodoWriteBackGate;
+use OCP\AppFramework\Db\DoesNotExistException;
+use Psr\Log\LoggerInterface;
+use Sabre\DAV\Exception\Forbidden;
+use Sabre\DAV\ICollection;
+use Sabre\DAV\INode;
+use Sabre\DAV\Server;
+use Sabre\DAV\ServerPlugin;
+use Throwable;
+
+/**
+ * Sabre plugin: refuse in-band, or store the engine's rendering.
+ *
+ * @spec openspec/changes/flow-task-inbox-projections/specs/flow-task-projections/spec.md#requirement-an-unauthorized-write-back-is-undone-and-explained
+ */
+class TaskVtodoWriteBackPlugin extends ServerPlugin {
+
+ /**
+ * The DAV path prefix calendar objects live under.
+ */
+ private const CALENDAR_PREFIX = 'calendars/';
+
+ /**
+ * The principal prefix a user's DAV identity carries.
+ */
+ private const PRINCIPAL_PREFIX = 'principals/users/';
+
+ /**
+ * The Sabre server, once initialised.
+ *
+ * @var Server|null
+ */
+ private ?Server $server = null;
+
+ /**
+ * Constructor.
+ *
+ * @param TaskVtodoWriteBackGate $gate The one gate.
+ * @param LoggerInterface $logger Failure reporting.
+ */
+ public function __construct(
+ private readonly TaskVtodoWriteBackGate $gate,
+ private readonly LoggerInterface $logger,
+ ) {
+
+ }//end __construct()
+
+ /**
+ * Subscribe to the write hooks.
+ *
+ * Priority 90: after Sabre's own CalDAV validation (which runs at 100
+ * and normalises the document), before the write reaches the backend.
+ *
+ * @param Server $server The Sabre server.
+ *
+ * @return void
+ *
+ * @spec openspec/changes/flow-task-inbox-projections/specs/flow-task-projections/spec.md#requirement-an-unauthorized-write-back-is-undone-and-explained
+ */
+ public function initialize(Server $server): void {
+ $this->server = $server;
+ $server->on('beforeWriteContent', [$this, 'beforeWriteContent'], 90);
+ $server->on('beforeCreateFile', [$this, 'beforeCreateFile'], 90);
+ $server->on('beforeUnbind', [$this, 'beforeUnbind'], 90);
+ }//end initialize()
+
+ /**
+ * The plugin's name, for Sabre's plugin registry.
+ *
+ * @return string The name.
+ *
+ * @spec openspec/changes/flow-task-inbox-projections/specs/flow-task-projections/spec.md#requirement-an-unauthorized-write-back-is-undone-and-explained
+ */
+ public function getPluginName(): string {
+ return 'openregister-task-write-back';
+ }//end getPluginName()
+
+ /**
+ * An existing calendar object is being overwritten.
+ *
+ * @param string $path The DAV path.
+ * @param INode $node The node being written.
+ * @param resource|string|null $data The incoming body, by reference.
+ * @param bool $modified Set to true when the body is replaced, by reference.
+ *
+ * @return void
+ *
+ * @throws Forbidden When the gate refuses.
+ *
+ * @SuppressWarnings(PHPMD.UnusedFormalParameter) The node is Sabre's hook signature.
+ *
+ * @spec openspec/changes/flow-task-inbox-projections/specs/flow-task-projections/spec.md#requirement-an-unauthorized-write-back-is-undone-and-explained
+ */
+ public function beforeWriteContent(string $path, INode $node, &$data, &$modified): void {
+ if ($this->isCalendarPath(path: $path) === false) {
+ return;
+ }
+
+ $body = $this->bodyOf(data: $data);
+ if ($body === null || $this->gate->isProjected(calendarData: $body) === false) {
+ return;
+ }
+
+ $replacement = $this->guard(
+ call: fn (): ?string => $this->gate->handleWrite(calendarData: $body, actor: $this->actor())
+ );
+
+ if ($replacement !== null) {
+ $data = $replacement;
+ $modified = true;
+ }
+ }//end beforeWriteContent()
+
+ /**
+ * A new calendar object is being created.
+ *
+ * @param string $path The DAV path.
+ * @param resource|string|null $data The incoming body, by reference.
+ * @param ICollection $parent The calendar.
+ * @param bool $modified Unused: a refusal replaces nothing.
+ *
+ * @return void
+ *
+ * @throws Forbidden When the body forges a task identity.
+ *
+ * @SuppressWarnings(PHPMD.UnusedFormalParameter) The parent and flag are Sabre's hook signature.
+ *
+ * @spec openspec/changes/flow-task-inbox-projections/specs/object-interactions/spec.md#requirement-tasks-on-objects-via-caldav-vtodo
+ */
+ public function beforeCreateFile(string $path, &$data, ICollection $parent, &$modified): void {
+ if ($this->isCalendarPath(path: $path) === false) {
+ return;
+ }
+
+ $body = $this->bodyOf(data: $data);
+ if ($body === null || $this->gate->isProjected(calendarData: $body) === false) {
+ return;
+ }
+
+ $this->logger->warning(
+ '[TaskVtodoWriteBackPlugin] Refused a calendar object that forges an engine task identity.',
+ ['path' => $path, 'actor' => $this->actor()]
+ );
+
+ throw new Forbidden('A calendar entry cannot create an engine task. Only OpenRegister writes task entries into a calendar.');
+ }//end beforeCreateFile()
+
+ /**
+ * A calendar object is being deleted.
+ *
+ * @param string $path The DAV path.
+ *
+ * @return void
+ *
+ * @throws Forbidden When the object is a projected VTODO.
+ *
+ * @spec openspec/changes/flow-task-inbox-projections/specs/object-interactions/spec.md#requirement-tasks-on-objects-via-caldav-vtodo
+ */
+ public function beforeUnbind(string $path): void {
+ if ($this->isCalendarPath(path: $path) === false || $this->server === null) {
+ return;
+ }
+
+ try {
+ $node = $this->server->tree->getNodeForPath($path);
+ } catch (Throwable) {
+ return;
+ }
+
+ if (method_exists($node, 'get') === false) {
+ return;
+ }
+
+ $body = $this->bodyOf(data: $node->get());
+ if ($body === null || $this->gate->isProjected(calendarData: $body) === false) {
+ return;
+ }
+
+ throw new Forbidden('This entry is an OpenRegister task. Complete or cancel the task instead of deleting its calendar entry.');
+ }//end beforeUnbind()
+
+ /**
+ * Run the gate, translating every refusal into a DAV 403 that names the reason.
+ *
+ * @param callable(): ?string $call The gate call.
+ *
+ * @return string|null The gate's replacement document, when any.
+ *
+ * @throws Forbidden On every refusal, including an unknown task and an unexpected failure (fail closed).
+ *
+ * @spec openspec/changes/flow-task-inbox-projections/specs/flow-task-projections/spec.md#requirement-an-unauthorized-write-back-is-undone-and-explained
+ */
+ private function guard(callable $call): ?string {
+ try {
+ return $call();
+ } catch (TaskAccessDeniedException | TaskConflictException | TaskValidationException $refused) {
+ throw new Forbidden('OpenRegister refused this change: ' . $refused->getMessage(), 0, $refused);
+ } catch (DoesNotExistException $missing) {
+ throw new Forbidden('OpenRegister refused this change: the entry names a task that does not exist.', 0, $missing);
+ } catch (Throwable $failure) {
+ $this->logger->error(
+ '[TaskVtodoWriteBackPlugin] Gate failure; the write is refused rather than applied unchecked: ' . $failure->getMessage(),
+ ['exception' => $failure]
+ );
+ throw new Forbidden('OpenRegister could not verify this change, so it was not applied.', 0, $failure);
+ }//end try
+ }//end guard()
+
+ /**
+ * The acting uid, from the authenticated DAV principal.
+ *
+ * @return string|null The uid, or null when there is none (which the gate denies).
+ *
+ * @spec openspec/changes/flow-task-inbox-projections/specs/flow-task-projections/spec.md#requirement-ticking-off-the-vtodo-completes-the-engine-task-through-authorization
+ */
+ private function actor(): ?string {
+ if ($this->server === null) {
+ return null;
+ }
+
+ try {
+ $auth = $this->server->getPlugin('auth');
+ if ($auth === null || method_exists($auth, 'getCurrentPrincipal') === false) {
+ return null;
+ }
+
+ $principal = (string)$auth->getCurrentPrincipal();
+ } catch (Throwable) {
+ return null;
+ }
+
+ if (str_starts_with($principal, self::PRINCIPAL_PREFIX) === false) {
+ return null;
+ }
+
+ $uid = substr($principal, strlen(self::PRINCIPAL_PREFIX));
+ if ($uid === '') {
+ return null;
+ }
+
+ return $uid;
+ }//end actor()
+
+ /**
+ * The body as a string, whatever Sabre handed over.
+ *
+ * @param mixed $data A string, a stream, or null.
+ *
+ * @return string|null The body, or null when unreadable.
+ */
+ private function bodyOf(mixed $data): ?string {
+ if (is_string($data) === true) {
+ return $data;
+ }
+
+ if (is_resource($data) === true) {
+ $contents = stream_get_contents($data);
+ rewind($data);
+ if ($contents === false) {
+ return null;
+ }
+
+ return $contents;
+ }
+
+ return null;
+ }//end bodyOf()
+
+ /**
+ * Whether a DAV path addresses a calendar object.
+ *
+ * @param string $path The DAV path.
+ *
+ * @return bool True under `calendars/`.
+ */
+ private function isCalendarPath(string $path): bool {
+ return str_starts_with(ltrim($path, '/'), self::CALENDAR_PREFIX);
+ }//end isCalendarPath()
+}//end class
diff --git a/lib/Db/ApprovalChain.php b/lib/Db/ApprovalChain.php
deleted file mode 100644
index b4c7a4fd9f..0000000000
--- a/lib/Db/ApprovalChain.php
+++ /dev/null
@@ -1,185 +0,0 @@
-
- * @copyright 2024 Conduction B.V.
- * @license EUPL-1.2 https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
- *
- * @version GIT:
- *
- * @link https://OpenRegister.app
- */
-
-namespace OCA\OpenRegister\Db;
-
-use DateTime;
-use JsonSerializable;
-use OCP\AppFramework\Db\Entity;
-
-/**
- * Entity class representing a multi-step approval chain configuration.
- *
- * @method string|null getUuid()
- * @method void setUuid(?string $uuid)
- * @method string|null getName()
- * @method void setName(?string $name)
- * @method int|null getSchemaId()
- * @method void setSchemaId(?int $schemaId)
- * @method string|null getStatusField()
- * @method void setStatusField(?string $statusField)
- * @method string|null getSteps()
- * @method void setSteps(?string $steps)
- * @method bool getEnabled()
- * @method void setEnabled(bool $enabled)
- * @method DateTime|null getCreated()
- * @method void setCreated(?DateTime $created)
- * @method DateTime|null getUpdated()
- * @method void setUpdated(?DateTime $updated)
- *
- * @psalm-suppress PropertyNotSetInConstructor
- */
-class ApprovalChain extends Entity implements JsonSerializable {
-
- /**
- * The uuid.
- *
- * @var string|null
- */
- protected ?string $uuid = null;
-
- /**
- * The name.
- *
- * @var string|null
- */
- protected ?string $name = null;
-
- /**
- * The schema id.
- *
- * @var integer|null
- */
- protected ?int $schemaId = null;
-
- /**
- * The status field.
- *
- * @var string|null
- */
- protected ?string $statusField = 'status';
-
- /**
- * The steps.
- *
- * @var string|null
- */
- protected ?string $steps = null;
-
- /**
- * The enabled.
- *
- * @var boolean
- */
- protected bool $enabled = true;
-
- /**
- * The created.
- *
- * @var DateTime|null
- */
- protected ?DateTime $created = null;
-
- /**
- * The updated.
- *
- * @var DateTime|null
- */
- protected ?DateTime $updated = null;
-
- /**
- * Constructor for ApprovalChain entity.
- */
- public function __construct() {
- $this->addType(fieldName: 'uuid', type: 'string');
- $this->addType(fieldName: 'name', type: 'string');
- $this->addType(fieldName: 'schemaId', type: 'integer');
- $this->addType(fieldName: 'statusField', type: 'string');
- $this->addType(fieldName: 'steps', type: 'string');
- $this->addType(fieldName: 'enabled', type: 'boolean');
- $this->addType(fieldName: 'created', type: 'datetime');
- $this->addType(fieldName: 'updated', type: 'datetime');
- }//end __construct()
-
- /**
- * Get the steps as a decoded array.
- *
- * @return array>
- */
- public function getStepsArray(): array {
- if ($this->steps === null) {
- return [];
- }
-
- return json_decode($this->steps, true) ?? [];
- }//end getStepsArray()
-
- /**
- * Hydrate entity from array.
- *
- * @param array $object Data to hydrate from
- *
- * @return self
- */
- public function hydrate(array $object): self {
- $fields = [
- 'uuid',
- 'name',
- 'schemaId',
- 'statusField',
- 'steps',
- 'enabled',
- 'created',
- 'updated',
- ];
-
- foreach ($object as $key => $value) {
- if (in_array($key, $fields, true) === true) {
- $setter = 'set' . ucfirst($key);
- if ($key === 'steps' && is_array($value) === true) {
- $value = json_encode($value);
- }
-
- $this->$setter($value);
- }
- }
-
- return $this;
- }//end hydrate()
-
- /**
- * Serialize to JSON.
- *
- * @return array
- */
- public function jsonSerialize(): array {
- return [
- 'id' => $this->id,
- 'uuid' => $this->uuid,
- 'name' => $this->name,
- 'schemaId' => $this->schemaId,
- 'statusField' => $this->statusField,
- 'steps' => $this->getStepsArray(),
- 'enabled' => $this->enabled,
- 'created' => $this->created?->format('c'),
- 'updated' => $this->updated?->format('c'),
- ];
- }//end jsonSerialize()
-}//end class
diff --git a/lib/Db/ApprovalChainMapper.php b/lib/Db/ApprovalChainMapper.php
deleted file mode 100644
index f36f87caa4..0000000000
--- a/lib/Db/ApprovalChainMapper.php
+++ /dev/null
@@ -1,189 +0,0 @@
-
- * @copyright 2024 Conduction B.V.
- * @license EUPL-1.2 https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
- *
- * @version GIT:
- *
- * @link https://OpenRegister.app
- */
-
-namespace OCA\OpenRegister\Db;
-
-use DateTime;
-use OCP\AppFramework\Db\QBMapper;
-use OCP\DB\QueryBuilder\IQueryBuilder;
-use OCP\IDBConnection;
-use Symfony\Component\Uid\Uuid;
-
-/**
- * Mapper for ApprovalChain entities.
- *
- * @extends QBMapper
- */
-class ApprovalChainMapper extends QBMapper {
- /**
- * Constructor for ApprovalChainMapper.
- *
- * @param IDBConnection $db Database connection
- */
- public function __construct(IDBConnection $db) {
- parent::__construct(
- db: $db,
- tableName: 'openregister_approval_chains',
- entityClass: ApprovalChain::class
- );
- }//end __construct()
-
- /**
- * Find an approval chain by ID.
- *
- * @param int $id Chain ID
- *
- * @return ApprovalChain
- */
- public function find(int $id): ApprovalChain {
- $qb = $this->db->getQueryBuilder();
-
- $qb->select('*')
- ->from($this->getTableName())
- ->where(
- $qb->expr()->eq('id', $qb->createNamedParameter(value: $id, type: IQueryBuilder::PARAM_INT))
- );
-
- return $this->findEntity(query: $qb);
- }//end find()
-
- /**
- * Find all approval chains.
- *
- * @param int|null $limit Maximum results
- * @param int|null $offset Offset for pagination
- *
- * @return array
- */
- public function findAll(?int $limit = null, ?int $offset = null): array {
- $qb = $this->db->getQueryBuilder();
-
- $qb->select('*')
- ->from($this->getTableName())
- ->orderBy('name', 'ASC');
-
- if ($limit !== null) {
- $qb->setMaxResults($limit);
- }
-
- if ($offset !== null) {
- $qb->setFirstResult($offset);
- }
-
- return $this->findEntities(query: $qb);
- }//end findAll()
-
- /**
- * Find approval chains by schema ID.
- *
- * @param int $schemaId Schema ID
- *
- * @return array
- */
- public function findBySchema(int $schemaId): array {
- $qb = $this->db->getQueryBuilder();
-
- $qb->select('*')
- ->from($this->getTableName())
- ->where(
- $qb->expr()->eq(
- 'schema_id',
- $qb->createNamedParameter(value: $schemaId, type: IQueryBuilder::PARAM_INT)
- )
- )
- ->orderBy('name', 'ASC');
-
- return $this->findEntities(query: $qb);
- }//end findBySchema()
-
- /**
- * Find the chain provisioned for a schema under a given declarative chain
- * key (the `x-openregister-approval-chains` entry name, stored as `name`).
- *
- * @param int $schemaId Schema ID.
- * @param string $name Chain key / name.
- *
- * @return ApprovalChain|null The matching chain, or null when none exists yet.
- *
- * @spec openspec/specs/approval-workflow/spec.md
- */
- public function findBySchemaAndName(int $schemaId, string $name): ?ApprovalChain {
- $qb = $this->db->getQueryBuilder();
-
- $qb->select('*')
- ->from($this->getTableName())
- ->where(
- $qb->expr()->eq(
- 'schema_id',
- $qb->createNamedParameter(value: $schemaId, type: IQueryBuilder::PARAM_INT)
- )
- )
- ->andWhere(
- $qb->expr()->eq('name', $qb->createNamedParameter($name))
- )
- ->setMaxResults(1);
-
- try {
- return $this->findEntity(query: $qb);
- } catch (\OCP\AppFramework\Db\DoesNotExistException $e) {
- return null;
- } catch (\Throwable $e) {
- return null;
- }
- }//end findBySchemaAndName()
-
- /**
- * Create an approval chain from an array.
- *
- * @param array $data Chain data
- *
- * @return ApprovalChain
- */
- public function createFromArray(array $data): ApprovalChain {
- $chain = new ApprovalChain();
- $chain->hydrate($data);
-
- if ($chain->getUuid() === null) {
- $chain->setUuid(Uuid::v4()->toRfc4122());
- }
-
- $now = new DateTime();
- $chain->setCreated($now);
- $chain->setUpdated($now);
-
- return $this->insert(entity: $chain);
- }//end createFromArray()
-
- /**
- * Update an approval chain from an array.
- *
- * @param int $id Chain ID
- * @param array $data Updated data
- *
- * @return ApprovalChain
- */
- public function updateFromArray(int $id, array $data): ApprovalChain {
- $chain = $this->find(id: $id);
- $chain->hydrate($data);
- $chain->setUpdated(new DateTime());
-
- return $this->update(entity: $chain);
- }//end updateFromArray()
-}//end class
diff --git a/lib/Db/ApprovalStep.php b/lib/Db/ApprovalStep.php
deleted file mode 100644
index 73c8f82b0f..0000000000
--- a/lib/Db/ApprovalStep.php
+++ /dev/null
@@ -1,208 +0,0 @@
-
- * @copyright 2024 Conduction B.V.
- * @license EUPL-1.2 https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
- *
- * @version GIT:
- *
- * @link https://OpenRegister.app
- */
-
-namespace OCA\OpenRegister\Db;
-
-use DateTime;
-use JsonSerializable;
-use OCP\AppFramework\Db\Entity;
-
-/**
- * Entity class representing a single approval step for an object in a chain.
- *
- * @method string|null getUuid()
- * @method void setUuid(?string $uuid)
- * @method int|null getChainId()
- * @method void setChainId(?int $chainId)
- * @method string|null getObjectUuid()
- * @method void setObjectUuid(?string $objectUuid)
- * @method int getStepOrder()
- * @method void setStepOrder(int $stepOrder)
- * @method string|null getRole()
- * @method void setRole(?string $role)
- * @method string|null getStatus()
- * @method void setStatus(?string $status)
- * @method string|null getDecidedBy()
- * @method void setDecidedBy(?string $decidedBy)
- * @method string|null getComment()
- * @method void setComment(?string $comment)
- * @method DateTime|null getDecidedAt()
- * @method void setDecidedAt(?DateTime $decidedAt)
- * @method DateTime|null getCreated()
- * @method void setCreated(?DateTime $created)
- * @method string|null getRequesterId()
- * @method void setRequesterId(?string $requesterId)
- *
- * @psalm-suppress PropertyNotSetInConstructor
- */
-class ApprovalStep extends Entity implements JsonSerializable {
-
- /**
- * The uuid.
- *
- * @var string|null
- */
- protected ?string $uuid = null;
-
- /**
- * The chain id.
- *
- * @var integer|null
- */
- protected ?int $chainId = null;
-
- /**
- * The object uuid.
- *
- * @var string|null
- */
- protected ?string $objectUuid = null;
-
- /**
- * The step order.
- *
- * @var integer
- */
- protected int $stepOrder = 0;
-
- /**
- * The role.
- *
- * @var string|null
- */
- protected ?string $role = null;
-
- /**
- * The status.
- *
- * @var string|null
- */
- protected ?string $status = 'pending';
-
- /**
- * The decided by.
- *
- * @var string|null
- */
- protected ?string $decidedBy = null;
-
- /**
- * The comment.
- *
- * @var string|null
- */
- protected ?string $comment = null;
-
- /**
- * The decided at.
- *
- * @var DateTime|null
- */
- protected ?DateTime $decidedAt = null;
-
- /**
- * The created.
- *
- * @var DateTime|null
- */
- protected ?DateTime $created = null;
-
- /**
- * Uid of the user whose attempted transition provisioned this step, when the
- * step was created via the declarative approval-chains gate. `null` for steps
- * created through the pure `POST /api/approval-chains` CRUD flow. Used by
- * `ApprovalService::resolveSeparationOfDuties()` to reject a decision made by
- * the same user who triggered the gate.
- *
- * @var string|null
- */
- protected ?string $requesterId = null;
-
- /**
- * Constructor for ApprovalStep entity.
- */
- public function __construct() {
- $this->addType(fieldName: 'uuid', type: 'string');
- $this->addType(fieldName: 'chainId', type: 'integer');
- $this->addType(fieldName: 'objectUuid', type: 'string');
- $this->addType(fieldName: 'stepOrder', type: 'integer');
- $this->addType(fieldName: 'role', type: 'string');
- $this->addType(fieldName: 'status', type: 'string');
- $this->addType(fieldName: 'decidedBy', type: 'string');
- $this->addType(fieldName: 'comment', type: 'string');
- $this->addType(fieldName: 'decidedAt', type: 'datetime');
- $this->addType(fieldName: 'created', type: 'datetime');
- $this->addType(fieldName: 'requesterId', type: 'string');
- }//end __construct()
-
- /**
- * Hydrate entity from array.
- *
- * @param array $object Data to hydrate from
- *
- * @return self
- */
- public function hydrate(array $object): self {
- $fields = [
- 'uuid',
- 'chainId',
- 'objectUuid',
- 'stepOrder',
- 'role',
- 'status',
- 'decidedBy',
- 'comment',
- 'decidedAt',
- 'created',
- 'requesterId',
- ];
-
- foreach ($object as $key => $value) {
- if (in_array($key, $fields, true) === true) {
- $setter = 'set' . ucfirst($key);
- $this->$setter($value);
- }
- }
-
- return $this;
- }//end hydrate()
-
- /**
- * Serialize to JSON.
- *
- * @return array
- */
- public function jsonSerialize(): array {
- return [
- 'id' => $this->id,
- 'uuid' => $this->uuid,
- 'chainId' => $this->chainId,
- 'objectUuid' => $this->objectUuid,
- 'stepOrder' => $this->stepOrder,
- 'role' => $this->role,
- 'status' => $this->status,
- 'decidedBy' => $this->decidedBy,
- 'comment' => $this->comment,
- 'decidedAt' => $this->decidedAt?->format('c'),
- 'created' => $this->created?->format('c'),
- 'requesterId' => $this->requesterId,
- ];
- }//end jsonSerialize()
-}//end class
diff --git a/lib/Db/ApprovalStepMapper.php b/lib/Db/ApprovalStepMapper.php
deleted file mode 100644
index 1d7998384e..0000000000
--- a/lib/Db/ApprovalStepMapper.php
+++ /dev/null
@@ -1,268 +0,0 @@
-
- * @copyright 2024 Conduction B.V.
- * @license EUPL-1.2 https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
- *
- * @version GIT:
- *
- * @link https://OpenRegister.app
- */
-
-namespace OCA\OpenRegister\Db;
-
-use DateTime;
-use OCP\AppFramework\Db\QBMapper;
-use OCP\DB\QueryBuilder\IQueryBuilder;
-use OCP\IDBConnection;
-use Symfony\Component\Uid\Uuid;
-
-/**
- * Mapper for ApprovalStep entities.
- *
- * @extends QBMapper
- */
-class ApprovalStepMapper extends QBMapper {
- /**
- * Constructor for ApprovalStepMapper.
- *
- * @param IDBConnection $db Database connection
- */
- public function __construct(IDBConnection $db) {
- parent::__construct(
- db: $db,
- tableName: 'openregister_approval_steps',
- entityClass: ApprovalStep::class
- );
- }//end __construct()
-
- /**
- * Find an approval step by ID.
- *
- * @param int $id Step ID
- *
- * @return ApprovalStep
- */
- public function find(int $id): ApprovalStep {
- $qb = $this->db->getQueryBuilder();
-
- $qb->select('*')
- ->from($this->getTableName())
- ->where(
- $qb->expr()->eq('id', $qb->createNamedParameter(value: $id, type: IQueryBuilder::PARAM_INT))
- );
-
- return $this->findEntity(query: $qb);
- }//end find()
-
- /**
- * Find all steps for a chain and object combination.
- *
- * @param int $chainId Chain ID
- * @param string $objectUuid Object UUID
- *
- * @return array
- */
- public function findByChainAndObject(int $chainId, string $objectUuid): array {
- $qb = $this->db->getQueryBuilder();
-
- $qb->select('*')
- ->from($this->getTableName())
- ->where(
- $qb->expr()->eq(
- 'chain_id',
- $qb->createNamedParameter(value: $chainId, type: IQueryBuilder::PARAM_INT)
- )
- )
- ->andWhere(
- $qb->expr()->eq('object_uuid', $qb->createNamedParameter($objectUuid))
- )
- ->orderBy('step_order', 'ASC');
-
- return $this->findEntities(query: $qb);
- }//end findByChainAndObject()
-
- /**
- * Find all pending steps matching a given role.
- *
- * @param string $role Role (Nextcloud group ID)
- *
- * @return array
- */
- public function findPendingByRole(string $role): array {
- $qb = $this->db->getQueryBuilder();
-
- $qb->select('*')
- ->from($this->getTableName())
- ->where(
- $qb->expr()->eq('status', $qb->createNamedParameter('pending'))
- )
- ->andWhere(
- $qb->expr()->eq('role', $qb->createNamedParameter($role))
- )
- ->orderBy('created', 'ASC');
-
- return $this->findEntities(query: $qb);
- }//end findPendingByRole()
-
- /**
- * Find all approval steps for a given object UUID.
- *
- * @param string $objectUuid Object UUID
- *
- * @return array
- */
- public function findByObjectUuid(string $objectUuid): array {
- $qb = $this->db->getQueryBuilder();
-
- $qb->select('*')
- ->from($this->getTableName())
- ->where(
- $qb->expr()->eq('object_uuid', $qb->createNamedParameter($objectUuid))
- )
- ->orderBy('step_order', 'ASC');
-
- return $this->findEntities(query: $qb);
- }//end findByObjectUuid()
-
- /**
- * Find all steps with optional filters.
- *
- * @param array $filters Filter parameters
- * @param int|null $limit Maximum results
- * @param int|null $offset Pagination offset
- *
- * @return array
- *
- * @spec openspec/specs/approval-workflow/spec.md
- */
- public function findAllFiltered(array $filters = [], ?int $limit = null, ?int $offset = null): array {
- $qb = $this->db->getQueryBuilder();
-
- $qb->select('*')
- ->from($this->getTableName())
- ->orderBy('created', 'ASC');
-
- if (isset($filters['status']) === true) {
- $qb->andWhere($qb->expr()->eq('status', $qb->createNamedParameter($filters['status'])));
- }
-
- if (isset($filters['role']) === true) {
- $qb->andWhere($qb->expr()->eq('role', $qb->createNamedParameter($filters['role'])));
- }
-
- if (isset($filters['chainId']) === true) {
- $qb->andWhere(
- $qb->expr()->eq(
- 'chain_id',
- $qb->createNamedParameter(value: (int)$filters['chainId'], type: IQueryBuilder::PARAM_INT)
- )
- );
- }
-
- if (isset($filters['objectUuid']) === true) {
- $qb->andWhere($qb->expr()->eq('object_uuid', $qb->createNamedParameter($filters['objectUuid'])));
- }
-
- if ($limit !== null) {
- $qb->setMaxResults($limit);
- }
-
- if ($offset !== null) {
- $qb->setFirstResult($offset);
- }
-
- return $this->findEntities(query: $qb);
- }//end findAllFiltered()
-
- /**
- * Find distinct object UUIDs in a chain with their step progress.
- *
- * @param int $chainId Chain ID
- *
- * @return array
- */
- public function findByChain(int $chainId): array {
- $qb = $this->db->getQueryBuilder();
-
- $qb->select('*')
- ->from($this->getTableName())
- ->where(
- $qb->expr()->eq(
- 'chain_id',
- $qb->createNamedParameter(value: $chainId, type: IQueryBuilder::PARAM_INT)
- )
- )
- ->orderBy('object_uuid', 'ASC')
- ->addOrderBy('step_order', 'ASC');
-
- return $this->findEntities(query: $qb);
- }//end findByChain()
-
- /**
- * Create an approval step from an array.
- *
- * @param array $data Step data
- *
- * @return ApprovalStep
- */
- public function createFromArray(array $data): ApprovalStep {
- $step = new ApprovalStep();
- $step->hydrate($data);
-
- if ($step->getUuid() === null) {
- $step->setUuid(Uuid::v4()->toRfc4122());
- }
-
- if ($step->getCreated() === null) {
- $step->setCreated(new DateTime());
- }
-
- return $this->insert(entity: $step);
- }//end createFromArray()
-
- /**
- * Delete every step for a chain and object combination.
- *
- * Used by `ApprovalChainGateListener` to clear a `rejected` cycle before
- * provisioning a fresh one on the next gated-transition attempt
- * (resubmission). `workflow_executions` (`WorkflowExecutionMapper`) remains
- * the durable audit trail for the cleared cycle's decisions — `ApprovalStep`
- * rows are working state, not audit log.
- *
- * @param int $chainId Chain ID
- * @param string $objectUuid Object UUID
- *
- * @return int Number of rows deleted (0 on error).
- *
- * @spec openspec/specs/approval-workflow/spec.md
- */
- public function deleteByChainAndObject(int $chainId, string $objectUuid): int {
- try {
- $qb = $this->db->getQueryBuilder();
- $qb->delete($this->getTableName())
- ->where(
- $qb->expr()->eq(
- 'chain_id',
- $qb->createNamedParameter(value: $chainId, type: IQueryBuilder::PARAM_INT)
- )
- )
- ->andWhere(
- $qb->expr()->eq('object_uuid', $qb->createNamedParameter($objectUuid))
- );
-
- return (int)$qb->executeStatement();
- } catch (\Throwable $e) {
- return 0;
- }
- }//end deleteByChainAndObject()
-}//end class
diff --git a/lib/Db/CaseItem.php b/lib/Db/CaseItem.php
new file mode 100644
index 0000000000..d51cd3fd17
--- /dev/null
+++ b/lib/Db/CaseItem.php
@@ -0,0 +1,638 @@
+
+ * SPDX-License-Identifier: EUPL-1.2
+ *
+ * @category Db
+ * @package OCA\OpenRegister\Db
+ *
+ * @author Conduction Development Team
+ * @copyright 2026 Conduction B.V.
+ * @license EUPL-1.2 https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
+ *
+ * @link https://OpenRegister.app
+ *
+ * @spec openspec/changes/flow-cmmn-case-semantics/specs/flow-cases/spec.md#requirement-the-case-is-the-openregister-object
+ */
+
+declare(strict_types=1);
+
+namespace OCA\OpenRegister\Db;
+
+use DateTime;
+use JsonSerializable;
+use OCP\AppFramework\Db\Entity;
+
+/**
+ * Class CaseItem
+ *
+ * @method string|null getUuid()
+ * @method void setUuid(?string $uuid)
+ * @method string|null getItemKey()
+ * @method void setItemKey(?string $itemKey)
+ * @method string|null getName()
+ * @method void setName(?string $name)
+ * @method string|null getDescription()
+ * @method void setDescription(?string $description)
+ * @method string|null getObjectUuid()
+ * @method void setObjectUuid(?string $objectUuid)
+ * @method integer|null getRegisterId()
+ * @method void setRegisterId(?int $registerId)
+ * @method integer|null getSchemaId()
+ * @method void setSchemaId(?int $schemaId)
+ * @method string|null getFlowUuid()
+ * @method void setFlowUuid(?string $flowUuid)
+ * @method integer|null getFlowVersion()
+ * @method void setFlowVersion(?int $flowVersion)
+ * @method string|null getDefinitionItemKey()
+ * @method void setDefinitionItemKey(?string $definitionItemKey)
+ * @method string|null getOrigin()
+ * @method void setOrigin(?string $origin)
+ * @method integer|null getParentItemId()
+ * @method void setParentItemId(?int $parentItemId)
+ * @method string|null getPlanItemType()
+ * @method void setPlanItemType(?string $planItemType)
+ * @method integer|null getPosition()
+ * @method void setPosition(?int $position)
+ * @method string|null getState()
+ * @method void setState(?string $state)
+ * @method bool|null getIsTerminal()
+ * @method void setIsTerminal(?bool $isTerminal)
+ * @method DateTime|null getEnteredAt()
+ * @method void setEnteredAt(?DateTime $enteredAt)
+ * @method string|null getTerminatedReason()
+ * @method void setTerminatedReason(?string $terminatedReason)
+ * @method array|null getEntryCriteria()
+ * @method void setEntryCriteria(?array $entryCriteria)
+ * @method array|null getExitCriteria()
+ * @method void setExitCriteria(?array $exitCriteria)
+ * @method bool|null getRequired()
+ * @method void setRequired(?bool $required)
+ * @method bool|null getDiscretionary()
+ * @method void setDiscretionary(?bool $discretionary)
+ * @method array|null getRepetition()
+ * @method void setRepetition(?array $repetition)
+ * @method string|null getRealisationKind()
+ * @method void setRealisationKind(?string $realisationKind)
+ * @method string|null getRealisationUuid()
+ * @method void setRealisationUuid(?string $realisationUuid)
+ * @method integer|null getRealisationCount()
+ * @method void setRealisationCount(?int $realisationCount)
+ * @method array|null getAuthorizationRules()
+ * @method void setAuthorizationRules(?array $authorizationRules)
+ * @method array|null getCandidateUsers()
+ * @method void setCandidateUsers(?array $candidateUsers)
+ * @method array|null getCandidateGroups()
+ * @method void setCandidateGroups(?array $candidateGroups)
+ * @method string|null getCandidateRole()
+ * @method void setCandidateRole(?string $candidateRole)
+ * @method DateTime|null getDueAt()
+ * @method void setDueAt(?DateTime $dueAt)
+ * @method DateTime|null getExpiresAt()
+ * @method void setExpiresAt(?DateTime $expiresAt)
+ * @method string|null getDoorlooptijd()
+ * @method void setDoorlooptijd(?string $doorlooptijd)
+ * @method string|null getServicenorm()
+ * @method void setServicenorm(?string $servicenorm)
+ * @method array|null getPlanSettings()
+ * @method void setPlanSettings(?array $planSettings)
+ * @method DateTime|null getCreated()
+ * @method void setCreated(?DateTime $created)
+ * @method DateTime|null getUpdated()
+ * @method void setUpdated(?DateTime $updated)
+ * @method string|null getCreatedBy()
+ * @method void setCreatedBy(?string $createdBy)
+ *
+ * @psalm-suppress PropertyNotSetInConstructor $id is set by Nextcloud's Entity base class
+ *
+ * @SuppressWarnings(PHPMD.TooManyFields) One property per column of
+ * `openregister_case_items` (design.md, Data model).
+ * @SuppressWarnings(PHPMD.ExcessiveClassLength) The @method block, the typed
+ * properties and the field-by-field constructor scale linearly with the
+ * column count, same as {@see Task} and {@see FlowRun}.
+ * @SuppressWarnings(PHPMD.ExcessivePublicCount) Entity getters/setters are
+ * the column surface, not an API design choice.
+ *
+ * @spec openspec/changes/flow-cmmn-case-semantics/specs/flow-cases/spec.md#requirement-the-case-is-the-openregister-object
+ */
+class CaseItem extends Entity implements JsonSerializable {
+
+ /**
+ * The six CMMN plan-item states: the same six a task carries.
+ */
+ public const STATE_AVAILABLE = 'available';
+
+ public const STATE_ENABLED = 'enabled';
+
+ public const STATE_ACTIVE = 'active';
+
+ public const STATE_COMPLETED = 'completed';
+
+ public const STATE_TERMINATED = 'terminated';
+
+ public const STATE_DISABLED = 'disabled';
+
+ /**
+ * Every persistable state.
+ *
+ * @var array
+ */
+ public const STATES = [
+ self::STATE_AVAILABLE,
+ self::STATE_ENABLED,
+ self::STATE_ACTIVE,
+ self::STATE_COMPLETED,
+ self::STATE_TERMINATED,
+ self::STATE_DISABLED,
+ ];
+
+ /**
+ * States out of which no plan item of any type ever moves.
+ *
+ * @var array
+ */
+ public const TERMINAL_STATES = [
+ self::STATE_COMPLETED,
+ self::STATE_TERMINATED,
+ self::STATE_DISABLED,
+ ];
+
+ /**
+ * The three plan-item types.
+ */
+ public const TYPE_STAGE = 'stage';
+
+ public const TYPE_HUMAN_TASK = 'humanTask';
+
+ public const TYPE_MILESTONE = 'milestone';
+
+ /**
+ * Every plan-item type.
+ *
+ * @var array
+ */
+ public const TYPES = [
+ self::TYPE_STAGE,
+ self::TYPE_HUMAN_TASK,
+ self::TYPE_MILESTONE,
+ ];
+
+ /**
+ * Where a plan item came from.
+ */
+ public const ORIGIN_DEFINED = 'defined';
+
+ public const ORIGIN_DISCRETIONARY = 'discretionary';
+
+ public const ORIGIN_ADHOC = 'adhoc';
+
+ /**
+ * Every origin.
+ *
+ * @var array
+ */
+ public const ORIGINS = [
+ self::ORIGIN_DEFINED,
+ self::ORIGIN_DISCRETIONARY,
+ self::ORIGIN_ADHOC,
+ ];
+
+ /**
+ * What realises an active item.
+ */
+ public const REALISATION_TASK = 'task';
+
+ public const REALISATION_RUN = 'run';
+
+ public const REALISATION_NONE = 'none';
+
+ /**
+ * Public identifier.
+ *
+ * @var string|null
+ */
+ protected ?string $uuid = null;
+
+ /**
+ * Stable id within the plan; what a sentry's on-part names. Shared by
+ * every realisation of a repeating item.
+ *
+ * @var string|null
+ */
+ protected ?string $itemKey = null;
+
+ /**
+ * Human name.
+ *
+ * @var string|null
+ */
+ protected ?string $name = null;
+
+ /**
+ * Longer description.
+ *
+ * @var string|null
+ */
+ protected ?string $description = null;
+
+ /**
+ * The anchor: the object that IS the case.
+ *
+ * @var string|null
+ */
+ protected ?string $objectUuid = null;
+
+ /**
+ * The anchor's register.
+ *
+ * @var integer|null
+ */
+ protected ?int $registerId = null;
+
+ /**
+ * The anchor's schema.
+ *
+ * @var integer|null
+ */
+ protected ?int $schemaId = null;
+
+ /**
+ * Definition provenance: the flow whose case definition produced this
+ * item. Null for an ad-hoc item.
+ *
+ * @var string|null
+ */
+ protected ?string $flowUuid = null;
+
+ /**
+ * The pinned definition version.
+ *
+ * @var integer|null
+ */
+ protected ?int $flowVersion = null;
+
+ /**
+ * The key in the definition this row was created from. Null for ad-hoc.
+ *
+ * @var string|null
+ */
+ protected ?string $definitionItemKey = null;
+
+ /**
+ * defined | discretionary | adhoc.
+ *
+ * @var string|null
+ */
+ protected ?string $origin = null;
+
+ /**
+ * The containing stage, or null at the plan root.
+ *
+ * @var integer|null
+ */
+ protected ?int $parentItemId = null;
+
+ /**
+ * stage | humanTask | milestone.
+ *
+ * @var string|null
+ */
+ protected ?string $planItemType = null;
+
+ /**
+ * Display order among siblings.
+ *
+ * @var integer|null
+ */
+ protected ?int $position = 0;
+
+ /**
+ * One of the six states.
+ *
+ * @var string|null
+ */
+ protected ?string $state = null;
+
+ /**
+ * Materialised terminality, written in the SAME statement as `state`.
+ *
+ * @var boolean|null
+ */
+ protected ?bool $isTerminal = false;
+
+ /**
+ * When the item first became active (or completed, for a milestone).
+ *
+ * @var DateTime|null
+ */
+ protected ?DateTime $enteredAt = null;
+
+ /**
+ * Why the item was terminated, when it was.
+ *
+ * @var string|null
+ */
+ protected ?string $terminatedReason = null;
+
+ /**
+ * Entry sentries. Empty means: satisfied as soon as the parent is active.
+ *
+ * @var array|null
+ */
+ protected ?array $entryCriteria = null;
+
+ /**
+ * Exit sentries. Empty means: never satisfied.
+ *
+ * @var array|null
+ */
+ protected ?array $exitCriteria = null;
+
+ /**
+ * Whether the parent's completion rule waits for this item.
+ *
+ * @var boolean|null
+ */
+ protected ?bool $required = true;
+
+ /**
+ * Whether entering requires an explicit act.
+ *
+ * @var boolean|null
+ */
+ protected ?bool $discretionary = false;
+
+ /**
+ * The repetition rule, when any: `{"max": N}`.
+ *
+ * @var array|null
+ */
+ protected ?array $repetition = null;
+
+ /**
+ * task | run | none.
+ *
+ * @var string|null
+ */
+ protected ?string $realisationKind = null;
+
+ /**
+ * The task or run uuid realising this row.
+ *
+ * @var string|null
+ */
+ protected ?string $realisationUuid = null;
+
+ /**
+ * Which realisation of the item this row is (1 for a non-repeating item).
+ *
+ * @var integer|null
+ */
+ protected ?int $realisationCount = 1;
+
+ /**
+ * Who may enable or attach here: a list of group ids, `user:` and
+ * `role:` entries. Serialised as `authorization`.
+ *
+ * @var array|null
+ */
+ protected ?array $authorizationRules = null;
+
+ /**
+ * Performer hint passed to the task on realisation.
+ *
+ * @var array|null
+ */
+ protected ?array $candidateUsers = null;
+
+ /**
+ * Performer hint passed to the task on realisation.
+ *
+ * @var array|null
+ */
+ protected ?array $candidateGroups = null;
+
+ /**
+ * Performer hint passed to the task on realisation.
+ *
+ * @var string|null
+ */
+ protected ?string $candidateRole = null;
+
+ /**
+ * Advisory deadline, carried onto the task.
+ *
+ * @var DateTime|null
+ */
+ protected ?DateTime $dueAt = null;
+
+ /**
+ * Enforcing deadline, carried onto the task.
+ *
+ * @var DateTime|null
+ */
+ protected ?DateTime $expiresAt = null;
+
+ /**
+ * The zaaktype's doorlooptijd, carried for flow-business-timers.
+ *
+ * @var string|null
+ */
+ protected ?string $doorlooptijd = null;
+
+ /**
+ * The zaaktype's servicenorm, carried for flow-business-timers.
+ *
+ * @var string|null
+ */
+ protected ?string $servicenorm = null;
+
+ /**
+ * Plan-level settings, frozen at creation: `authorization` (root),
+ * `results` (the allowed end states), `writeThrough` (field mapping).
+ *
+ * @var array|null
+ */
+ protected ?array $planSettings = null;
+
+ /**
+ * Creation timestamp.
+ *
+ * @var DateTime|null
+ */
+ protected ?DateTime $created = null;
+
+ /**
+ * Last-modified timestamp.
+ *
+ * @var DateTime|null
+ */
+ protected ?DateTime $updated = null;
+
+ /**
+ * Who created the item.
+ *
+ * @var string|null
+ */
+ protected ?string $createdBy = null;
+
+ /**
+ * Constructor: declare field types so the mapper hydrates them correctly.
+ */
+ public function __construct() {
+ $this->addType(fieldName: 'uuid', type: 'string');
+ $this->addType(fieldName: 'itemKey', type: 'string');
+ $this->addType(fieldName: 'name', type: 'string');
+ $this->addType(fieldName: 'description', type: 'string');
+ $this->addType(fieldName: 'objectUuid', type: 'string');
+ $this->addType(fieldName: 'registerId', type: 'integer');
+ $this->addType(fieldName: 'schemaId', type: 'integer');
+ $this->addType(fieldName: 'flowUuid', type: 'string');
+ $this->addType(fieldName: 'flowVersion', type: 'integer');
+ $this->addType(fieldName: 'definitionItemKey', type: 'string');
+ $this->addType(fieldName: 'origin', type: 'string');
+ $this->addType(fieldName: 'parentItemId', type: 'integer');
+ $this->addType(fieldName: 'planItemType', type: 'string');
+ $this->addType(fieldName: 'position', type: 'integer');
+ $this->addType(fieldName: 'state', type: 'string');
+ $this->addType(fieldName: 'isTerminal', type: 'boolean');
+ $this->addType(fieldName: 'enteredAt', type: 'datetime');
+ $this->addType(fieldName: 'terminatedReason', type: 'string');
+ $this->addType(fieldName: 'entryCriteria', type: 'json');
+ $this->addType(fieldName: 'exitCriteria', type: 'json');
+ $this->addType(fieldName: 'required', type: 'boolean');
+ $this->addType(fieldName: 'discretionary', type: 'boolean');
+ $this->addType(fieldName: 'repetition', type: 'json');
+ $this->addType(fieldName: 'realisationKind', type: 'string');
+ $this->addType(fieldName: 'realisationUuid', type: 'string');
+ $this->addType(fieldName: 'realisationCount', type: 'integer');
+ $this->addType(fieldName: 'authorizationRules', type: 'json');
+ $this->addType(fieldName: 'candidateUsers', type: 'json');
+ $this->addType(fieldName: 'candidateGroups', type: 'json');
+ $this->addType(fieldName: 'candidateRole', type: 'string');
+ $this->addType(fieldName: 'dueAt', type: 'datetime');
+ $this->addType(fieldName: 'expiresAt', type: 'datetime');
+ $this->addType(fieldName: 'doorlooptijd', type: 'string');
+ $this->addType(fieldName: 'servicenorm', type: 'string');
+ $this->addType(fieldName: 'planSettings', type: 'json');
+ $this->addType(fieldName: 'created', type: 'datetime');
+ $this->addType(fieldName: 'updated', type: 'datetime');
+ $this->addType(fieldName: 'createdBy', type: 'string');
+
+ }//end __construct()
+
+ /**
+ * Whether this row will never move again.
+ *
+ * Reads the state set, NOT the materialised column: the column exists for
+ * indexed queries, and a test asserts the two agree.
+ *
+ * @return boolean True when the state is terminal.
+ *
+ * @spec openspec/changes/flow-cmmn-case-semantics/specs/flow-cases/spec.md#requirement-one-lifecycle-table-governs-every-plan-item
+ */
+ public function isInTerminalState(): bool {
+ return in_array($this->state, self::TERMINAL_STATES, true);
+ }//end isInTerminalState()
+
+ /**
+ * Whether this row has been entered (is or was past `available`).
+ *
+ * @return boolean True for enabled, active or a terminal state other than disabled.
+ *
+ * @spec openspec/changes/flow-cmmn-case-semantics/specs/flow-cases/spec.md#requirement-stages-nest-and-complete-by-a-written-rule
+ */
+ public function isEntered(): bool {
+ return $this->state !== null
+ && $this->state !== self::STATE_AVAILABLE
+ && $this->state !== self::STATE_DISABLED;
+ }//end isEntered()
+
+ /**
+ * Hydrate entity from array.
+ *
+ * @param array $object Data to hydrate from.
+ *
+ * @return self This item.
+ *
+ * @spec openspec/changes/flow-cmmn-case-semantics/specs/flow-cases/spec.md#requirement-plan-item-state-is-stored-as-rows-never-as-an-encoded-blob
+ */
+ public function hydrate(array $object): self {
+ foreach ($object as $fieldName => $value) {
+ if (array_key_exists($fieldName, $this->getFieldTypes()) === false || $fieldName === 'id') {
+ continue;
+ }
+
+ $setter = 'set' . ucfirst($fieldName);
+ $this->$setter($value);
+ }
+
+ return $this;
+ }//end hydrate()
+
+ /**
+ * Serialise for the API.
+ *
+ * @return array The plan item as plain data.
+ *
+ * @spec openspec/changes/flow-cmmn-case-semantics/specs/flow-cases/spec.md#requirement-the-case-is-the-openregister-object
+ */
+ public function jsonSerialize(): array {
+ return [
+ 'id' => $this->id,
+ 'uuid' => $this->uuid,
+ 'key' => $this->itemKey,
+ 'name' => $this->name,
+ 'description' => $this->description,
+ 'objectUuid' => $this->objectUuid,
+ 'registerId' => $this->registerId,
+ 'schemaId' => $this->schemaId,
+ 'flowUuid' => $this->flowUuid,
+ 'flowVersion' => $this->flowVersion,
+ 'definitionItemKey' => $this->definitionItemKey,
+ 'origin' => $this->origin,
+ 'parentItemId' => $this->parentItemId,
+ 'type' => $this->planItemType,
+ 'position' => $this->position,
+ 'state' => $this->state,
+ 'isTerminal' => $this->isTerminal,
+ 'enteredAt' => $this->enteredAt?->format('c'),
+ 'terminatedReason' => $this->terminatedReason,
+ 'entryCriteria' => ($this->entryCriteria ?? []),
+ 'exitCriteria' => ($this->exitCriteria ?? []),
+ 'required' => $this->required,
+ 'discretionary' => $this->discretionary,
+ 'repetition' => $this->repetition,
+ 'realisationKind' => $this->realisationKind,
+ 'realisationUuid' => $this->realisationUuid,
+ 'realisationCount' => $this->realisationCount,
+ 'authorization' => $this->authorizationRules,
+ 'candidateUsers' => $this->candidateUsers,
+ 'candidateGroups' => $this->candidateGroups,
+ 'candidateRole' => $this->candidateRole,
+ 'dueAt' => $this->dueAt?->format('c'),
+ 'expiresAt' => $this->expiresAt?->format('c'),
+ 'doorlooptijd' => $this->doorlooptijd,
+ 'servicenorm' => $this->servicenorm,
+ 'planSettings' => $this->planSettings,
+ 'created' => $this->created?->format('c'),
+ 'updated' => $this->updated?->format('c'),
+ 'createdBy' => $this->createdBy,
+ ];
+ }//end jsonSerialize()
+}//end class
diff --git a/lib/Db/CaseItemAudit.php b/lib/Db/CaseItemAudit.php
new file mode 100644
index 0000000000..79bb71e10a
--- /dev/null
+++ b/lib/Db/CaseItemAudit.php
@@ -0,0 +1,175 @@
+
+ * SPDX-License-Identifier: EUPL-1.2
+ *
+ * @category Db
+ * @package OCA\OpenRegister\Db
+ *
+ * @author Conduction Development Team
+ * @copyright 2026 Conduction B.V.
+ * @license EUPL-1.2 https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
+ *
+ * @link https://OpenRegister.app
+ *
+ * @spec openspec/changes/flow-cmmn-case-semantics/specs/flow-cases/spec.md#requirement-plan-item-state-is-stored-as-rows-never-as-an-encoded-blob
+ */
+
+declare(strict_types=1);
+
+namespace OCA\OpenRegister\Db;
+
+use DateTime;
+use JsonSerializable;
+use OCP\AppFramework\Db\Entity;
+
+/**
+ * Class CaseItemAudit
+ *
+ * @method integer|null getCaseItemId()
+ * @method void setCaseItemId(?int $caseItemId)
+ * @method string|null getFromState()
+ * @method void setFromState(?string $fromState)
+ * @method string|null getToState()
+ * @method void setToState(?string $toState)
+ * @method string|null getCause()
+ * @method void setCause(?string $cause)
+ * @method string|null getCauseRef()
+ * @method void setCauseRef(?string $causeRef)
+ * @method string|null getActor()
+ * @method void setActor(?string $actor)
+ * @method string|null getReason()
+ * @method void setReason(?string $reason)
+ * @method bool|null getAuthorized()
+ * @method void setAuthorized(?bool $authorized)
+ * @method DateTime|null getCreated()
+ * @method void setCreated(?DateTime $created)
+ *
+ * @psalm-suppress PropertyNotSetInConstructor $id is set by Nextcloud's Entity base class
+ *
+ * @spec openspec/changes/flow-cmmn-case-semantics/specs/flow-cases/spec.md#requirement-plan-item-state-is-stored-as-rows-never-as-an-encoded-blob
+ */
+class CaseItemAudit extends Entity implements JsonSerializable {
+
+ /**
+ * The five causes a transition can have.
+ */
+ public const CAUSE_SENTRY = 'sentry';
+
+ public const CAUSE_USER = 'user';
+
+ public const CAUSE_REALISATION = 'realisation';
+
+ public const CAUSE_CASCADE = 'cascade';
+
+ public const CAUSE_IMPORT = 'import';
+
+ /**
+ * The plan item this entry is about.
+ *
+ * @var integer|null
+ */
+ protected ?int $caseItemId = null;
+
+ /**
+ * The state before.
+ *
+ * @var string|null
+ */
+ protected ?string $fromState = null;
+
+ /**
+ * The state after (or the state that was requested, on a denial).
+ *
+ * @var string|null
+ */
+ protected ?string $toState = null;
+
+ /**
+ * sentry | user | realisation | cascade | import.
+ *
+ * @var string|null
+ */
+ protected ?string $cause = null;
+
+ /**
+ * The sentry id, the task or run uuid, or the parent item uuid.
+ *
+ * @var string|null
+ */
+ protected ?string $causeRef = null;
+
+ /**
+ * The acting identity.
+ *
+ * @var string|null
+ */
+ protected ?string $actor = null;
+
+ /**
+ * Free-text reason, or the denial message.
+ *
+ * @var string|null
+ */
+ protected ?string $reason = null;
+
+ /**
+ * False on a recorded denial.
+ *
+ * @var boolean|null
+ */
+ protected ?bool $authorized = true;
+
+ /**
+ * When it happened.
+ *
+ * @var DateTime|null
+ */
+ protected ?DateTime $created = null;
+
+ /**
+ * Constructor: declare field types.
+ */
+ public function __construct() {
+ $this->addType(fieldName: 'caseItemId', type: 'integer');
+ $this->addType(fieldName: 'fromState', type: 'string');
+ $this->addType(fieldName: 'toState', type: 'string');
+ $this->addType(fieldName: 'cause', type: 'string');
+ $this->addType(fieldName: 'causeRef', type: 'string');
+ $this->addType(fieldName: 'actor', type: 'string');
+ $this->addType(fieldName: 'reason', type: 'string');
+ $this->addType(fieldName: 'authorized', type: 'boolean');
+ $this->addType(fieldName: 'created', type: 'datetime');
+
+ }//end __construct()
+
+ /**
+ * Serialise for the API.
+ *
+ * @return array The entry as plain data.
+ *
+ * @spec openspec/changes/flow-cmmn-case-semantics/specs/flow-cases/spec.md#requirement-plan-item-state-is-stored-as-rows-never-as-an-encoded-blob
+ */
+ public function jsonSerialize(): array {
+ return [
+ 'id' => $this->id,
+ 'caseItemId' => $this->caseItemId,
+ 'fromState' => $this->fromState,
+ 'toState' => $this->toState,
+ 'cause' => $this->cause,
+ 'causeRef' => $this->causeRef,
+ 'actor' => $this->actor,
+ 'reason' => $this->reason,
+ 'authorized' => $this->authorized,
+ 'created' => $this->created?->format('c'),
+ ];
+ }//end jsonSerialize()
+}//end class
diff --git a/lib/Db/CaseItemAuditMapper.php b/lib/Db/CaseItemAuditMapper.php
new file mode 100644
index 0000000000..b15bcc6439
--- /dev/null
+++ b/lib/Db/CaseItemAuditMapper.php
@@ -0,0 +1,157 @@
+
+ * SPDX-License-Identifier: EUPL-1.2
+ *
+ * @category Db
+ * @package OCA\OpenRegister\Db
+ *
+ * @author Conduction Development Team
+ * @copyright 2026 Conduction B.V.
+ * @license EUPL-1.2 https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
+ *
+ * @link https://OpenRegister.app
+ *
+ * @template-extends QBMapper
+ *
+ * @spec openspec/changes/flow-cmmn-case-semantics/specs/flow-cases/spec.md#requirement-plan-item-state-is-stored-as-rows-never-as-an-encoded-blob
+ */
+
+declare(strict_types=1);
+
+namespace OCA\OpenRegister\Db;
+
+use DateTime;
+use InvalidArgumentException;
+use LogicException;
+use OCP\AppFramework\Db\Entity;
+use OCP\AppFramework\Db\QBMapper;
+use OCP\DB\QueryBuilder\IQueryBuilder;
+use OCP\IDBConnection;
+
+/**
+ * Appends and reads plan-item audit entries.
+ *
+ * @template-extends QBMapper
+ *
+ * @spec openspec/changes/flow-cmmn-case-semantics/specs/flow-cases/spec.md#requirement-plan-item-state-is-stored-as-rows-never-as-an-encoded-blob
+ */
+class CaseItemAuditMapper extends QBMapper {
+
+ /**
+ * Constructor.
+ *
+ * @param IDBConnection $db The database connection.
+ */
+ public function __construct(IDBConnection $db) {
+ parent::__construct(db: $db, tableName: 'openregister_case_item_audit', entityClass: CaseItemAudit::class);
+
+ }//end __construct()
+
+ /**
+ * Append an entry, stamping `created`.
+ *
+ * @param Entity $entity The entry to append.
+ *
+ * @return CaseItemAudit The appended entry.
+ *
+ * @spec openspec/changes/flow-cmmn-case-semantics/specs/flow-cases/spec.md#requirement-plan-item-state-is-stored-as-rows-never-as-an-encoded-blob
+ */
+ public function insert(Entity $entity): CaseItemAudit {
+ if ($entity instanceof CaseItemAudit === false) {
+ throw new InvalidArgumentException('CaseItemAuditMapper appends CaseItemAudit entries only.');
+ }
+
+ if ($entity->getCreated() === null) {
+ $entity->setCreated(new DateTime());
+ }
+
+ return parent::insert(entity: $entity);
+ }//end insert()
+
+ /**
+ * Refused: the audit is append-only.
+ *
+ * @param Entity $entity Ignored.
+ *
+ * @return CaseItemAudit Never returns.
+ *
+ * @throws LogicException Always.
+ *
+ * @SuppressWarnings(PHPMD.UnusedFormalParameter) The parameter is the
+ * inherited signature; refusing it unread is the whole method.
+ *
+ * @spec openspec/changes/flow-cmmn-case-semantics/specs/flow-cases/spec.md#requirement-plan-item-state-is-stored-as-rows-never-as-an-encoded-blob
+ */
+ public function update(Entity $entity): CaseItemAudit {
+ throw new LogicException('The plan-item audit is append-only: entries are never updated.');
+ }//end update()
+
+ /**
+ * Refused: the audit is append-only.
+ *
+ * @param Entity $entity Ignored.
+ *
+ * @return CaseItemAudit Never returns.
+ *
+ * @throws LogicException Always.
+ *
+ * @SuppressWarnings(PHPMD.UnusedFormalParameter) The parameter is the
+ * inherited signature; refusing it unread is the whole method.
+ *
+ * @spec openspec/changes/flow-cmmn-case-semantics/specs/flow-cases/spec.md#requirement-plan-item-state-is-stored-as-rows-never-as-an-encoded-blob
+ */
+ public function delete(Entity $entity): CaseItemAudit {
+ throw new LogicException('The plan-item audit is append-only: entries are never deleted.');
+ }//end delete()
+
+ /**
+ * The audit trail of one plan item, oldest first.
+ *
+ * @param int $caseItemId The item's row id.
+ *
+ * @return array The entries.
+ *
+ * @spec openspec/changes/flow-cmmn-case-semantics/specs/flow-cases/spec.md#requirement-plan-item-state-is-stored-as-rows-never-as-an-encoded-blob
+ */
+ public function findForItem(int $caseItemId): array {
+ $qb = $this->db->getQueryBuilder();
+ $qb->select('*')
+ ->from($this->getTableName())
+ ->where($qb->expr()->eq('case_item_id', $qb->createNamedParameter($caseItemId, IQueryBuilder::PARAM_INT)))
+ ->orderBy('id', 'ASC');
+
+ return $this->findEntities(query: $qb);
+ }//end findForItem()
+
+ /**
+ * The audit trail of a whole plan, oldest first.
+ *
+ * @param array $caseItemIds The plan's row ids.
+ *
+ * @return array The entries.
+ *
+ * @spec openspec/changes/flow-cmmn-case-semantics/specs/flow-cases/spec.md#requirement-plan-item-state-is-stored-as-rows-never-as-an-encoded-blob
+ */
+ public function findForItems(array $caseItemIds): array {
+ if ($caseItemIds === []) {
+ return [];
+ }
+
+ $qb = $this->db->getQueryBuilder();
+ $qb->select('*')
+ ->from($this->getTableName())
+ ->where($qb->expr()->in('case_item_id', $qb->createNamedParameter(array_values($caseItemIds), IQueryBuilder::PARAM_INT_ARRAY)))
+ ->orderBy('id', 'ASC');
+
+ return $this->findEntities(query: $qb);
+ }//end findForItems()
+}//end class
diff --git a/lib/Db/CaseItemMapper.php b/lib/Db/CaseItemMapper.php
new file mode 100644
index 0000000000..48768ded04
--- /dev/null
+++ b/lib/Db/CaseItemMapper.php
@@ -0,0 +1,330 @@
+
+ * SPDX-License-Identifier: EUPL-1.2
+ *
+ * @category Db
+ * @package OCA\OpenRegister\Db
+ *
+ * @author Conduction Development Team
+ * @copyright 2026 Conduction B.V.
+ * @license EUPL-1.2 https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
+ *
+ * @link https://OpenRegister.app
+ *
+ * @template-extends QBMapper
+ *
+ * @spec openspec/changes/flow-cmmn-case-semantics/specs/flow-cases/spec.md#requirement-plan-item-state-is-stored-as-rows-never-as-an-encoded-blob
+ */
+
+declare(strict_types=1);
+
+namespace OCA\OpenRegister\Db;
+
+use DateTime;
+use InvalidArgumentException;
+use OCP\AppFramework\Db\Entity;
+use OCP\AppFramework\Db\QBMapper;
+use OCP\DB\QueryBuilder\IQueryBuilder;
+use OCP\IDBConnection;
+use Symfony\Component\Uid\Uuid;
+
+/**
+ * Reads and writes plan items.
+ *
+ * @SuppressWarnings(PHPMD.TooManyPublicMethods) A mapper's public methods
+ * are its query vocabulary, one per distinct question the case layer asks of
+ * the table (same reasoning as TaskMapper and FlowRunMapper).
+ *
+ * @template-extends QBMapper
+ *
+ * @spec openspec/changes/flow-cmmn-case-semantics/specs/flow-cases/spec.md#requirement-plan-item-state-is-stored-as-rows-never-as-an-encoded-blob
+ */
+class CaseItemMapper extends QBMapper {
+
+ /**
+ * Constructor.
+ *
+ * @param IDBConnection $db The database connection.
+ */
+ public function __construct(IDBConnection $db) {
+ parent::__construct(db: $db, tableName: 'openregister_case_items', entityClass: CaseItem::class);
+
+ }//end __construct()
+
+ /**
+ * Insert, stamping `uuid` and `created` when absent.
+ *
+ * @param Entity $entity The plan item to insert.
+ *
+ * @return CaseItem The inserted item, with its id.
+ *
+ * @spec openspec/changes/flow-cmmn-case-semantics/specs/flow-cases/spec.md#requirement-plan-item-state-is-stored-as-rows-never-as-an-encoded-blob
+ */
+ public function insert(Entity $entity): CaseItem {
+ if ($entity instanceof CaseItem === false) {
+ throw new InvalidArgumentException('CaseItemMapper persists CaseItem entities only.');
+ }
+
+ if (trim((string)$entity->getUuid()) === '') {
+ $entity->setUuid(Uuid::v4()->toRfc4122());
+ }
+
+ if ($entity->getCreated() === null) {
+ $entity->setCreated(new DateTime());
+ }
+
+ return parent::insert(entity: $entity);
+ }//end insert()
+
+ /**
+ * Update, stamping `updated`.
+ *
+ * @param Entity $entity The plan item to update.
+ *
+ * @return CaseItem The updated item.
+ *
+ * @spec openspec/changes/flow-cmmn-case-semantics/specs/flow-cases/spec.md#requirement-plan-item-state-is-stored-as-rows-never-as-an-encoded-blob
+ */
+ public function update(Entity $entity): CaseItem {
+ if ($entity instanceof CaseItem === false) {
+ throw new InvalidArgumentException('CaseItemMapper persists CaseItem entities only.');
+ }
+
+ $entity->setUpdated(new DateTime());
+
+ return parent::update(entity: $entity);
+ }//end update()
+
+ /**
+ * Persist a transition ONLY if the row is still in the state it was read in.
+ *
+ * Mirrors QBMapper::update() field by field (updated fields only) with the
+ * extra predicate. Two callers can both pass the in-memory legality check;
+ * exactly one of them changes the row, and the other learns it here.
+ *
+ * @param CaseItem $item The item, with its setters already applied.
+ * @param string $expectedState The state the caller read before mutating.
+ *
+ * @return boolean True when the row moved; false when somebody else moved it first.
+ *
+ * @spec openspec/changes/flow-cmmn-case-semantics/specs/flow-cases/spec.md#requirement-plan-item-state-is-stored-as-rows-never-as-an-encoded-blob
+ */
+ public function updateIfState(CaseItem $item, string $expectedState): bool {
+ $id = $item->getId();
+ if ($id === null) {
+ throw new InvalidArgumentException('A plan item must be persisted before it can be transitioned.');
+ }
+
+ $item->setUpdated(new DateTime());
+ $properties = $item->getUpdatedFields();
+ unset($properties['id']);
+
+ $qb = $this->db->getQueryBuilder();
+ $qb->update($this->getTableName());
+ foreach (array_keys($properties) as $property) {
+ $getter = 'get' . ucfirst($property);
+ $qb->set(
+ $item->propertyToColumn(property: $property),
+ $qb->createNamedParameter($item->$getter(), $this->getParameterTypeForProperty(entity: $item, property: $property))
+ );
+ }
+
+ $qb->where($qb->expr()->eq('id', $qb->createNamedParameter($id, IQueryBuilder::PARAM_INT)))
+ ->andWhere($qb->expr()->eq('state', $qb->createNamedParameter($expectedState)));
+
+ return $qb->executeStatement() === 1;
+ }//end updateIfState()
+
+ /**
+ * Find a plan item by its public uuid.
+ *
+ * @param string $uuid The item uuid.
+ *
+ * @return CaseItem The item.
+ *
+ * @throws \OCP\AppFramework\Db\DoesNotExistException When no such item exists.
+ *
+ * @spec openspec/changes/flow-cmmn-case-semantics/specs/flow-cases/spec.md#requirement-the-case-is-the-openregister-object
+ */
+ public function findByUuid(string $uuid): CaseItem {
+ $qb = $this->db->getQueryBuilder();
+ $qb->select('*')
+ ->from($this->getTableName())
+ ->where($qb->expr()->eq('uuid', $qb->createNamedParameter($uuid)));
+
+ return $this->findEntity(query: $qb);
+ }//end findByUuid()
+
+ /**
+ * The whole plan of one object: every row, tree order.
+ *
+ * ONE indexed read by the anchor. No run uuid is involved, so a plan on
+ * an object that never had a run reads identically.
+ *
+ * @param string $objectUuid The anchoring object's uuid.
+ *
+ * @return array The rows, parents before children by id.
+ *
+ * @spec openspec/changes/flow-cmmn-case-semantics/specs/flow-cases/spec.md#requirement-the-case-is-the-openregister-object
+ */
+ public function findByObject(string $objectUuid): array {
+ $qb = $this->db->getQueryBuilder();
+ $qb->select('*')
+ ->from($this->getTableName())
+ ->where($qb->expr()->eq('object_uuid', $qb->createNamedParameter($objectUuid)))
+ ->orderBy('position', 'ASC')
+ ->addOrderBy('id', 'ASC');
+
+ return $this->findEntities(query: $qb);
+ }//end findByObject()
+
+ /**
+ * How many non-terminal rows an object has: the cheap "is there a live
+ * plan here at all" question an object-event listener asks first.
+ *
+ * @param string $objectUuid The anchoring object's uuid.
+ *
+ * @return int The open row count.
+ *
+ * @spec openspec/changes/flow-cmmn-case-semantics/specs/flow-cases/spec.md#requirement-plan-item-state-is-stored-as-rows-never-as-an-encoded-blob
+ */
+ public function countOpenByObject(string $objectUuid): int {
+ $qb = $this->db->getQueryBuilder();
+ $qb->select($qb->func()->count('*', 'total'))
+ ->from($this->getTableName())
+ ->where($qb->expr()->eq('object_uuid', $qb->createNamedParameter($objectUuid)))
+ ->andWhere($qb->expr()->eq('is_terminal', $qb->createNamedParameter(false, IQueryBuilder::PARAM_BOOL)));
+
+ $result = $qb->executeQuery();
+ $total = (int)$result->fetchOne();
+ $result->closeCursor();
+
+ return $total;
+ }//end countOpenByObject()
+
+ /**
+ * The plan items realised by a task or a run: the reverse lookup.
+ *
+ * @param string $realisationUuid The task or run uuid.
+ *
+ * @return array The rows (normally one).
+ *
+ * @spec openspec/changes/flow-cmmn-case-semantics/specs/flow-cases/spec.md#requirement-a-human-plan-item-is-realised-by-a-task-and-a-stage-may-be-realised-by-a-flow-run
+ */
+ public function findByRealisation(string $realisationUuid): array {
+ $qb = $this->db->getQueryBuilder();
+ $qb->select('*')
+ ->from($this->getTableName())
+ ->where($qb->expr()->eq('realisation_uuid', $qb->createNamedParameter($realisationUuid)))
+ ->orderBy('id', 'ASC');
+
+ return $this->findEntities(query: $qb);
+ }//end findByRealisation()
+
+ /**
+ * "Which cases are stuck where": rows of one type in one state, paged.
+ *
+ * Filtering, ordering and paging happen in the datastore over the
+ * `(plan_item_type, state)` index. The total is {@see countByTypeAndState()}
+ * over the same predicate, so page and total cannot disagree.
+ *
+ * @param string|null $type Restrict to one plan-item type, or null for all.
+ * @param string|null $state Restrict to one state, or null for all.
+ * @param int $limit Page size.
+ * @param int $offset Page offset.
+ *
+ * @return array The page, oldest first.
+ *
+ * @spec openspec/changes/flow-cmmn-case-semantics/specs/flow-cases/spec.md#requirement-plan-item-state-is-stored-as-rows-never-as-an-encoded-blob
+ */
+ public function findByTypeAndState(?string $type, ?string $state, int $limit = 25, int $offset = 0): array {
+ $qb = $this->db->getQueryBuilder();
+ $qb->select('*')
+ ->from($this->getTableName());
+ $this->applyTypeAndState(qb: $qb, type: $type, state: $state);
+ $qb->orderBy('id', 'ASC')
+ ->setMaxResults(max(1, $limit))
+ ->setFirstResult(max(0, $offset));
+
+ return $this->findEntities(query: $qb);
+ }//end findByTypeAndState()
+
+ /**
+ * The total behind {@see findByTypeAndState()}.
+ *
+ * @param string|null $type Restrict to one plan-item type, or null for all.
+ * @param string|null $state Restrict to one state, or null for all.
+ *
+ * @return int The count, computed in the datastore.
+ *
+ * @spec openspec/changes/flow-cmmn-case-semantics/specs/flow-cases/spec.md#requirement-plan-item-state-is-stored-as-rows-never-as-an-encoded-blob
+ */
+ public function countByTypeAndState(?string $type, ?string $state): int {
+ $qb = $this->db->getQueryBuilder();
+ $qb->select($qb->func()->count('*', 'total'))
+ ->from($this->getTableName());
+ $this->applyTypeAndState(qb: $qb, type: $type, state: $state);
+
+ $result = $qb->executeQuery();
+ $total = (int)$result->fetchOne();
+ $result->closeCursor();
+
+ return $total;
+ }//end countByTypeAndState()
+
+ /**
+ * Delete every plan item of one object. The audit is NOT touched: it is
+ * append-only and outlives the rows it describes.
+ *
+ * @param string $objectUuid The anchoring object's uuid.
+ *
+ * @return int How many rows were deleted.
+ *
+ * @spec openspec/changes/flow-cmmn-case-semantics/specs/flow-cases/spec.md#requirement-business-state-is-written-through-to-the-register-never-owned-by-the-engine
+ */
+ public function deleteByObject(string $objectUuid): int {
+ $qb = $this->db->getQueryBuilder();
+ $qb->delete($this->getTableName())
+ ->where($qb->expr()->eq('object_uuid', $qb->createNamedParameter($objectUuid)));
+
+ return $qb->executeStatement();
+ }//end deleteByObject()
+
+ /**
+ * The shared predicate of the stuck-where page and its total.
+ *
+ * @param IQueryBuilder $qb The query under construction.
+ * @param string|null $type The type filter, or null.
+ * @param string|null $state The state filter, or null.
+ *
+ * @return void
+ *
+ * @spec openspec/changes/flow-cmmn-case-semantics/specs/flow-cases/spec.md#requirement-plan-item-state-is-stored-as-rows-never-as-an-encoded-blob
+ */
+ private function applyTypeAndState(IQueryBuilder $qb, ?string $type, ?string $state): void {
+ if ($type !== null && trim($type) !== '') {
+ $qb->andWhere($qb->expr()->eq('plan_item_type', $qb->createNamedParameter($type)));
+ }
+
+ if ($state !== null && trim($state) !== '') {
+ $qb->andWhere($qb->expr()->eq('state', $qb->createNamedParameter($state)));
+ }
+ }//end applyTypeAndState()
+}//end class
diff --git a/lib/Db/CaseToken.php b/lib/Db/CaseToken.php
index 8e0b8af63d..54eb808cb1 100644
--- a/lib/Db/CaseToken.php
+++ b/lib/Db/CaseToken.php
@@ -43,7 +43,6 @@
* Class CaseToken
*
* @method string|null getToken()
- * @method void getToken(?string $token)
* @method void setToken(?string $token)
* @method string|null getObjectUuid()
* @method void setObjectUuid(?string $objectUuid)
diff --git a/lib/Db/File.php b/lib/Db/File.php
index b1b2a2920d..68f6d61bdd 100644
--- a/lib/Db/File.php
+++ b/lib/Db/File.php
@@ -23,6 +23,24 @@
* @link https://OpenRegister.app
*
* @spec openspec/changes/file-actions/tasks.md
+ */
+
+declare(strict_types=1);
+
+namespace OCA\OpenRegister\Db;
+
+use DateTime;
+use OCP\AppFramework\Db\Entity;
+
+/**
+ * File entity for the `openregister_files` table.
+ *
+ * The `@method` tags below belong on the CLASS, not on the file docblock they
+ * used to sit in. A static analyser resolves magic accessors from the class it
+ * is analysing; a docblock above `declare(strict_types=1)` documents the file
+ * and is invisible to it. That is why phpstan.neon carried counted ignore
+ * entries for `File::setUpdated()` and friends, and why adding one accessor
+ * made an unrelated ignore count wrong.
*
* @method int|null getFileId()
* @method void setFileId(int $fileId)
@@ -44,16 +62,10 @@
* @method void setCreated(\DateTime $created)
* @method \DateTime|null getUpdated()
* @method void setUpdated(?\DateTime $updated)
- */
-
-declare(strict_types=1);
-
-namespace OCA\OpenRegister\Db;
-
-use OCP\AppFramework\Db\Entity;
-
-/**
- * File entity for the `openregister_files` table.
+ * @method \DateTime|null getPublished()
+ * @method void setPublished(?\DateTime $published)
+ * @method \DateTime|null getDepublished()
+ * @method void setDepublished(?\DateTime $depublished)
*/
class File extends Entity {
@@ -127,6 +139,29 @@ class File extends Entity {
*/
protected ?\DateTime $updated = null;
+ /**
+ * When this file becomes public.
+ *
+ * Null means it has never been published, which is why the key is nullable
+ * rather than defaulting to the creation time. A file that exists is not a
+ * file that was published, and reporting the creation time as a publication
+ * date is what this column exists to stop.
+ *
+ * @var \DateTime|null
+ */
+ protected ?\DateTime $published = null;
+
+ /**
+ * When this file stops being public.
+ *
+ * Null means no end date, not "already ended". The distinction matters: a
+ * published attachment with no depublication date stays public, which is the
+ * ordinary case.
+ *
+ * @var \DateTime|null
+ */
+ protected ?\DateTime $depublished = null;
+
/**
* Configure typed columns for the file metadata row.
*
@@ -143,6 +178,8 @@ public function __construct() {
$this->addType(fieldName: 'downloadCount', type: 'integer');
$this->addType(fieldName: 'created', type: 'datetime');
$this->addType(fieldName: 'updated', type: 'datetime');
+ $this->addType(fieldName: 'published', type: 'datetime');
+ $this->addType(fieldName: 'depublished', type: 'datetime');
}//end __construct()
@@ -165,6 +202,51 @@ public function jsonSerialize(): array {
'downloadCount' => $this->downloadCount,
'created' => $this->created?->format('c'),
'updated' => $this->updated?->format('c'),
+ 'published' => $this->published?->format('c'),
+ 'depublished' => $this->depublished?->format('c'),
+ 'isPublished' => $this->isPublishedAt(),
];
}//end jsonSerialize()
+
+ /**
+ * Whether this file is public at a given moment.
+ *
+ * The rule reads as three separate questions rather than one expression,
+ * because each null means something different:
+ *
+ * - No `published` at all means never published. This is NOT the same as
+ * published long ago, and defaulting it to the creation time would make
+ * every file that has ever existed look published.
+ * - A `published` in the future means not yet, which is the whole point of
+ * being able to set one.
+ * - No `depublished` means no end date, not an end date in the past.
+ *
+ * The boundaries are inclusive at the start and exclusive at the end, so a
+ * file published and depublished at the same instant is not public.
+ *
+ * @param DateTime|null $now The moment to evaluate, defaulting to this one.
+ *
+ * @return bool True when the file is public at that moment.
+ *
+ * @spec openspec/changes/file-publication-window/specs/file-publication-window/spec.md#requirement-a-file-carries-its-own-publication-window-req-fpw-101
+ */
+ public function isPublishedAt(?DateTime $now = null): bool {
+ if ($this->published === null) {
+ return false;
+ }
+
+ if ($now === null) {
+ $now = new DateTime();
+ }
+
+ if ($this->published > $now) {
+ return false;
+ }
+
+ if ($this->depublished === null) {
+ return true;
+ }
+
+ return ($this->depublished > $now);
+ }//end isPublishedAt()
}//end class
diff --git a/lib/Db/FileMapper.php b/lib/Db/FileMapper.php
index 847ebe4d18..01a4cd835b 100644
--- a/lib/Db/FileMapper.php
+++ b/lib/Db/FileMapper.php
@@ -42,7 +42,13 @@
* @version GIT:
* @link https://OpenRegister.app
*
- * @phpstan-type File array{
+ * The alias below describes a filecache ROW, not the {@see File} entity. It was
+ * named `File`, which shadowed that entity in every docblock in this file: a
+ * mapper method annotated `@return File` read as an array shape, which is why
+ * the phpstan baseline carried an entry for each one. Renamed rather than
+ * baselined.
+ *
+ * @phpstan-type FilecacheRow array{
* fileid: int,
* storage: int,
* path: string,
@@ -68,17 +74,7 @@
* published: string|null
* }
*
- * @method \OCP\AppFramework\Db\Entity insert(\OCP\AppFramework\Db\Entity $entity)
- * @method \OCP\AppFramework\Db\Entity update(\OCP\AppFramework\Db\Entity $entity)
- * @method \OCP\AppFramework\Db\Entity insertOrUpdate(\OCP\AppFramework\Db\Entity $entity)
- * @method \OCP\AppFramework\Db\Entity delete(\OCP\AppFramework\Db\Entity $entity)
- * @method \OCP\AppFramework\Db\Entity find(int|string $id)
- * @method \OCP\AppFramework\Db\Entity findEntity(IQueryBuilder $query)
- * @method File[] findAll(int|null $limit=null, int|null $offset=null)
- * @method File[] findEntities(IQueryBuilder $query)
- * @psalm-suppress LessSpecificImplementedReturnType - File[] is more specific than list