Compare commits

...

98 Commits

Author SHA1 Message Date
Git'Fellow
9964198a93 fix(session): Ensure token and UID are valid
Wrap token retrieval in try-catch to handle InvalidTokenException.

Signed-off-by: Git'Fellow <12234510+solracsf@users.noreply.github.com>
2025-10-17 12:19:51 +02:00
Nextcloud bot
c316ed655a fix(l10n): Update translations from Transifex
Signed-off-by: Nextcloud bot <bot@nextcloud.com>
2025-10-17 00:12:29 +00:00
Maxence Lange
7da7de8409 Merge pull request #55634 from nextcloud/fix/noid/ocm-value-format
fix(ocm): format notifications
2025-10-16 20:17:21 -01:00
dependabot[bot]
324ae80b4e Merge pull request #55680 from nextcloud/dependabot/npm_and_yarn/nextcloud/vue-8.32.0 2025-10-16 21:14:17 +00:00
nextcloud-command
d6299f93f5 chore(assets): Recompile assets
Signed-off-by: nextcloud-command <nextcloud-command@users.noreply.github.com>
2025-10-16 18:07:05 +00:00
dependabot[bot]
3d08708f13 build(deps): bump @nextcloud/vue from 8.31.0 to 8.32.0
Bumps [@nextcloud/vue](https://github.com/nextcloud-libraries/nextcloud-vue) from 8.31.0 to 8.32.0.
- [Release notes](https://github.com/nextcloud-libraries/nextcloud-vue/releases)
- [Changelog](https://github.com/nextcloud-libraries/nextcloud-vue/blob/v8.32.0/CHANGELOG.md)
- [Commits](https://github.com/nextcloud-libraries/nextcloud-vue/compare/v8.31.0...v8.32.0)

---
updated-dependencies:
- dependency-name: "@nextcloud/vue"
  dependency-version: 8.32.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-16 19:58:41 +02:00
Ferdinand Thiessen
39dc1185a6 Merge pull request #55799 from nextcloud/fix/dialog-props
fix: migrate to non-deprecated dialog props
2025-10-16 19:41:24 +02:00
nextcloud-command
08eb5879dd chore(assets): Recompile assets
Signed-off-by: nextcloud-command <nextcloud-command@users.noreply.github.com>
2025-10-16 16:09:41 +00:00
Ferdinand Thiessen
470ff8d3d3 fix: migrate to non-deprecated dialog props
In Nextcloud Vue v8 some props for dialog buttons were deprecated (type
for e.g. primary or nativeType) those are replaced with `variant` and
`type`.
In v9 the deprecated props are removed - thus this breaks with
nextcloud-dialogs v7 which is based on Vue 3.

Signed-off-by: Ferdinand Thiessen <opensource@fthiessen.de>
2025-10-16 17:55:11 +02:00
dependabot[bot]
093c95f260 Merge pull request #55681 from nextcloud/dependabot/npm_and_yarn/cypress-split-1.24.24 2025-10-16 15:49:13 +00:00
Maxence Lange
b2a6c75b44 fix(ocm): format notifications
Signed-off-by: Maxence Lange <maxence@artificial-owl.com>
2025-10-16 14:30:04 -01:00
Joas Schilling
6fc190ef4c Merge pull request #55803 from nextcloud/bugfix/55274/dont-fallback-from-3letter-languages-to-2letter
fix(l10n): Don't fallback from 3-letter languages to 2-letter
2025-10-16 13:43:13 +02:00
Joas Schilling
9e4ac50206 fix(l10n): Don't fallback from 3-letter languages to 2-letter
Signed-off-by: Joas Schilling <coding@schilljs.com>
2025-10-16 11:46:01 +02:00
Joas Schilling
8b51705b4e Merge pull request #55757 from nextcloud/test/net/localhost-by-ip
test(net): include test for localhost by IP
2025-10-16 11:38:11 +02:00
Marcel Klehr
7320322d52 Merge pull request #55735 from nextcloud/feat/taskprocessing-api-next-batch
feat(TaskProcessingApiController): Add new next_batch endpoint
2025-10-16 09:55:49 +02:00
Arthur Schiwon
84be993633 Merge pull request #55800 from nextcloud/fix/file-drop/chunked-upload
Fix chunked upload for file drop shares
2025-10-16 09:43:22 +02:00
provokateurin
3a242166f7 fix(FilesDropPlugin): Fix request method and nickname header checks
Signed-off-by: provokateurin <kate@provokateurin.de>
2025-10-16 08:47:28 +02:00
Joas Schilling
3f85bcc69a Merge pull request #55777 from nextcloud/bugfix/55706/fix-sample-config-parsing
fix(sample-config): Fix sample config so parsing works again
2025-10-16 08:32:50 +02:00
Nextcloud bot
9938bc70b7 fix(l10n): Update translations from Transifex
Signed-off-by: Nextcloud bot <bot@nextcloud.com>
2025-10-16 00:12:27 +00:00
provokateurin
2201f77aa6 fix(FilesDropPlugin): Fix name conflict resolution for chunked uploads
Signed-off-by: provokateurin <kate@provokateurin.de>
2025-10-15 23:52:05 +02:00
provokateurin
cde80c14d3 fix(FilesDropPlugin): Disable plugin for chunked uploads
Signed-off-by: provokateurin <kate@provokateurin.de>
2025-10-15 23:52:04 +02:00
provokateurin
5fa4c3d8fd fix(publicremote): Always grant read and delete permission for chunked uploads to a share
Signed-off-by: provokateurin <kate@provokateurin.de>
2025-10-15 23:37:58 +02:00
Arthur Schiwon
6df6b58e6c Merge pull request #55797 from nextcloud/fixDbType
fix(setupCheck): Fix checking database type
2025-10-15 22:44:35 +02:00
Andy Scherzinger
6266000b99 Merge pull request #55750 from nextcloud/feat/globalscale-url
feat: add new link endpoint when using globalscale
2025-10-15 21:26:48 +02:00
nextcloud-command
92dab6633c chore(assets): Recompile assets
Signed-off-by: nextcloud-command <nextcloud-command@users.noreply.github.com>
2025-10-15 19:00:59 +00:00
Ferdinand Thiessen
7fbc2ca25e feat: add new link endpoint when using globalscale
Signed-off-by: Ferdinand Thiessen <opensource@fthiessen.de>
2025-10-15 18:58:10 +00:00
Git'Fellow
3f976c2548 fix(setupCheck): Fix checking database type
Signed-off-by: Git'Fellow <12234510+solracsf@users.noreply.github.com>
2025-10-15 20:15:55 +02:00
Ferdinand Thiessen
50f287402a Merge pull request #55791 from nextcloud/chore/ensure-no-only
chore: ensure no `.only` is commited in test files
2025-10-15 17:57:00 +02:00
Joas Schilling
074d69820f fix(sample-config): Fix more typos that break RST parsing
Signed-off-by: Joas Schilling <coding@schilljs.com>
2025-10-15 16:30:49 +02:00
Ferdinand Thiessen
3cf210a9a5 chore: ensure no .only is commited in test files
`.only` is only to be used for development, but must not be committed.
Instead failing tests which should be kept for later should be skipped
(`.skip`).

Signed-off-by: Ferdinand Thiessen <opensource@fthiessen.de>
2025-10-15 16:00:01 +02:00
dependabot[bot]
ac9ff0d3fa build(deps-dev): bump cypress-split from 1.24.23 to 1.24.24
Bumps [cypress-split](https://github.com/bahmutov/cypress-split) from 1.24.23 to 1.24.24.
- [Release notes](https://github.com/bahmutov/cypress-split/releases)
- [Commits](https://github.com/bahmutov/cypress-split/compare/v1.24.23...v1.24.24)

---
updated-dependencies:
- dependency-name: cypress-split
  dependency-version: 1.24.24
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2025-10-15 13:54:49 +00:00
Ferdinand Thiessen
65cdf14667 Merge pull request #55726 from nextcloud/chore/update-dialog-v7
chore: Update `@nextcloud/dialogs` to v7.0.0
2025-10-15 15:51:41 +02:00
Ferdinand Thiessen
cc4f8309d0 chore: compile assets
Signed-off-by: Ferdinand Thiessen <opensource@fthiessen.de>
2025-10-15 14:25:11 +02:00
Ferdinand Thiessen
b3762488e8 test: adjust FilePicker tests to new dialogs version
Signed-off-by: Ferdinand Thiessen <opensource@fthiessen.de>
2025-10-15 14:25:10 +02:00
Ferdinand Thiessen
2b39cb49ab refactor: adjust code for breaking changes in @nextcloud/dialogs v7
Signed-off-by: Ferdinand Thiessen <opensource@fthiessen.de>
2025-10-15 13:45:12 +02:00
Ferdinand Thiessen
f2b309b6ee chore: Update @nextcloud/dialogs to v7.0.0
This is the first step torwards Vue 3.
As this package is a Vue version agnostic version of dialogs, written in
Vue 3.

Signed-off-by: Ferdinand Thiessen <opensource@fthiessen.de>
2025-10-15 13:45:11 +02:00
Marcel Klehr
d5220d6a15 Merge pull request #55776 from nextcloud/fix/text2image-better-attributes
fix(TextToImage): Set better attribute for routes
2025-10-15 13:07:50 +02:00
Ferdinand Thiessen
0c1be89f1b Merge pull request #55747 from nextcloud/chore/migrate-cypress-vitest
refactor(test): migrate Cypress component test to vitest
2025-10-15 10:55:44 +02:00
Stephan Orbaugh
567a988c6c Merge pull request #55100 from invario/previews-better-logging
feat(previews): improved logging for movie previews
2025-10-15 10:54:09 +02:00
Joas Schilling
0938c5f1ce fix(config-sample): Deduplicate warning
Signed-off-by: Joas Schilling <coding@schilljs.com>
2025-10-15 10:47:29 +02:00
Joas Schilling
5ef933ff6c fix(sample-config): Fix more list, note and warning blocks
Signed-off-by: Joas Schilling <coding@schilljs.com>
2025-10-15 10:45:27 +02:00
Marcel Klehr
a5ce35ac84 fix(TextToImage): Set better attribute for routes
Signed-off-by: Marcel Klehr <mklehr@gmx.net>
2025-10-15 09:55:30 +02:00
Joas Schilling
126944b346 fix(sample-config): Fix sample config so parsing works again
Signed-off-by: Joas Schilling <coding@schilljs.com>
2025-10-15 09:38:15 +02:00
Marcel Klehr
7619f78aa2 Merge pull request #55732 from nextcloud/fix/text-processing-no-admin-required
fix(TextProcessingApiController): Set better attribute on routes
2025-10-15 09:31:05 +02:00
Marcel Klehr
81bf9f342c fix: regenerate openapi descriptions
Signed-off-by: Marcel Klehr <mklehr@gmx.net>
2025-10-15 09:30:12 +02:00
Marcel Klehr
954b140da6 Merge pull request #55716 from nextcloud/feat/taskprocessing-successrate-setupcheck
feat(settings): Introduce TaskProcessingSuccessRate setup check
2025-10-15 09:28:36 +02:00
Nextcloud bot
3aae74236a fix(l10n): Update translations from Transifex
Signed-off-by: Nextcloud bot <bot@nextcloud.com>
2025-10-15 00:12:30 +00:00
Daniel
d39ae92aaf Merge pull request #54819 from nextcloud/fix/issue-53949-imip-quirks-mode
fix: iMip reply from outlook.com does not contain organizer property
2025-10-14 21:29:11 +02:00
Côme Chilliet
ef2e7170a4 Merge pull request #55754 from nextcloud/fix/fix-cachewrapper-shouldencrypt
fix: Fix crash in files_version about uninitialized property
2025-10-14 20:32:28 +02:00
invario
13500be1d1 feat(previews): improved logging for movie previews
Signed-off-by: invario <67800603+invario@users.noreply.github.com>
2025-10-14 13:17:09 -04:00
SebastianKrupinski
ea2180d6ad fix: iMip reply from outlook.com does not contain organizer property
Signed-off-by: SebastianKrupinski <krupinskis05@gmail.com>
2025-10-14 12:44:06 -04:00
Carl Schwan
04a21650cc Merge pull request #55720 from nextcloud/carl/remote-querybuilder-execute
feat(querybuilder): Remove deprecated IQueryBuilder::execute
2025-10-14 17:19:37 +02:00
Côme Chilliet
ad9574970a fix: Fix crash in files_version about uninitialized property
Fix "Typed property OC\\Files\\Cache\\Cache::$storage must not be accessed before initialization"

Signed-off-by: Côme Chilliet <come.chilliet@nextcloud.com>
2025-10-14 16:56:07 +02:00
Marcel Klehr
be8e168f38 fix: Address psalm issues and review comments
Signed-off-by: Marcel Klehr <mklehr@gmx.net>
2025-10-14 15:51:31 +02:00
Marcel Klehr
bd2e629e3b fix: Update openapi descriptions
Signed-off-by: Marcel Klehr <mklehr@gmx.net>
2025-10-14 15:29:40 +02:00
Marcel Klehr
5e0c7a5813 fix(TextProcessingApiController): Set better attribute on routes
Signed-off-by: Marcel Klehr <mklehr@gmx.net>
2025-10-14 15:29:40 +02:00
Marcel Klehr
76eba41d77 fix: Fix logic error to make tests pass
Signed-off-by: Marcel Klehr <mklehr@gmx.net>
2025-10-14 15:23:01 +02:00
Marcel Klehr
4ec76cf834 Merge pull request #55715 from nextcloud/fix/taskprocessing/setupcheck-pickupspeed
fix(settings): Improve TaskProcessingPickupSpeed setup check
2025-10-14 15:11:33 +02:00
Marcel Klehr
e7ac6ff71b fix: Apply suggestion from @kyteinski
Signed-off-by: Marcel Klehr <mklehr@gmx.net>
2025-10-14 15:05:55 +02:00
Ferdinand Thiessen
e7357dffec chore: compile assets
Signed-off-by: Ferdinand Thiessen <opensource@fthiessen.de>
2025-10-14 14:32:51 +02:00
Ferdinand Thiessen
a66135f32f chore: remove Cypress component testing
Signed-off-by: Ferdinand Thiessen <opensource@fthiessen.de>
2025-10-14 14:30:14 +02:00
Ferdinand Thiessen
3f6f277dba refactor(test): migrate component tests in core to vitest
Signed-off-by: Ferdinand Thiessen <opensource@fthiessen.de>
2025-10-14 14:30:14 +02:00
Ferdinand Thiessen
81cfb9580a refactor(test): migrate cypress component tests to vitest
Signed-off-by: Ferdinand Thiessen <opensource@fthiessen.de>
2025-10-14 14:30:14 +02:00
Ferdinand Thiessen
5aa1f5bb84 Merge pull request #55718 from nextcloud/chore/remove-oca-sharing-external-link-actions
chore!(files_sharing): remove deprecated `OCA.Sharing.ExternalLinkActions`
2025-10-14 14:25:53 +02:00
Ferdinand Thiessen
48378aede3 Merge pull request #55731 from nextcloud/jtr/fix-files-stream-quota-actual
fix(files): decrement quota by actual bytes written in stream_write
2025-10-14 13:56:27 +02:00
nextcloud-command
9aa38aaacc chore(assets): Recompile assets
Signed-off-by: nextcloud-command <nextcloud-command@users.noreply.github.com>
2025-10-14 11:41:49 +00:00
Ferdinand Thiessen
23be816568 chore!(files_sharing): remove deprecated OCA.Sharing.ExternalLinkActions
This API was deprecated in Nextcloud 23.
It was replaced with `OCA.Sharing.ExternalShareAction` which now have a proper API
by using `registerSidebarAction` from `@nextcloud/sharing` instead.

Signed-off-by: Ferdinand Thiessen <opensource@fthiessen.de>
2025-10-14 13:34:54 +02:00
Marcel Klehr
5c5c9384b1 fix: Apply suggestion from @julien-nc
Co-authored-by: Julien Veyssier <julien-nc@posteo.net>
Signed-off-by: Marcel Klehr <mklehr@gmx.net>
2025-10-14 11:52:49 +02:00
Marcel Klehr
f7a89fee24 fix: Apply suggestion from @julien-nc
Co-authored-by: Julien Veyssier <julien-nc@posteo.net>
Signed-off-by: Marcel Klehr <mklehr@gmx.net>
2025-10-14 11:52:37 +02:00
Marcel Klehr
16da8bbc8a fix(TaskProcessingApiController): Implement getNextScheduledTasks for next_batch endpoint
in order to avoid hitting the DB with multiple 1 row requests

Signed-off-by: Marcel Klehr <mklehr@gmx.net>
2025-10-14 11:50:29 +02:00
Marcel Klehr
858118274d fix: Apply suggestion from @julien-nc
Co-authored-by: Julien Veyssier <julien-nc@posteo.net>
Signed-off-by: Marcel Klehr <mklehr@gmx.net>
2025-10-14 11:22:03 +02:00
Marcel Klehr
2286b9f57d fix: Apply suggestion from @julien-nc
Co-authored-by: Julien Veyssier <julien-nc@posteo.net>
Signed-off-by: Marcel Klehr <mklehr@gmx.net>
2025-10-14 11:21:54 +02:00
Marcel Klehr
1ba5f7d53a fix(settings): Remove copypasta
Signed-off-by: Marcel Klehr <mklehr@gmx.net>
2025-10-14 11:20:59 +02:00
Maksim Sukharev
8659002d7a Merge pull request #55655 from nextcloud/fix/noid/throw-failed-share 2025-10-14 11:03:48 +02:00
Christoph Wurst
3e90ce89eb test(net): include test for localhost by IP
Signed-off-by: Christoph Wurst <christoph@winzerhof-wurst.at>
2025-10-14 10:33:35 +02:00
Kate
ae0aa175b3 Merge pull request #55661 from nextcloud/fix/55519/ldap-cert-req-handling 2025-10-14 09:42:16 +02:00
nextcloud-command
9e5111f983 chore(assets): Recompile assets
Signed-off-by: nextcloud-command <nextcloud-command@users.noreply.github.com>
2025-10-14 07:36:00 +00:00
Marcel Klehr
80eb3dd0d0 feat(TaskProcessingApiController): Add new next_batch endpoint
Signed-off-by: Marcel Klehr <mklehr@gmx.net>
2025-10-14 09:35:18 +02:00
Maksim Sukharev
a4d440e1f0 fix(files_sharing): correctly handle error in case of failing share creation
Signed-off-by: Maksim Sukharev <antreesy.web@gmail.com>
2025-10-14 09:27:05 +02:00
Maksim Sukharev
9c8b500116 Merge pull request #55666 from nextcloud/fix/53038/clear-search 2025-10-14 09:22:50 +02:00
Marcel Klehr
33922faf4a fix: Change messages to use days instead of hours
Signed-off-by: Marcel Klehr <mklehr@gmx.net>
2025-10-14 08:42:56 +02:00
Marcel Klehr
ea8ab8e192 Merge pull request #55646 from nextcloud/feat/taskprocessing/is-internal
enh(TaskProcessing): Introduce internal task types
2025-10-14 08:25:00 +02:00
Kate
ffbbdb2d04 Merge pull request #54953 from nextcloud/fix/noid/lighter-team-request 2025-10-14 07:56:14 +02:00
Nextcloud bot
736259c4df fix(l10n): Update translations from Transifex
Signed-off-by: Nextcloud bot <bot@nextcloud.com>
2025-10-14 00:12:22 +00:00
Josh
bd43cb7d04 fix(files): decrement quota by actual bytes written in stream_write
The quota is now decremented by the actual number of bytes written ($written) rather than the intended size.

This ensures quota tracking stays accurate even if fwrite writes fewer (or more - i.e. from underlying buffering/etc) bytes than requested.

Signed-off-by: Josh <josh.t.richards@gmail.com>
2025-10-13 18:26:48 -04:00
Kate
692d265d4a Merge pull request #55727 from nextcloud/bug/noid/update-sample-config-mp3 2025-10-13 18:46:21 +02:00
nextcloud-command
4e87741bab chore(assets): Recompile assets
Signed-off-by: nextcloud-command <nextcloud-command@users.noreply.github.com>
2025-10-13 16:12:38 +00:00
Daniel Kesselberg
8ed6722a4b docs(previews): mp3 preview provider is no longer enabled by default
Signed-off-by: Daniel Kesselberg <mail@danielkesselberg.de>
2025-10-13 17:53:34 +02:00
Maksim Sukharev
196aa9b41b fix(files): clear search input on directory navigation
Signed-off-by: Maksim Sukharev <antreesy.web@gmail.com>
2025-10-13 17:28:44 +02:00
Carl Schwan
1eff9e5c90 feat(querybuilder): Remove deprecated IQueryBuilder::execute
This won't work when we update to doctrine DBAL 4 and all usages in
server were ported away.

Signed-off-by: Carl Schwan <carl.schwan@nextcloud.com>
2025-10-13 17:02:04 +02:00
Marcel Klehr
f296f9055c fix: Run cs:fix
Signed-off-by: Marcel Klehr <mklehr@gmx.net>
2025-10-13 14:45:17 +02:00
Marcel Klehr
62fd3576c9 test(settings): Add tests for TaskProcessingSuccessRate setup check
Signed-off-by: Marcel Klehr <mklehr@gmx.net>
2025-10-13 14:42:51 +02:00
Marcel Klehr
6c9af3f8ee fix(settings): Introduce TaskProcessingSuccessRate setup check
Signed-off-by: Marcel Klehr <mklehr@gmx.net>
2025-10-13 14:35:55 +02:00
Maxence Lange
9ba3ce27cb fix(team-api): get all teams details in a single request
Signed-off-by: Maxence Lange <maxence@artificial-owl.com>
Signed-off-by: provokateurin <kate@provokateurin.de>
2025-10-13 14:21:15 +02:00
Marcel Klehr
5a48887a2b fix(settings): Improve TaskProcessingPickupSpeed setup check
Signed-off-by: Marcel Klehr <mklehr@gmx.net>
2025-10-13 14:07:33 +02:00
provokateurin
2552950299 fix(core): Fix TeamsApiController typing
Signed-off-by: provokateurin <kate@provokateurin.de>
2025-10-13 13:59:54 +02:00
Marcel Klehr
13eb2d1cbd feat(TaskProcessing): Introduce internal task types
which are not shown in the assistant UI

Signed-off-by: Marcel Klehr <mklehr@gmx.net>
2025-10-13 11:07:40 +02:00
Arthur Schiwon
fbd29bcf7f fix(LDAP): properly disable are require TLS certificate verification
- the old approach lead connection issues, as ldap_set_option was called
  too late. Specifically it needs to be called before ldap_connect and set
  globally!
- The old approach also connected it to the ldapTLS configuration, which
  has a misleading naming. It indicates StartTLS usage only, not plain TLS
  connections.

Signed-off-by: Arthur Schiwon <blizzz@arthur-schiwon.de>
2025-10-09 20:22:37 +02:00
662 changed files with 40953 additions and 4246 deletions

View File

@@ -102,8 +102,8 @@ jobs:
matrix:
# Run multiple copies of the current job in parallel
# Please increase the number or runners as your tests suite grows (0 based index for e2e tests)
containers: ['component', 'setup', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9']
# Hack as strategy.job-total includes the component and GitHub does not allow math expressions
containers: ['setup', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9']
# Hack as strategy.job-total includes the "setup" and GitHub does not allow math expressions
# Always align this number with the total of e2e runners (max. index + 1)
total-containers: [10]

View File

@@ -84,9 +84,10 @@ jobs:
ports:
- 6379:6379/tcp
openldap:
image: ghcr.io/nextcloud/continuous-integration-openldap:openldap-7 # zizmor: ignore[unpinned-images]
image: ghcr.io/nextcloud/continuous-integration-openldap:openldap-8 # zizmor: ignore[unpinned-images]
ports:
- 389:389
- 636:636
env:
SLAPD_DOMAIN: nextcloud.ci
SLAPD_ORGANIZATION: Nextcloud

View File

@@ -2,6 +2,7 @@
* SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: CC0-1.0
*/
export function setup() {
process.env.TZ = 'UTC'
}

View File

@@ -2,5 +2,6 @@
* SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: CC0-1.0
*/
import '@testing-library/jest-dom/vitest'
import 'core-js/stable/index.js'

View File

@@ -17,6 +17,7 @@ OC.L10N.register(
"Delete comment" : "Slet kommentar",
"Cancel edit" : "Annullér redigering",
"New comment" : "Ny kommentar",
"Write a comment …" : "Skriv kommentar …",
"Post comment" : "Skriv kommentar",
"@ for mentions, : for emoji, / for smart picker" : "\"@\" for at omtale, \":\" for emojis, \"/\" for Smart Vælger",
"Could not reload comments" : "Kunne ikke indlæse kommentarer",

View File

@@ -15,6 +15,7 @@
"Delete comment" : "Slet kommentar",
"Cancel edit" : "Annullér redigering",
"New comment" : "Ny kommentar",
"Write a comment …" : "Skriv kommentar …",
"Post comment" : "Skriv kommentar",
"@ for mentions, : for emoji, / for smart picker" : "\"@\" for at omtale, \":\" for emojis, \"/\" for Smart Vælger",
"Could not reload comments" : "Kunne ikke indlæse kommentarer",

View File

@@ -17,7 +17,7 @@ OC.L10N.register(
"Delete comment" : "Kommentar löschen",
"Cancel edit" : "Bearbeiten abbrechen",
"New comment" : "Neuer Kommentar",
"Write a comment …" : "Schreiben Sie einen Kommentar  …",
"Write a comment …" : "Einen Kommentar schreiben …",
"Post comment" : "Kommentar veröffentlichen",
"@ for mentions, : for emoji, / for smart picker" : "@ für Erwähnungen, : für Emoji, / für Smart Picker",
"Could not reload comments" : "Kommentare konnten nicht erneut geladen werden",

View File

@@ -15,7 +15,7 @@
"Delete comment" : "Kommentar löschen",
"Cancel edit" : "Bearbeiten abbrechen",
"New comment" : "Neuer Kommentar",
"Write a comment …" : "Schreiben Sie einen Kommentar  …",
"Write a comment …" : "Einen Kommentar schreiben …",
"Post comment" : "Kommentar veröffentlichen",
"@ for mentions, : for emoji, / for smart picker" : "@ für Erwähnungen, : für Emoji, / für Smart Picker",
"Could not reload comments" : "Kommentare konnten nicht erneut geladen werden",

View File

@@ -17,6 +17,7 @@ OC.L10N.register(
"Delete comment" : "Вилучити коментар",
"Cancel edit" : "Скасувати редагування",
"New comment" : "Новий коментар",
"Write a comment …" : "Додайте коментар …",
"Post comment" : "Опублікувати коментар",
"@ for mentions, : for emoji, / for smart picker" : "@ згадати, : емоційки, / асистент вибору",
"Could not reload comments" : "Не вдалося перезавантажити коментарі",

View File

@@ -15,6 +15,7 @@
"Delete comment" : "Вилучити коментар",
"Cancel edit" : "Скасувати редагування",
"New comment" : "Новий коментар",
"Write a comment …" : "Додайте коментар …",
"Post comment" : "Опублікувати коментар",
"@ for mentions, : for emoji, / for smart picker" : "@ згадати, : емоційки, / асистент вибору",
"Could not reload comments" : "Не вдалося перезавантажити коментарі",

View File

@@ -20,6 +20,7 @@ OC.L10N.register(
"Edit widgets" : "Tilpas widgets",
"Get more widgets from the App Store" : "Få flere widgets fra App Store",
"Weather service" : "Vejret",
"For your privacy, the weather data is requested by your {productName} server on your behalf so the weather service receives no personal information." : "Af hensyn til dit privatliv anmoder din {productName} server om vejrdata på dine vegne, så vejrtjenesten ikke modtager personlige oplysninger.",
"Weather data from Met.no" : "Vejr-data leveres af Met.no",
"geocoding with Nominatim" : "Geocoding med Nominatim",
"elevation data from OpenTopoData" : "Højde-data fra OpenTopoData",

View File

@@ -18,6 +18,7 @@
"Edit widgets" : "Tilpas widgets",
"Get more widgets from the App Store" : "Få flere widgets fra App Store",
"Weather service" : "Vejret",
"For your privacy, the weather data is requested by your {productName} server on your behalf so the weather service receives no personal information." : "Af hensyn til dit privatliv anmoder din {productName} server om vejrdata på dine vegne, så vejrtjenesten ikke modtager personlige oplysninger.",
"Weather data from Met.no" : "Vejr-data leveres af Met.no",
"geocoding with Nominatim" : "Geocoding med Nominatim",
"elevation data from OpenTopoData" : "Højde-data fra OpenTopoData",

View File

@@ -81,7 +81,7 @@ $linkCheckPlugin = new PublicLinkCheckPlugin();
$filesDropPlugin = new FilesDropPlugin();
/** @var string $baseuri defined in public.php */
$server = $serverFactory->createServer(true, $baseuri, $requestUri, $authPlugin, function (\Sabre\DAV\Server $server) use ($authBackend, $linkCheckPlugin, $filesDropPlugin) {
$server = $serverFactory->createServer(true, $baseuri, $requestUri, $authPlugin, function (\Sabre\DAV\Server $server) use ($baseuri, $requestUri, $authBackend, $linkCheckPlugin, $filesDropPlugin) {
// GET must be allowed for e.g. showing images and allowing Zip downloads
if ($server->httpRequest->getMethod() !== 'GET') {
// If this is *not* a GET request we only allow access to public DAV from AJAX or when Server2Server is allowed
@@ -103,8 +103,16 @@ $server = $serverFactory->createServer(true, $baseuri, $requestUri, $authPlugin,
$previousLog = Filesystem::logWarningWhenAddingStorageWrapper(false);
/** @psalm-suppress MissingClosureParamType */
Filesystem::addStorageWrapper('sharePermissions', function ($mountPoint, $storage) use ($share) {
return new PermissionsMask(['storage' => $storage, 'mask' => $share->getPermissions() | Constants::PERMISSION_SHARE]);
Filesystem::addStorageWrapper('sharePermissions', function ($mountPoint, $storage) use ($requestUri, $baseuri, $share) {
$mask = $share->getPermissions() | Constants::PERMISSION_SHARE;
// For chunked uploads it is necessary to have read and delete permission,
// so the temporary directory, chunks and destination file can be read and delete after the assembly.
if (str_starts_with(substr($requestUri, strlen($baseuri) - 1), '/uploads/')) {
$mask |= Constants::PERMISSION_READ | Constants::PERMISSION_DELETE;
}
return new PermissionsMask(['storage' => $storage, 'mask' => $mask]);
});
/** @psalm-suppress MissingClosureParamType */

View File

@@ -252,6 +252,7 @@ OC.L10N.register(
"Completed on %s" : "Dokončeno %s",
"Due on %s by %s" : "Termín do %s od %s",
"Due on %s" : "Termín do %s",
"Welcome to Nextcloud Calendar!\n\nThis is a sample event - explore the flexibility of planning with Nextcloud Calendar by making any edits you want!\n\nWith Nextcloud Calendar, you can:\n- Create, edit, and manage events effortlessly.\n- Create multiple calendars and share them with teammates, friends, or family.\n- Check availability and display your busy times to others.\n- Seamlessly integrate with apps and devices via CalDAV.\n- Customize your experience: schedule recurring events, adjust notifications and other settings." : "Vítejte v Nextcloud Kalendáři!\n\nToto je událost pro ukázku prozkoumejte flexibilitu plánování pomoc Nextcloud Kalendáře upravením čeho chcete!\n\nS Nextcloud Kalendářem je možné:\n- Jednoduše vytvářet, upravovat a spravovat události.\n- Vytvářet vícero kalendářů a sdílet je s kolegy, přáteli či rodinou.\n- Zjišťovat dostupnost a zobrazovat své doby nedostupnosti ostatním.\n- Hladce napojovat na aplikace a zřízení prostřednictvím CalDAV.\n- Přizpůsobit si svůj dojem z používání: plánovat opakující se události, upravovat notifikace a ostatní nastavení.",
"Example event - open me!" : "Událost pro ukázku otevřete ji!",
"System Address Book" : "Systémový adresář kontaktů",
"The system address book contains contact information for all users in your instance." : "Systémový adresář kontaktů obsahuje informace pro všechny uživatele ve vámi využívané instanci.",

View File

@@ -250,6 +250,7 @@
"Completed on %s" : "Dokončeno %s",
"Due on %s by %s" : "Termín do %s od %s",
"Due on %s" : "Termín do %s",
"Welcome to Nextcloud Calendar!\n\nThis is a sample event - explore the flexibility of planning with Nextcloud Calendar by making any edits you want!\n\nWith Nextcloud Calendar, you can:\n- Create, edit, and manage events effortlessly.\n- Create multiple calendars and share them with teammates, friends, or family.\n- Check availability and display your busy times to others.\n- Seamlessly integrate with apps and devices via CalDAV.\n- Customize your experience: schedule recurring events, adjust notifications and other settings." : "Vítejte v Nextcloud Kalendáři!\n\nToto je událost pro ukázku prozkoumejte flexibilitu plánování pomoc Nextcloud Kalendáře upravením čeho chcete!\n\nS Nextcloud Kalendářem je možné:\n- Jednoduše vytvářet, upravovat a spravovat události.\n- Vytvářet vícero kalendářů a sdílet je s kolegy, přáteli či rodinou.\n- Zjišťovat dostupnost a zobrazovat své doby nedostupnosti ostatním.\n- Hladce napojovat na aplikace a zřízení prostřednictvím CalDAV.\n- Přizpůsobit si svůj dojem z používání: plánovat opakující se události, upravovat notifikace a ostatní nastavení.",
"Example event - open me!" : "Událost pro ukázku otevřete ji!",
"System Address Book" : "Systémový adresář kontaktů",
"The system address book contains contact information for all users in your instance." : "Systémový adresář kontaktů obsahuje informace pro všechny uživatele ve vámi využívané instanci.",

View File

@@ -220,6 +220,8 @@ OC.L10N.register(
"{actor} updated contact {card} in address book {addressbook}" : "{actor} opdaterede kontakten {card} i adressebog {addressbook}",
"You updated contact {card} in address book {addressbook}" : "Du opdaterede kontakten {card} i adressebog {addressbook}",
"A <strong>contact</strong> or <strong>address book</strong> was modified" : "En <strong>kontakt</strong> eller <strong>adressebog</strong> blev ændret",
"System address book disabled" : "Systemadressebog deaktiveret",
"The system contacts address book has been automatically disabled during upgrade. This means that the address book will no longer be available to users in the contacts app or other clients. The system contacts address book was disabled because the amount of contacts in the address book exceeded the maximum recommended number of contacts. This limit is set to prevent performance issues. You can re-enable the system address book with the following command {command}" : "Adressebogen for systemkontakter er automatisk blevet deaktiveret under opgraderingen. Det betyder, at adressebogen ikke længere vil være tilgængelig for brugere i kontaktappen eller andre klienter. Adressebogen for systemkontakter blev deaktiveret, fordi antallet af kontakter i adressebogen oversteg det maksimale anbefalede antal kontakter. Denne grænse er indstillet for at forhindre problemer med ydeevnen. Du kan genaktivere systemadressebogen med følgende kommando {command}",
"Accounts" : "Konti",
"System address book which holds all accounts" : "Systemets adressebog, som indeholder alle konti",
"File is not updatable: %1$s" : "Filen kan ikke updateres: %1$s",
@@ -258,6 +260,10 @@ OC.L10N.register(
"DAV system address book" : "DAV system adressebog",
"No outstanding DAV system address book sync." : "Ingen udestående synkronisering af DAV-systemets adressebog.",
"The DAV system address book sync has not run yet as your instance has more than 1000 users or because an error occurred. Please run it manually by calling \"occ dav:sync-system-addressbook\"." : "DAV-systemets adressebogssynkronisering er ikke kørt endnu, da din instans har mere end 1000 brugere, eller fordi der opstod en fejl. Kør det manuelt ved at kalde \"occ dav:sync-system-addressbook\".",
"DAV system address book size" : "Størrelse på DAV-systemets adressebog",
"The system address book is disabled" : "Systemets adressebog er deaktiveret",
"The system address book is enabled, but contains more than the configured limit of %d contacts" : "Systemadressebogen er aktiveret, men indeholder mere end den konfigurerede grænse på %d kontakter",
"The system address book is enabled and contains less than the configured limit of %d contacts" : "Systemadressebogen er aktiveret og indeholder mindre end den konfigurerede grænse på %d kontakter",
"WebDAV endpoint" : "WebDAV endpoint",
"Could not check that your web server is properly set up to allow file synchronization over WebDAV. Please check manually." : "Kunne ikke kontrollere, at din webserver er korrekt konfigureret til at tillade filsynkronisering over WebDAV. Tjek venligst manuelt.",
"Your web server is not yet properly set up to allow file synchronization, because the WebDAV interface seems to be broken." : "Din webserver er endnu ikke sat korrekt op til at tillade filsynkronisering, fordi WebDAV-grænsefladen ser ud til at være i stykker.",

View File

@@ -218,6 +218,8 @@
"{actor} updated contact {card} in address book {addressbook}" : "{actor} opdaterede kontakten {card} i adressebog {addressbook}",
"You updated contact {card} in address book {addressbook}" : "Du opdaterede kontakten {card} i adressebog {addressbook}",
"A <strong>contact</strong> or <strong>address book</strong> was modified" : "En <strong>kontakt</strong> eller <strong>adressebog</strong> blev ændret",
"System address book disabled" : "Systemadressebog deaktiveret",
"The system contacts address book has been automatically disabled during upgrade. This means that the address book will no longer be available to users in the contacts app or other clients. The system contacts address book was disabled because the amount of contacts in the address book exceeded the maximum recommended number of contacts. This limit is set to prevent performance issues. You can re-enable the system address book with the following command {command}" : "Adressebogen for systemkontakter er automatisk blevet deaktiveret under opgraderingen. Det betyder, at adressebogen ikke længere vil være tilgængelig for brugere i kontaktappen eller andre klienter. Adressebogen for systemkontakter blev deaktiveret, fordi antallet af kontakter i adressebogen oversteg det maksimale anbefalede antal kontakter. Denne grænse er indstillet for at forhindre problemer med ydeevnen. Du kan genaktivere systemadressebogen med følgende kommando {command}",
"Accounts" : "Konti",
"System address book which holds all accounts" : "Systemets adressebog, som indeholder alle konti",
"File is not updatable: %1$s" : "Filen kan ikke updateres: %1$s",
@@ -256,6 +258,10 @@
"DAV system address book" : "DAV system adressebog",
"No outstanding DAV system address book sync." : "Ingen udestående synkronisering af DAV-systemets adressebog.",
"The DAV system address book sync has not run yet as your instance has more than 1000 users or because an error occurred. Please run it manually by calling \"occ dav:sync-system-addressbook\"." : "DAV-systemets adressebogssynkronisering er ikke kørt endnu, da din instans har mere end 1000 brugere, eller fordi der opstod en fejl. Kør det manuelt ved at kalde \"occ dav:sync-system-addressbook\".",
"DAV system address book size" : "Størrelse på DAV-systemets adressebog",
"The system address book is disabled" : "Systemets adressebog er deaktiveret",
"The system address book is enabled, but contains more than the configured limit of %d contacts" : "Systemadressebogen er aktiveret, men indeholder mere end den konfigurerede grænse på %d kontakter",
"The system address book is enabled and contains less than the configured limit of %d contacts" : "Systemadressebogen er aktiveret og indeholder mindre end den konfigurerede grænse på %d kontakter",
"WebDAV endpoint" : "WebDAV endpoint",
"Could not check that your web server is properly set up to allow file synchronization over WebDAV. Please check manually." : "Kunne ikke kontrollere, at din webserver er korrekt konfigureret til at tillade filsynkronisering over WebDAV. Tjek venligst manuelt.",
"Your web server is not yet properly set up to allow file synchronization, because the WebDAV interface seems to be broken." : "Din webserver er endnu ikke sat korrekt op til at tillade filsynkronisering, fordi WebDAV-grænsefladen ser ud til at være i stykker.",

View File

@@ -308,14 +308,14 @@ OC.L10N.register(
"Reset to default" : "Auf Standard zurücksetzen ",
"Import contacts" : "Kontakte importieren",
"Importing a new .vcf file will delete the existing default contact and replace it with the new one. Do you want to continue?" : "Durch das Importieren einer neuen VCF-Datei wird der vorhandene Standardkontakt gelöscht und durch den neuen ersetzt. Fortsetzen?",
"Failed to save example event creation setting" : "Einstellung für die Beispiels-Ereigniserstellung konnte nicht gespeichert werden",
"Failed to upload the example event" : "Das Beispielsereignis konnte nicht hochgeladen werden",
"Custom example event was saved successfully" : "Benutzerdefiniertes Beispielereignis gespeichert",
"Failed to delete the custom example event" : "Benutzerdefiniertes Beispielsereignis konnte nicht gelöscht werden",
"Custom example event was deleted successfully" : "Benutzerdefiniertes Beispielsereignis wurde gelöscht",
"Failed to save example event creation setting" : "Einstellung für die Beispiels-Terminerstellung konnte nicht gespeichert werden",
"Failed to upload the example event" : "Der Beispieltermin konnte nicht hochgeladen werden",
"Custom example event was saved successfully" : "Benutzerdefinierter Beispieltermin gespeichert",
"Failed to delete the custom example event" : "Benutzerdefinierter Beispieltermin konnte nicht gelöscht werden",
"Custom example event was deleted successfully" : "Benutzerdefinierter Beispieltermin wurde gelöscht",
"Import calendar event" : "Kalenderereignis importieren",
"Uploading a new event will overwrite the existing one." : "Das Hochladen eines neuen Ereignisses wird das bestehende Ereignis überschreiben.",
"Upload event" : "Ereignis hochladen",
"Uploading a new event will overwrite the existing one." : "Das Hochladen eines neuen Termins wird den bestehenden Termin überschreiben.",
"Upload event" : "Termin hochladen",
"Availability" : "Verfügbarkeit",
"If you configure your working hours, other people will see when you are out of office when they book a meeting." : "Wenn du deine Arbeitszeiten angibst, können andere beim Buchen einer Besprechung sehen, wann du nicht im Büro bist.",
"Absence" : "Abwesenheit",

View File

@@ -306,14 +306,14 @@
"Reset to default" : "Auf Standard zurücksetzen ",
"Import contacts" : "Kontakte importieren",
"Importing a new .vcf file will delete the existing default contact and replace it with the new one. Do you want to continue?" : "Durch das Importieren einer neuen VCF-Datei wird der vorhandene Standardkontakt gelöscht und durch den neuen ersetzt. Fortsetzen?",
"Failed to save example event creation setting" : "Einstellung für die Beispiels-Ereigniserstellung konnte nicht gespeichert werden",
"Failed to upload the example event" : "Das Beispielsereignis konnte nicht hochgeladen werden",
"Custom example event was saved successfully" : "Benutzerdefiniertes Beispielereignis gespeichert",
"Failed to delete the custom example event" : "Benutzerdefiniertes Beispielsereignis konnte nicht gelöscht werden",
"Custom example event was deleted successfully" : "Benutzerdefiniertes Beispielsereignis wurde gelöscht",
"Failed to save example event creation setting" : "Einstellung für die Beispiels-Terminerstellung konnte nicht gespeichert werden",
"Failed to upload the example event" : "Der Beispieltermin konnte nicht hochgeladen werden",
"Custom example event was saved successfully" : "Benutzerdefinierter Beispieltermin gespeichert",
"Failed to delete the custom example event" : "Benutzerdefinierter Beispieltermin konnte nicht gelöscht werden",
"Custom example event was deleted successfully" : "Benutzerdefinierter Beispieltermin wurde gelöscht",
"Import calendar event" : "Kalenderereignis importieren",
"Uploading a new event will overwrite the existing one." : "Das Hochladen eines neuen Ereignisses wird das bestehende Ereignis überschreiben.",
"Upload event" : "Ereignis hochladen",
"Uploading a new event will overwrite the existing one." : "Das Hochladen eines neuen Termins wird den bestehenden Termin überschreiben.",
"Upload event" : "Termin hochladen",
"Availability" : "Verfügbarkeit",
"If you configure your working hours, other people will see when you are out of office when they book a meeting." : "Wenn du deine Arbeitszeiten angibst, können andere beim Buchen einer Besprechung sehen, wann du nicht im Büro bist.",
"Absence" : "Abwesenheit",

View File

@@ -42,6 +42,10 @@ class FilesDropPlugin extends ServerPlugin {
}
public function onMkcol(RequestInterface $request, ResponseInterface $response) {
if ($this->isChunkedUpload($request)) {
return;
}
if (!$this->enabled || $this->share === null) {
return;
}
@@ -58,7 +62,18 @@ class FilesDropPlugin extends ServerPlugin {
return false;
}
private function isChunkedUpload(RequestInterface $request): bool {
return str_starts_with(substr($request->getUrl(), strlen($request->getBaseUrl()) - 1), '/uploads/');
}
public function beforeMethod(RequestInterface $request, ResponseInterface $response) {
$isChunkedUpload = $this->isChunkedUpload($request);
// For the final MOVE request of a chunked upload it is necessary to modify the Destination header.
if ($isChunkedUpload && $request->getMethod() !== 'MOVE') {
return;
}
if (!$this->enabled || $this->share === null) {
return;
}
@@ -68,21 +83,8 @@ class FilesDropPlugin extends ServerPlugin {
return;
}
// Retrieve the nickname from the request
$nickname = $request->hasHeader('X-NC-Nickname')
? trim(urldecode($request->getHeader('X-NC-Nickname')))
: null;
if ($request->getMethod() !== 'PUT') {
// If uploading subfolders we need to ensure they get created
// within the nickname folder
if ($request->getMethod() === 'MKCOL') {
if (!$nickname) {
throw new BadRequest('A nickname header is required when uploading subfolders');
}
} else {
throw new MethodNotAllowed('Only PUT is allowed on files drop');
}
if ($request->getMethod() !== 'PUT' && $request->getMethod() !== 'MKCOL' && (!$isChunkedUpload || $request->getMethod() !== 'MOVE')) {
throw new MethodNotAllowed('Only PUT, MKCOL and MOVE are allowed on files drop');
}
// If this is a folder creation request
@@ -95,8 +97,16 @@ class FilesDropPlugin extends ServerPlugin {
// full path along the way. We'll only handle conflict
// resolution on file conflicts, but not on folders.
// e.g files/dCP8yn3N86EK9sL/Folder/image.jpg
$path = $request->getPath();
if ($isChunkedUpload) {
$destination = $request->getHeader('destination');
$baseUrl = $request->getBaseUrl();
// e.g files/dCP8yn3N86EK9sL/Folder/image.jpg
$path = substr($destination, strpos($destination, $baseUrl) + strlen($baseUrl));
} else {
// e.g files/dCP8yn3N86EK9sL/Folder/image.jpg
$path = $request->getPath();
}
$token = $this->share->getToken();
// e.g files/dCP8yn3N86EK9sL
@@ -112,6 +122,11 @@ class FilesDropPlugin extends ServerPlugin {
$isFileRequest = $attributes->getAttribute('fileRequest', 'enabled') === true;
}
// Retrieve the nickname from the request
$nickname = $request->hasHeader('X-NC-Nickname')
? trim(urldecode($request->getHeader('X-NC-Nickname')))
: null;
// We need a valid nickname for file requests
if ($isFileRequest && !$nickname) {
throw new BadRequest('A nickname header is required for file requests');
@@ -187,7 +202,11 @@ class FilesDropPlugin extends ServerPlugin {
$relativePath = substr($folder->getPath(), strlen($node->getPath()));
$path = '/files/' . $token . '/' . $relativePath . '/' . $uniqueName;
$url = rtrim($request->getBaseUrl(), '/') . str_replace('//', '/', $path);
$request->setUrl($url);
if ($isChunkedUpload) {
$request->setHeader('destination', $url);
} else {
$request->setUrl($url);
}
}
private function getPathSegments(string $path): array {

View File

@@ -98,8 +98,8 @@ export default {
},
{
label: this.$t('dav', 'Import'),
type: 'primary',
icon: IconCheck,
variant: 'primary',
callback: () => { this.clickImportInput() },
},
],

View File

@@ -13,7 +13,6 @@ use OCP\Files\NotFoundException;
use OCP\Share\IAttributes;
use OCP\Share\IShare;
use PHPUnit\Framework\MockObject\MockObject;
use Sabre\DAV\Exception\BadRequest;
use Sabre\DAV\Server;
use Sabre\HTTP\RequestInterface;
use Sabre\HTTP\ResponseInterface;
@@ -56,13 +55,6 @@ class FilesDropPluginTest extends TestCase {
->willReturn('token');
}
public function testNotEnabled(): void {
$this->request->expects($this->never())
->method($this->anything());
$this->plugin->beforeMethod($this->request, $this->response);
}
public function testValid(): void {
$this->plugin->enable();
$this->plugin->setShare($this->share);
@@ -112,32 +104,13 @@ class FilesDropPluginTest extends TestCase {
$this->plugin->beforeMethod($this->request, $this->response);
}
public function testNoMKCOLWithoutNickname(): void {
public function testMKCOL(): void {
$this->plugin->enable();
$this->plugin->setShare($this->share);
$this->request->method('getMethod')
->willReturn('MKCOL');
$this->expectException(BadRequest::class);
$this->plugin->beforeMethod($this->request, $this->response);
}
public function testMKCOLWithNickname(): void {
$this->plugin->enable();
$this->plugin->setShare($this->share);
$this->request->method('getMethod')
->willReturn('MKCOL');
$this->request->method('hasHeader')
->with('X-NC-Nickname')
->willReturn(true);
$this->request->method('getHeader')
->with('X-NC-Nickname')
->willReturn('nickname');
$this->expectNotToPerformAssertions();
$this->plugin->beforeMethod($this->request, $this->response);

View File

@@ -34,6 +34,7 @@ OC.L10N.register(
"Please login to the web interface, go to the \"Security\" section of your personal settings and update your encryption password by entering this password into the \"Old login password\" field and your current login password." : "Log venligst ind på webgrænsefladen, gå til afsnittet \"Sikkerhed\" i dine personlige indstillinger og opdater din krypteringsadgangskode ved at indtaste denne adgangskode i feltet \"Gammel loginadgangskode\" og din nuværende loginadgangskode.",
"Cannot decrypt this file, probably this is a shared file. Please ask the file owner to reshare the file with you." : "Kan ikke dekryptere denne fil, sandsynligvis er dette en delt fil. Bed filejeren om at videredele filen med dig.",
"Cannot read this file, probably this is a shared file. Please ask the file owner to reshare the file with you." : "Kan ikke læse denne fil, sandsynligvis er dette en delt fil. Bed filejeren om at videredele filen med dig.",
"Default Encryption Module" : "Standard krypteringsmodul",
"Default encryption module" : "Standard krypterings modul",
"Encryption app is enabled but your keys are not initialized, please log-out and log-in again" : "Krypteringsprogrammet er aktiveret men dine nøgler er ikke indlæst, log venligst ud og ind igen",
"Encrypt the home storage" : "Krypter hjemmelageret",

View File

@@ -32,6 +32,7 @@
"Please login to the web interface, go to the \"Security\" section of your personal settings and update your encryption password by entering this password into the \"Old login password\" field and your current login password." : "Log venligst ind på webgrænsefladen, gå til afsnittet \"Sikkerhed\" i dine personlige indstillinger og opdater din krypteringsadgangskode ved at indtaste denne adgangskode i feltet \"Gammel loginadgangskode\" og din nuværende loginadgangskode.",
"Cannot decrypt this file, probably this is a shared file. Please ask the file owner to reshare the file with you." : "Kan ikke dekryptere denne fil, sandsynligvis er dette en delt fil. Bed filejeren om at videredele filen med dig.",
"Cannot read this file, probably this is a shared file. Please ask the file owner to reshare the file with you." : "Kan ikke læse denne fil, sandsynligvis er dette en delt fil. Bed filejeren om at videredele filen med dig.",
"Default Encryption Module" : "Standard krypteringsmodul",
"Default encryption module" : "Standard krypterings modul",
"Encryption app is enabled but your keys are not initialized, please log-out and log-in again" : "Krypteringsprogrammet er aktiveret men dine nøgler er ikke indlæst, log venligst ud og ind igen",
"Encrypt the home storage" : "Krypter hjemmelageret",

View File

@@ -34,6 +34,8 @@ OC.L10N.register(
"Please login to the web interface, go to the \"Security\" section of your personal settings and update your encryption password by entering this password into the \"Old login password\" field and your current login password." : "Por favor, faça login na interface web, vá para a seção \"Segurança\" de suas configurações pessoais e atualize sua senha de criptografia inserindo esta senha no campo \"Senha de login antiga\" e sua senha de login atual.",
"Cannot decrypt this file, probably this is a shared file. Please ask the file owner to reshare the file with you." : "Não foi possível descriptografar este arquivo, provavelmente é um arquivo compartilhado. Por favor, solicite ao proprietário do arquivo para recompartilhá-lo com você.",
"Cannot read this file, probably this is a shared file. Please ask the file owner to reshare the file with you." : "Não foi possível ler este arquivo, provavelmente é um arquivo compartilhado. Por favor, solicite ao proprietário do arquivo para recompartilhá-lo com você.",
"Default Encryption Module" : "Módulo de Criptografia Padrão",
"Default encryption module for Nextcloud Server-side Encryption (SSE)" : "Módulo de criptografia padrão para criptografia do lado do servidor (SSE) do Nextcloud",
"Default encryption module" : "Módulo de criptografia padrão",
"Encryption app is enabled but your keys are not initialized, please log-out and log-in again" : "O aplicativo de criptografia está habilitado, mas suas chaves não foram inicializadas. Por favor, saia e entre novamente.",
"Encrypt the home storage" : "Criptografar a pasta de armazenamento home",

View File

@@ -32,6 +32,8 @@
"Please login to the web interface, go to the \"Security\" section of your personal settings and update your encryption password by entering this password into the \"Old login password\" field and your current login password." : "Por favor, faça login na interface web, vá para a seção \"Segurança\" de suas configurações pessoais e atualize sua senha de criptografia inserindo esta senha no campo \"Senha de login antiga\" e sua senha de login atual.",
"Cannot decrypt this file, probably this is a shared file. Please ask the file owner to reshare the file with you." : "Não foi possível descriptografar este arquivo, provavelmente é um arquivo compartilhado. Por favor, solicite ao proprietário do arquivo para recompartilhá-lo com você.",
"Cannot read this file, probably this is a shared file. Please ask the file owner to reshare the file with you." : "Não foi possível ler este arquivo, provavelmente é um arquivo compartilhado. Por favor, solicite ao proprietário do arquivo para recompartilhá-lo com você.",
"Default Encryption Module" : "Módulo de Criptografia Padrão",
"Default encryption module for Nextcloud Server-side Encryption (SSE)" : "Módulo de criptografia padrão para criptografia do lado do servidor (SSE) do Nextcloud",
"Default encryption module" : "Módulo de criptografia padrão",
"Encryption app is enabled but your keys are not initialized, please log-out and log-in again" : "O aplicativo de criptografia está habilitado, mas suas chaves não foram inicializadas. Por favor, saia e entre novamente.",
"Encrypt the home storage" : "Criptografar a pasta de armazenamento home",

View File

@@ -34,6 +34,9 @@ OC.L10N.register(
"Please login to the web interface, go to the \"Security\" section of your personal settings and update your encryption password by entering this password into the \"Old login password\" field and your current login password." : "Молимо вас да се пријавите на веб интерфејс, одете на одељак „Безбедност” ваших личник подешавања и ажурирате своју лозинку за шифровање уносећи ову лозинку у поље „Стара лозинка за пријаву” и своју текућу лозинку за пријаву.",
"Cannot decrypt this file, probably this is a shared file. Please ask the file owner to reshare the file with you." : "Овај фајл не може да се дешифрује, то је вероватно дељени фајл. Молимо вас да замолите власника да га поново подели са вама.",
"Cannot read this file, probably this is a shared file. Please ask the file owner to reshare the file with you." : "Овај фајл не може да се прочита, то је вероватно дељени фајл. Молимо вас да замолите власника да га поново подели са вама.",
"Default Encryption Module" : "Подразумевани модул за шифровање",
"Default encryption module for Nextcloud Server-side Encryption (SSE)" : "Подразумевани модул за Nextcloud шифровање на серверској страни (SSE)",
"This app provides the (default) cryptography implementation for Nextcloud's Server-side Encryption (SSE) feature.\n\n\t\t\t**Encryption Details**\n\t\t\t* **Cipher Mode:** AES-256-CTR (default)\n\t\t\t* **Authentication:** HMAC-SHA256\n\n\t\t\t**Important Warnings**\n\t\t\t* **DANGER:** Do not disable this application until all files have been decrypted (`occ encryption:decrypt-all`).\n\t\t\t* **WARNING**: Reverting to non-encrypted file storage after activation requires command-line access. The action is permanent via the Web UI.\"\n\n\t\t\t**Notes for Existing Files**\n\t\t\t* By default, enabling SSE does not encrypt existing files; only new files will be encrypted.\n\t\t\t* To encrypt all existing files, use the command `occ encryption:encrypt-all`.\n\n\t\t\t**Before You Begin**\n\t\t\t* **Read the Documentation:** Before you enable SSE, encrypt existing files, or disable SSE, it is critical to \n\t\t\t\tread the documentation to understand implications and the appropriate procedures to avoid data loss." : "Ова апликација обезбеђује (подразумевану) криптографску имплементацију за Nextcloud функционалност шифровање на серверској страни (SSE) feature.\n\n\t\t\t**Детаљи шифровања**\n\t\t\t* **Режим шифрирања:** AES-256-CTR (подразумевани)\n\t\t\t* **Провера идентитета:** HMAC-SHA256\n\n\t\t\t**Важна упозорења**\n\t\t\t* **ОПАСНОСТ:** немојте да искључујете апликаију све док се сви фајлови не дешифрују (`occ encryption:decrypt-all`).\n\t\t\t* **УПОЗОРЕЊЕ**: враћање на нешифрирано складиште фајлове након активирања захтева приступ командној линији. Акција је трајна преко Веб КИ.\"\n\n\t\t\t**Напомене за постојеће фајлове**\n\t\t\t* Укључивање SSE подразумевано не шифрује постојеће фајлове; шифроваће се само нови фајлови.\n\t\t\t* Ако желите да шифрујете постојеће фајлове, употребите команду `occ encryption:encrypt-all`.\n\n\t\t\t**Пре него што почнете**\n\t\t\t* **Прочитајте документацију:** пре него што укључите SSE, шифрујете постојеће фајлове, или искључите SSE, веома је \n\t\t\t\tважно да прочитате документацију и у потпуности разумете последице и одговарајуће процедуре и тако спречите губитак података.",
"Default encryption module" : "Подразумевани модул за шифровање",
"Encryption app is enabled but your keys are not initialized, please log-out and log-in again" : "Апликација за шифровање је укључена али кључеви још нису иницијализовани. Одјавите се и поново се пријавите.",
"Encrypt the home storage" : "Шифровање главног складишта",

View File

@@ -32,6 +32,9 @@
"Please login to the web interface, go to the \"Security\" section of your personal settings and update your encryption password by entering this password into the \"Old login password\" field and your current login password." : "Молимо вас да се пријавите на веб интерфејс, одете на одељак „Безбедност” ваших личник подешавања и ажурирате своју лозинку за шифровање уносећи ову лозинку у поље „Стара лозинка за пријаву” и своју текућу лозинку за пријаву.",
"Cannot decrypt this file, probably this is a shared file. Please ask the file owner to reshare the file with you." : "Овај фајл не може да се дешифрује, то је вероватно дељени фајл. Молимо вас да замолите власника да га поново подели са вама.",
"Cannot read this file, probably this is a shared file. Please ask the file owner to reshare the file with you." : "Овај фајл не може да се прочита, то је вероватно дељени фајл. Молимо вас да замолите власника да га поново подели са вама.",
"Default Encryption Module" : "Подразумевани модул за шифровање",
"Default encryption module for Nextcloud Server-side Encryption (SSE)" : "Подразумевани модул за Nextcloud шифровање на серверској страни (SSE)",
"This app provides the (default) cryptography implementation for Nextcloud's Server-side Encryption (SSE) feature.\n\n\t\t\t**Encryption Details**\n\t\t\t* **Cipher Mode:** AES-256-CTR (default)\n\t\t\t* **Authentication:** HMAC-SHA256\n\n\t\t\t**Important Warnings**\n\t\t\t* **DANGER:** Do not disable this application until all files have been decrypted (`occ encryption:decrypt-all`).\n\t\t\t* **WARNING**: Reverting to non-encrypted file storage after activation requires command-line access. The action is permanent via the Web UI.\"\n\n\t\t\t**Notes for Existing Files**\n\t\t\t* By default, enabling SSE does not encrypt existing files; only new files will be encrypted.\n\t\t\t* To encrypt all existing files, use the command `occ encryption:encrypt-all`.\n\n\t\t\t**Before You Begin**\n\t\t\t* **Read the Documentation:** Before you enable SSE, encrypt existing files, or disable SSE, it is critical to \n\t\t\t\tread the documentation to understand implications and the appropriate procedures to avoid data loss." : "Ова апликација обезбеђује (подразумевану) криптографску имплементацију за Nextcloud функционалност шифровање на серверској страни (SSE) feature.\n\n\t\t\t**Детаљи шифровања**\n\t\t\t* **Режим шифрирања:** AES-256-CTR (подразумевани)\n\t\t\t* **Провера идентитета:** HMAC-SHA256\n\n\t\t\t**Важна упозорења**\n\t\t\t* **ОПАСНОСТ:** немојте да искључујете апликаију све док се сви фајлови не дешифрују (`occ encryption:decrypt-all`).\n\t\t\t* **УПОЗОРЕЊЕ**: враћање на нешифрирано складиште фајлове након активирања захтева приступ командној линији. Акција је трајна преко Веб КИ.\"\n\n\t\t\t**Напомене за постојеће фајлове**\n\t\t\t* Укључивање SSE подразумевано не шифрује постојеће фајлове; шифроваће се само нови фајлови.\n\t\t\t* Ако желите да шифрујете постојеће фајлове, употребите команду `occ encryption:encrypt-all`.\n\n\t\t\t**Пре него што почнете**\n\t\t\t* **Прочитајте документацију:** пре него што укључите SSE, шифрујете постојеће фајлове, или искључите SSE, веома је \n\t\t\t\tважно да прочитате документацију и у потпуности разумете последице и одговарајуће процедуре и тако спречите губитак података.",
"Default encryption module" : "Подразумевани модул за шифровање",
"Encryption app is enabled but your keys are not initialized, please log-out and log-in again" : "Апликација за шифровање је укључена али кључеви још нису иницијализовани. Одјавите се и поново се пријавите.",
"Encrypt the home storage" : "Шифровање главног складишта",

View File

@@ -34,6 +34,8 @@ OC.L10N.register(
"Please login to the web interface, go to the \"Security\" section of your personal settings and update your encryption password by entering this password into the \"Old login password\" field and your current login password." : "Будь ласка, увійдіть до вебінтерфейсу хмари, перейдіть до розділу \"Безпека\" ваших особистих налаштувань та оновіть ваш пароль шифрування даних: для цього зазначте пароль у полі \"Старий пароль входу\" та ваш поточний пароль входу.",
"Cannot decrypt this file, probably this is a shared file. Please ask the file owner to reshare the file with you." : "Не вдається розшифрувати цей файл, ймовірно, він знаходиться у спільному доступі. Будь ласка, зверніться до власника файлу з проханням надати вам доступ до нього.",
"Cannot read this file, probably this is a shared file. Please ask the file owner to reshare the file with you." : "Не вдається прочитати цей файл, ймовірно, це файл із загальним доступом. Будь ласка, попросіть власника файлу надати вам спільний доступ до нього. ",
"Default Encryption Module" : "Типовий модуль шифрування",
"Default encryption module for Nextcloud Server-side Encryption (SSE)" : "Типовий модуль шифрування для шифрування Nextcloud на стороні сервера (SSE)",
"Default encryption module" : "Типовий модуль шифрування",
"Encryption app is enabled but your keys are not initialized, please log-out and log-in again" : "Застосунок для шифрування увімкнено, але ваші ключі не ініціалізовано. Будь ласка, вийдіть із системи та увійдіть знову",
"Encrypt the home storage" : "Зашифрувати домашній каталог",

View File

@@ -32,6 +32,8 @@
"Please login to the web interface, go to the \"Security\" section of your personal settings and update your encryption password by entering this password into the \"Old login password\" field and your current login password." : "Будь ласка, увійдіть до вебінтерфейсу хмари, перейдіть до розділу \"Безпека\" ваших особистих налаштувань та оновіть ваш пароль шифрування даних: для цього зазначте пароль у полі \"Старий пароль входу\" та ваш поточний пароль входу.",
"Cannot decrypt this file, probably this is a shared file. Please ask the file owner to reshare the file with you." : "Не вдається розшифрувати цей файл, ймовірно, він знаходиться у спільному доступі. Будь ласка, зверніться до власника файлу з проханням надати вам доступ до нього.",
"Cannot read this file, probably this is a shared file. Please ask the file owner to reshare the file with you." : "Не вдається прочитати цей файл, ймовірно, це файл із загальним доступом. Будь ласка, попросіть власника файлу надати вам спільний доступ до нього. ",
"Default Encryption Module" : "Типовий модуль шифрування",
"Default encryption module for Nextcloud Server-side Encryption (SSE)" : "Типовий модуль шифрування для шифрування Nextcloud на стороні сервера (SSE)",
"Default encryption module" : "Типовий модуль шифрування",
"Encryption app is enabled but your keys are not initialized, please log-out and log-in again" : "Застосунок для шифрування увімкнено, але ваші ключі не ініціалізовано. Будь ласка, вийдіть із системи та увійдіть знову",
"Encrypt the home storage" : "Зашифрувати домашній каталог",

View File

@@ -34,6 +34,9 @@ OC.L10N.register(
"Please login to the web interface, go to the \"Security\" section of your personal settings and update your encryption password by entering this password into the \"Old login password\" field and your current login password." : "請登入網頁介面,請到個人設定中的「安全」區塊,透過輸入此密碼至「舊登入密碼」欄位與您目前的登入密碼,來更新您的加密密碼。",
"Cannot decrypt this file, probably this is a shared file. Please ask the file owner to reshare the file with you." : "無法解密這個檔案,也許這是分享的檔案。請要求檔案所有人重新分享檔案給您。",
"Cannot read this file, probably this is a shared file. Please ask the file owner to reshare the file with you." : "無法讀取這個檔案,也許這是分享的檔案。請要求檔案所有人重新分享檔案給您。",
"Default Encryption Module" : "預設加密模組",
"Default encryption module for Nextcloud Server-side Encryption (SSE)" : "Nextcloud 伺服器端加密 (SSE) 的預設加密模組",
"This app provides the (default) cryptography implementation for Nextcloud's Server-side Encryption (SSE) feature.\n\n\t\t\t**Encryption Details**\n\t\t\t* **Cipher Mode:** AES-256-CTR (default)\n\t\t\t* **Authentication:** HMAC-SHA256\n\n\t\t\t**Important Warnings**\n\t\t\t* **DANGER:** Do not disable this application until all files have been decrypted (`occ encryption:decrypt-all`).\n\t\t\t* **WARNING**: Reverting to non-encrypted file storage after activation requires command-line access. The action is permanent via the Web UI.\"\n\n\t\t\t**Notes for Existing Files**\n\t\t\t* By default, enabling SSE does not encrypt existing files; only new files will be encrypted.\n\t\t\t* To encrypt all existing files, use the command `occ encryption:encrypt-all`.\n\n\t\t\t**Before You Begin**\n\t\t\t* **Read the Documentation:** Before you enable SSE, encrypt existing files, or disable SSE, it is critical to \n\t\t\t\tread the documentation to understand implications and the appropriate procedures to avoid data loss." : "此應用程式提供了 Nextcloud 伺服器端加密 (SSE) 功能的(預設)密碼學實作。\n\n\t\t\t**加密詳細資訊**\n\t\t\t* **加密模式:**AES-256-CTR預設\n\t\t\t* **驗證:**HMAC-SHA256\n\n\t\t\t**重要警告**\n\t\t\t* **危險:**在解密所有檔案 (`occ encryption:decrypt-all`) 完成前請勿停用此應用程式。\n\t\t\t* **警告:**啟用後若要恢復為未加密的檔案儲存模式,需透過命令列介面進行操作。若透過網頁使用者介面執行此操作,該設定將永久生效。\n\n\t\t\t**既有檔案的備註**\n\t\t\t* 預設情況下,啟用 SSE 並不會加密既有檔案;僅會加密新的檔案。\n\t\t\t* 要加密所有既有檔案,請使用 `occ encryption:encrypt-all` 命令。\n\n\t\t\t**在您開始前**\n\t\t\t* **請讀文件:**在您啟用 SSE、加密既有檔案或停用 SSE 前,閱讀文件以理解其影響及避免資料遺失的適當程序至關重要。",
"Default encryption module" : "預設加密模組",
"Encryption app is enabled but your keys are not initialized, please log-out and log-in again" : "已啟用加密應用程式,但您的金鑰並未初始化,請登出並再次登入",
"Encrypt the home storage" : "加密家目錄儲存空間",

View File

@@ -32,6 +32,9 @@
"Please login to the web interface, go to the \"Security\" section of your personal settings and update your encryption password by entering this password into the \"Old login password\" field and your current login password." : "請登入網頁介面,請到個人設定中的「安全」區塊,透過輸入此密碼至「舊登入密碼」欄位與您目前的登入密碼,來更新您的加密密碼。",
"Cannot decrypt this file, probably this is a shared file. Please ask the file owner to reshare the file with you." : "無法解密這個檔案,也許這是分享的檔案。請要求檔案所有人重新分享檔案給您。",
"Cannot read this file, probably this is a shared file. Please ask the file owner to reshare the file with you." : "無法讀取這個檔案,也許這是分享的檔案。請要求檔案所有人重新分享檔案給您。",
"Default Encryption Module" : "預設加密模組",
"Default encryption module for Nextcloud Server-side Encryption (SSE)" : "Nextcloud 伺服器端加密 (SSE) 的預設加密模組",
"This app provides the (default) cryptography implementation for Nextcloud's Server-side Encryption (SSE) feature.\n\n\t\t\t**Encryption Details**\n\t\t\t* **Cipher Mode:** AES-256-CTR (default)\n\t\t\t* **Authentication:** HMAC-SHA256\n\n\t\t\t**Important Warnings**\n\t\t\t* **DANGER:** Do not disable this application until all files have been decrypted (`occ encryption:decrypt-all`).\n\t\t\t* **WARNING**: Reverting to non-encrypted file storage after activation requires command-line access. The action is permanent via the Web UI.\"\n\n\t\t\t**Notes for Existing Files**\n\t\t\t* By default, enabling SSE does not encrypt existing files; only new files will be encrypted.\n\t\t\t* To encrypt all existing files, use the command `occ encryption:encrypt-all`.\n\n\t\t\t**Before You Begin**\n\t\t\t* **Read the Documentation:** Before you enable SSE, encrypt existing files, or disable SSE, it is critical to \n\t\t\t\tread the documentation to understand implications and the appropriate procedures to avoid data loss." : "此應用程式提供了 Nextcloud 伺服器端加密 (SSE) 功能的(預設)密碼學實作。\n\n\t\t\t**加密詳細資訊**\n\t\t\t* **加密模式:**AES-256-CTR預設\n\t\t\t* **驗證:**HMAC-SHA256\n\n\t\t\t**重要警告**\n\t\t\t* **危險:**在解密所有檔案 (`occ encryption:decrypt-all`) 完成前請勿停用此應用程式。\n\t\t\t* **警告:**啟用後若要恢復為未加密的檔案儲存模式,需透過命令列介面進行操作。若透過網頁使用者介面執行此操作,該設定將永久生效。\n\n\t\t\t**既有檔案的備註**\n\t\t\t* 預設情況下,啟用 SSE 並不會加密既有檔案;僅會加密新的檔案。\n\t\t\t* 要加密所有既有檔案,請使用 `occ encryption:encrypt-all` 命令。\n\n\t\t\t**在您開始前**\n\t\t\t* **請讀文件:**在您啟用 SSE、加密既有檔案或停用 SSE 前,閱讀文件以理解其影響及避免資料遺失的適當程序至關重要。",
"Default encryption module" : "預設加密模組",
"Encryption app is enabled but your keys are not initialized, please log-out and log-in again" : "已啟用加密應用程式,但您的金鑰並未初始化,請登出並再次登入",
"Encrypt the home storage" : "加密家目錄儲存空間",

View File

@@ -74,7 +74,7 @@
<script>
import axios from '@nextcloud/axios'
import { DialogBuilder, DialogSeverity, showError } from '@nextcloud/dialogs'
import { DialogBuilder, showError } from '@nextcloud/dialogs'
import { loadState } from '@nextcloud/initial-state'
import { confirmPassword } from '@nextcloud/password-confirmation'
import { generateOcsUrl } from '@nextcloud/router'
@@ -124,7 +124,7 @@ export default {
const dialog = new DialogBuilder(t('federatedfilesharing', 'Confirm data upload to lookup server'))
await dialog
.setSeverity(DialogSeverity.Warning)
.setSeverity('warning')
.setText(t('federatedfilesharing', 'When enabled, all account properties (e.g. email address) with scope visibility set to "published", will be automatically synced and transmitted to an external system and made available in a public, global address book.'))
.addButton({
callback: () => this.setLookupServerUploadEnabled(false),
@@ -155,7 +155,7 @@ export default {
const dialog = new DialogBuilder(t('federatedfilesharing', 'Confirm querying lookup server'))
await dialog
.setSeverity(DialogSeverity.Warning)
.setSeverity('warning')
.setText(t('federatedfilesharing', 'When enabled, the search input when creating shares will be sent to an external system that provides a public and global address book.')
+ t('federatedfilesharing', 'This is used to retrieve the federated cloud ID to make federated sharing easier.')
+ t('federatedfilesharing', 'Moreover, email addresses of users might be sent to that system in order to verify them.'))

View File

@@ -1,123 +0,0 @@
/**
* SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
import RemoteShareDialog from './RemoteShareDialog.vue'
describe('RemoteShareDialog', () => {
it('can be mounted', () => {
cy.mount(RemoteShareDialog, {
propsData: {
owner: 'user123',
name: 'my-photos',
remote: 'nextcloud.local',
passwordRequired: false,
},
})
cy.findByRole('dialog')
.should('be.visible')
.and('contain.text', 'user123@nextcloud.local')
.and('contain.text', 'my-photos')
cy.findByRole('button', { name: 'Cancel' })
.should('be.visible')
cy.findByRole('button', { name: /add remote share/i })
.should('be.visible')
})
it('does not show password input if not enabled', () => {
cy.mount(RemoteShareDialog, {
propsData: {
owner: 'user123',
name: 'my-photos',
remote: 'nextcloud.local',
passwordRequired: false,
},
})
cy.findByRole('dialog')
.should('be.visible')
.find('input[type="password"]')
.should('not.exist')
})
it('emits true when accepted', () => {
const onClose = cy.spy().as('onClose')
cy.mount(RemoteShareDialog, {
listeners: {
close: onClose,
},
propsData: {
owner: 'user123',
name: 'my-photos',
remote: 'nextcloud.local',
passwordRequired: false,
},
})
cy.findByRole('button', { name: 'Cancel' }).click()
cy.get('@onClose')
.should('have.been.calledWith', false)
})
it('show password input if needed', () => {
cy.mount(RemoteShareDialog, {
propsData: {
owner: 'admin',
name: 'secret-data',
remote: 'nextcloud.local',
passwordRequired: true,
},
})
cy.findByRole('dialog')
.should('be.visible')
.find('input[type="password"]')
.should('be.visible')
})
it('emits the submitted password', () => {
const onClose = cy.spy().as('onClose')
cy.mount(RemoteShareDialog, {
listeners: {
close: onClose,
},
propsData: {
owner: 'admin',
name: 'secret-data',
remote: 'nextcloud.local',
passwordRequired: true,
},
})
cy.get('input[type="password"]')
.type('my password{enter}')
cy.get('@onClose')
.should('have.been.calledWith', true, 'my password')
})
it('emits no password if cancelled', () => {
const onClose = cy.spy().as('onClose')
cy.mount(RemoteShareDialog, {
listeners: {
close: onClose,
},
propsData: {
owner: 'admin',
name: 'secret-data',
remote: 'nextcloud.local',
passwordRequired: true,
},
})
cy.get('input[type="password"]')
.type('my password')
cy.findByRole('button', { name: 'Cancel' }).click()
cy.get('@onClose')
.should('have.been.calledWith', false)
})
})

View File

@@ -0,0 +1,115 @@
/**
* SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
import { cleanup, fireEvent, render } from '@testing-library/vue'
import { beforeEach, describe, expect, it, vi } from 'vitest'
import RemoteShareDialog from './RemoteShareDialog.vue'
describe('RemoteShareDialog', () => {
beforeEach(cleanup)
it('can be mounted', async () => {
const component = render(RemoteShareDialog, {
props: {
owner: 'user123',
name: 'my-photos',
remote: 'nextcloud.local',
passwordRequired: false,
},
})
await expect(component.findByRole('dialog', { name: 'Remote share' })).resolves.not.toThrow()
expect(component.getByRole('dialog').innerText).toContain(/my-photos from user123@nextcloud.local/)
await expect(component.findByRole('button', { name: 'Cancel' })).resolves.not.toThrow()
await expect(component.findByRole('button', { name: /Add remote share/ })).resolves.not.toThrow()
})
it('does not show password input if not enabled', async () => {
const component = render(RemoteShareDialog, {
props: {
owner: 'user123',
name: 'my-photos',
remote: 'nextcloud.local',
passwordRequired: false,
},
})
await expect(component.findByLabelText('Remote share password')).rejects.toThrow()
})
it('emits true when accepted', () => {
const onClose = vi.fn()
const component = render(RemoteShareDialog, {
listeners: {
close: onClose,
},
props: {
owner: 'user123',
name: 'my-photos',
remote: 'nextcloud.local',
passwordRequired: false,
},
})
component.getByRole('button', { name: 'Cancel' }).click()
expect(onClose).toHaveBeenCalledWith(false)
})
it('show password input if needed', async () => {
const component = render(RemoteShareDialog, {
props: {
owner: 'admin',
name: 'secret-data',
remote: 'nextcloud.local',
passwordRequired: true,
},
})
await expect(component.findByLabelText('Remote share password')).resolves.not.toThrow()
})
it('emits the submitted password', async () => {
const onClose = vi.fn()
const component = render(RemoteShareDialog, {
listeners: {
close: onClose,
},
props: {
owner: 'admin',
name: 'secret-data',
remote: 'nextcloud.local',
passwordRequired: true,
},
})
const input = component.getByLabelText('Remote share password')
await fireEvent.update(input, 'my password')
component.getByRole('button', { name: 'Add remote share' }).click()
expect(onClose).toHaveBeenCalledWith(true, 'my password')
})
it('emits no password if cancelled', async () => {
const onClose = vi.fn()
const component = render(RemoteShareDialog, {
listeners: {
close: onClose,
},
props: {
owner: 'admin',
name: 'secret-data',
remote: 'nextcloud.local',
passwordRequired: true,
},
})
const input = component.getByLabelText('Remote share password')
await fireEvent.update(input, 'my password')
component.getByRole('button', { name: 'Cancel' }).click()
expect(onClose).toHaveBeenCalledWith(false)
})
})

View File

@@ -35,8 +35,8 @@ const buttons = computed(() => [
},
{
label: t('federatedfilesharing', 'Add remote share'),
nativeType: props.passwordRequired ? 'submit' : undefined,
type: 'primary',
type: props.passwordRequired ? 'submit' : undefined,
variant: 'primary',
callback: () => emit('close', true, password.value),
},
])

View File

@@ -3,7 +3,7 @@
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
import { spawnDialog } from '@nextcloud/dialogs'
import { spawnDialog } from '@nextcloud/vue/functions/dialog'
import RemoteShareDialog from '../components/RemoteShareDialog.vue'
/**

View File

@@ -142,6 +142,7 @@ OC.L10N.register(
"Failed to refresh filename sanitization status." : "Nepodařilo se znovu načíst stav sanitizace názvů souborů.",
"Filename sanitization in progress." : "Probíhá sanitizace názvu souboru.",
"Currently {processedUsers} of {totalUsers} accounts are already processed." : "V tuto chvíli je už zpracováno {processedUsers} z {totalUsers} účtů.",
"Preparing …" : "Příprava …",
"Refresh" : "Znovu načíst",
"All files have been santized for Windows filename support." : "Všechny soubory byly sanitizovány ohledně podpory názvů souborů ve Windows.",
"Some files could not be sanitized, please check your logs." : "Některé soubory nebylo možné sanitizovat podívejte se do záznamu událostí.",

View File

@@ -140,6 +140,7 @@
"Failed to refresh filename sanitization status." : "Nepodařilo se znovu načíst stav sanitizace názvů souborů.",
"Filename sanitization in progress." : "Probíhá sanitizace názvu souboru.",
"Currently {processedUsers} of {totalUsers} accounts are already processed." : "V tuto chvíli je už zpracováno {processedUsers} z {totalUsers} účtů.",
"Preparing …" : "Příprava …",
"Refresh" : "Znovu načíst",
"All files have been santized for Windows filename support." : "Všechny soubory byly sanitizovány ohledně podpory názvů souborů ve Windows.",
"Some files could not be sanitized, please check your logs." : "Některé soubory nebylo možné sanitizovat podívejte se do záznamu událostí.",

View File

@@ -124,6 +124,8 @@ OC.L10N.register(
"This list is not fully rendered for performance reasons. The files will be rendered as you navigate through the list." : "Hele listen er ikke hentet, af hensyn til størrelsen. Listen vil blive hentet løbende som du kører igennem listen.",
"File not found" : "Filen blev ikke fundet",
"_{count} selected_::_{count} selected_" : ["{count} valgt","{count} valgt"],
"Search everywhere …" : "Søg over alt ...",
"Search here …" : "Søg her ...",
"Search scope options" : "Indstillinger for søgeområde",
"Search here" : "Søg her",
"{usedQuotaByte} used" : "{usedQuotaByte} brugt",
@@ -142,6 +144,7 @@ OC.L10N.register(
"Failed to refresh filename sanitization status." : "Kunne ikke genopfriske status for filnavnsrensning.",
"Filename sanitization in progress." : "Filnavnsrensning i gang.",
"Currently {processedUsers} of {totalUsers} accounts are already processed." : "Aktuelt er {processedUsers} ud af {totalUsers} konti allerede processeret.",
"Preparing …" : "Forbereder ...",
"Refresh" : "Opdatér",
"All files have been santized for Windows filename support." : "Alle filer er blevet filnavnsrensede af hensyn til Windows filnavnsunderstøttelse.",
"Some files could not be sanitized, please check your logs." : "Nogle filer kunne ikke blive filnavnsrensede, kontroller venligst dine logfiler.",
@@ -156,6 +159,7 @@ OC.L10N.register(
"Sanitize filenames" : "Rens filnavne",
"(starting)" : "(starter)",
"Fill template fields" : "Udfyld skabelonfelter",
"Submitting fields …" : "Indsender felter ...",
"Submit" : "Tilføj",
"Choose a file or folder to transfer" : "Vælg en fil eller mappe til overførsel",
"Transfer" : "Overfør",
@@ -268,6 +272,8 @@ OC.L10N.register(
"Create a new file with the selected template" : "Opret en ny fil med den valgte skabelon",
"Creating file" : "Opretter fil",
"Save as {displayName}" : "Gem som {displayName}",
"Save as …" : "Gem som ...",
"Converting files …" : "Konverterer filer ...",
"Failed to convert files: {message}" : "Kunne ikke konvertere filer: {message}",
"All files failed to be converted" : "Alle filer kunne ikke konverteres",
"One file could not be converted: {message}" : "En fil kunne ikke konverteres: {message}",
@@ -275,6 +281,7 @@ OC.L10N.register(
"_One file successfully converted_::_%n files successfully converted_" : ["En fil konverteret","%n filer konverteret"],
"Files successfully converted" : "Filer konverteret",
"Failed to convert files" : "Kunne ikke konvertere filer",
"Converting file …" : "Konverterer fil …",
"File successfully converted" : "Filen konverteret",
"Failed to convert file: {message}" : "Kunne ikke konvertere fil: {message}",
"Failed to convert file" : "Kunne ikke konvertere fil",
@@ -295,6 +302,8 @@ OC.L10N.register(
"Download" : "Download",
"The requested file is not available." : "Den forespurgte fil er ikke tilgængelig.",
"The requested files are not available." : "De forespurgte filer er ikke tilgængelige.",
"Moving \"{source}\" to \"{destination}\" …" : "Flytter \"{source}\" til \"{destination}\" …",
"Copying \"{source}\" to \"{destination}\" …" : "Kopierer \"{source}\" til \"{destination}\" …",
"Destination is not a folder" : "Destinationen er ikke en mappe",
"This file/folder is already in that directory" : "Filen/mappen er allerede i denne mappe",
"You cannot move a file/folder onto itself or into a subfolder of itself" : "Du kan ikke flytte en fil/mappe ind i sig selv, eller til en mappe inden i sig selv",
@@ -304,11 +313,11 @@ OC.L10N.register(
"The files are locked" : "Filerne er låste",
"The file does not exist anymore" : "Filen findes ikke længere",
"Choose destination" : "Vælg destination",
"Copy to {target}" : "Kopier til {target}",
"Copy to {target}" : "Kopiér til {target}",
"Move to {target}" : "Flyt til {target}",
"Move" : "Flyt",
"Move or copy operation failed" : "Flytte- eller kopioperationen fejlede",
"Move or copy" : "Flyt eller kopier",
"Move or copy" : "Flyt eller kopiér",
"Open folder {displayName}" : "Åben mappe {displayName}",
"Open in Files" : "Åben i Filer",
"Open locally" : "Åben lokalt",

View File

@@ -122,6 +122,8 @@
"This list is not fully rendered for performance reasons. The files will be rendered as you navigate through the list." : "Hele listen er ikke hentet, af hensyn til størrelsen. Listen vil blive hentet løbende som du kører igennem listen.",
"File not found" : "Filen blev ikke fundet",
"_{count} selected_::_{count} selected_" : ["{count} valgt","{count} valgt"],
"Search everywhere …" : "Søg over alt ...",
"Search here …" : "Søg her ...",
"Search scope options" : "Indstillinger for søgeområde",
"Search here" : "Søg her",
"{usedQuotaByte} used" : "{usedQuotaByte} brugt",
@@ -140,6 +142,7 @@
"Failed to refresh filename sanitization status." : "Kunne ikke genopfriske status for filnavnsrensning.",
"Filename sanitization in progress." : "Filnavnsrensning i gang.",
"Currently {processedUsers} of {totalUsers} accounts are already processed." : "Aktuelt er {processedUsers} ud af {totalUsers} konti allerede processeret.",
"Preparing …" : "Forbereder ...",
"Refresh" : "Opdatér",
"All files have been santized for Windows filename support." : "Alle filer er blevet filnavnsrensede af hensyn til Windows filnavnsunderstøttelse.",
"Some files could not be sanitized, please check your logs." : "Nogle filer kunne ikke blive filnavnsrensede, kontroller venligst dine logfiler.",
@@ -154,6 +157,7 @@
"Sanitize filenames" : "Rens filnavne",
"(starting)" : "(starter)",
"Fill template fields" : "Udfyld skabelonfelter",
"Submitting fields …" : "Indsender felter ...",
"Submit" : "Tilføj",
"Choose a file or folder to transfer" : "Vælg en fil eller mappe til overførsel",
"Transfer" : "Overfør",
@@ -266,6 +270,8 @@
"Create a new file with the selected template" : "Opret en ny fil med den valgte skabelon",
"Creating file" : "Opretter fil",
"Save as {displayName}" : "Gem som {displayName}",
"Save as …" : "Gem som ...",
"Converting files …" : "Konverterer filer ...",
"Failed to convert files: {message}" : "Kunne ikke konvertere filer: {message}",
"All files failed to be converted" : "Alle filer kunne ikke konverteres",
"One file could not be converted: {message}" : "En fil kunne ikke konverteres: {message}",
@@ -273,6 +279,7 @@
"_One file successfully converted_::_%n files successfully converted_" : ["En fil konverteret","%n filer konverteret"],
"Files successfully converted" : "Filer konverteret",
"Failed to convert files" : "Kunne ikke konvertere filer",
"Converting file …" : "Konverterer fil …",
"File successfully converted" : "Filen konverteret",
"Failed to convert file: {message}" : "Kunne ikke konvertere fil: {message}",
"Failed to convert file" : "Kunne ikke konvertere fil",
@@ -293,6 +300,8 @@
"Download" : "Download",
"The requested file is not available." : "Den forespurgte fil er ikke tilgængelig.",
"The requested files are not available." : "De forespurgte filer er ikke tilgængelige.",
"Moving \"{source}\" to \"{destination}\" …" : "Flytter \"{source}\" til \"{destination}\" …",
"Copying \"{source}\" to \"{destination}\" …" : "Kopierer \"{source}\" til \"{destination}\" …",
"Destination is not a folder" : "Destinationen er ikke en mappe",
"This file/folder is already in that directory" : "Filen/mappen er allerede i denne mappe",
"You cannot move a file/folder onto itself or into a subfolder of itself" : "Du kan ikke flytte en fil/mappe ind i sig selv, eller til en mappe inden i sig selv",
@@ -302,11 +311,11 @@
"The files are locked" : "Filerne er låste",
"The file does not exist anymore" : "Filen findes ikke længere",
"Choose destination" : "Vælg destination",
"Copy to {target}" : "Kopier til {target}",
"Copy to {target}" : "Kopiér til {target}",
"Move to {target}" : "Flyt til {target}",
"Move" : "Flyt",
"Move or copy operation failed" : "Flytte- eller kopioperationen fejlede",
"Move or copy" : "Flyt eller kopier",
"Move or copy" : "Flyt eller kopiér",
"Open folder {displayName}" : "Åben mappe {displayName}",
"Open in Files" : "Åben i Filer",
"Open locally" : "Åben lokalt",

View File

@@ -110,6 +110,9 @@ OC.L10N.register(
"Column headers with buttons are sortable." : "버튼이 있는 열 머리글은 정렬할 수 있습니다.",
"This list is not fully rendered for performance reasons. The files will be rendered as you navigate through the list." : "성능 상의 이유로 목록을 전부 표시하지 않았습니다. 목록을 탐색하면 파일들이 표시됩니다.",
"File not found" : "파일을 찾을 수 없음",
"Search everywhere …" : "모든 곳에서 검색 ...",
"Search here …" : "여기서 검색 ...",
"Search here" : "여기서 검색",
"{usedQuotaByte} used" : "{usedQuotaByte} 사용",
"{used} of {quota} used" : "{quota} 중 {used} 사용함",
"{relative}% used" : "{relative}% 사용",
@@ -149,27 +152,46 @@ OC.L10N.register(
"Clipboard is not available" : "클립보드를 사용할 수 없습니다.",
"Files settings" : "파일 설정",
"General" : "일반",
"Default view" : "기본 보기",
"All files" : "모든 파일",
"Personal files" : "개인 파일",
"Sort favorites first" : "즐겨찾기를 처음에 나열",
"Sort folders before files" : "폴더를 파일보다 먼저 정렬",
"Folder tree" : "폴더 트리",
"Appearance" : "외형",
"Show hidden files" : "숨김 파일 보이기",
"Show file type column" : "파일 형식 열 보이기",
"Show file extensions" : "파일 확장자 보이기",
"Crop image previews" : "이미지 미리보기 확대",
"Additional settings" : "고급 설정",
"WebDAV" : "WebDAV",
"WebDAV URL" : "WebDAV URL",
"Copy" : "복사",
"How to access files using WebDAV" : "WebDAV를 사용해 파일에 접근하는 방법",
"Two-Factor Authentication is enabled for your account, and therefore you need to use an app password to connect an external WebDAV client." : "2단계 인증이 활성화되어 있어 외부 WebDAV 클라이언트를 연결할 때 앱 암호를 사용해야 합니다.",
"Warnings" : "경고",
"Warn before changing a file extension" : "파일 확장자 변경 시 경고",
"Warn before deleting files" : "파일 삭제 시 경고",
"Keyboard shortcuts" : "키보드 단축키",
"File actions" : "파일 동작",
"Rename" : "이름 바꾸기",
"Delete" : "삭제",
"Add or remove favorite" : "즐겨찾기 추가 또는 삭제",
"Manage tags" : "태그 관리하기",
"Selection" : "선택",
"Select all files" : "모든 파일 선택",
"Deselect all" : "모두 선택 해제",
"Select or deselect" : "선택 또는 선택 해제",
"Select a range" : "범위 선택",
"Navigation" : "탐색",
"Go to parent folder" : "상위 폴더로 이동",
"Go to file above" : "위 파일로 이동",
"Go to file below" : "아래 파일로 이동",
"Go left in grid" : "그리드에서 왼쪽으로 이동",
"Go right in grid" : "그리드에서 오른쪽으로 이동",
"View" : "보기",
"Toggle grid view" : "그리드뷰 전환",
"Open file sidebar" : "파일 사이드바 열기",
"Show those shortcuts" : "다음 단축키 표시",
"Share" : "공유하기",
"Shared by link" : "링크로 공유됨",
@@ -354,6 +376,8 @@ OC.L10N.register(
"Photos and images" : "사진과 이미지",
"New folder creation cancelled" : "새 폴더 생성 취소됨",
"This directory is unavailable, please check the logs or contact the administrator" : "디렉터리를 사용할 수 없습니다. 로그를 확인하거나 관리자에게 연락하십시오",
"All folders" : "모든 폴더"
"All folders" : "모든 폴더",
"Search everywhere …" : "모든 곳에서 검색 ...",
"Search here …" : "여기서 검색 ..."
},
"nplurals=1; plural=0;");

View File

@@ -108,6 +108,9 @@
"Column headers with buttons are sortable." : "버튼이 있는 열 머리글은 정렬할 수 있습니다.",
"This list is not fully rendered for performance reasons. The files will be rendered as you navigate through the list." : "성능 상의 이유로 목록을 전부 표시하지 않았습니다. 목록을 탐색하면 파일들이 표시됩니다.",
"File not found" : "파일을 찾을 수 없음",
"Search everywhere …" : "모든 곳에서 검색 ...",
"Search here …" : "여기서 검색 ...",
"Search here" : "여기서 검색",
"{usedQuotaByte} used" : "{usedQuotaByte} 사용",
"{used} of {quota} used" : "{quota} 중 {used} 사용함",
"{relative}% used" : "{relative}% 사용",
@@ -147,27 +150,46 @@
"Clipboard is not available" : "클립보드를 사용할 수 없습니다.",
"Files settings" : "파일 설정",
"General" : "일반",
"Default view" : "기본 보기",
"All files" : "모든 파일",
"Personal files" : "개인 파일",
"Sort favorites first" : "즐겨찾기를 처음에 나열",
"Sort folders before files" : "폴더를 파일보다 먼저 정렬",
"Folder tree" : "폴더 트리",
"Appearance" : "외형",
"Show hidden files" : "숨김 파일 보이기",
"Show file type column" : "파일 형식 열 보이기",
"Show file extensions" : "파일 확장자 보이기",
"Crop image previews" : "이미지 미리보기 확대",
"Additional settings" : "고급 설정",
"WebDAV" : "WebDAV",
"WebDAV URL" : "WebDAV URL",
"Copy" : "복사",
"How to access files using WebDAV" : "WebDAV를 사용해 파일에 접근하는 방법",
"Two-Factor Authentication is enabled for your account, and therefore you need to use an app password to connect an external WebDAV client." : "2단계 인증이 활성화되어 있어 외부 WebDAV 클라이언트를 연결할 때 앱 암호를 사용해야 합니다.",
"Warnings" : "경고",
"Warn before changing a file extension" : "파일 확장자 변경 시 경고",
"Warn before deleting files" : "파일 삭제 시 경고",
"Keyboard shortcuts" : "키보드 단축키",
"File actions" : "파일 동작",
"Rename" : "이름 바꾸기",
"Delete" : "삭제",
"Add or remove favorite" : "즐겨찾기 추가 또는 삭제",
"Manage tags" : "태그 관리하기",
"Selection" : "선택",
"Select all files" : "모든 파일 선택",
"Deselect all" : "모두 선택 해제",
"Select or deselect" : "선택 또는 선택 해제",
"Select a range" : "범위 선택",
"Navigation" : "탐색",
"Go to parent folder" : "상위 폴더로 이동",
"Go to file above" : "위 파일로 이동",
"Go to file below" : "아래 파일로 이동",
"Go left in grid" : "그리드에서 왼쪽으로 이동",
"Go right in grid" : "그리드에서 오른쪽으로 이동",
"View" : "보기",
"Toggle grid view" : "그리드뷰 전환",
"Open file sidebar" : "파일 사이드바 열기",
"Show those shortcuts" : "다음 단축키 표시",
"Share" : "공유하기",
"Shared by link" : "링크로 공유됨",
@@ -352,6 +374,8 @@
"Photos and images" : "사진과 이미지",
"New folder creation cancelled" : "새 폴더 생성 취소됨",
"This directory is unavailable, please check the logs or contact the administrator" : "디렉터리를 사용할 수 없습니다. 로그를 확인하거나 관리자에게 연락하십시오",
"All folders" : "모든 폴더"
"All folders" : "모든 폴더",
"Search everywhere …" : "모든 곳에서 검색 ...",
"Search here …" : "여기서 검색 ..."
},"pluralForm" :"nplurals=1; plural=0;"
}

View File

@@ -13,7 +13,7 @@ OC.L10N.register(
"Restored by {user}" : "Hersteld door {user}",
"Renamed by {user}" : "Hernoemd door {user}",
"Moved by {user}" : "Verplaatst door {user}",
"\"remote account\"" : "\"remote account\"",
"\"remote account\"" : "\"extern account\"",
"You created {file}" : "Je creëerde {file}",
"You created an encrypted file in {file}" : "Je creëerde een versleuteld bestand in {file}",
"{user} created {file}" : "{user} creëerde {file}",
@@ -51,6 +51,10 @@ OC.L10N.register(
"You do not have permission to create a file at the specified location" : "Je hebt geen toestemming om een bestand aan te maken op de opgegeven locatie",
"The file could not be converted." : "Het bestand kon niet worden geconverteerd.",
"Could not get relative path to converted file" : "Kon geen relatief pad naar geconverteerd bestand achterhalen",
"Limit must be a positive integer." : "Limiet moet een positief integer getal zijn.",
"The replacement character may only be a single character." : "Het vervangende teken kan alleen maar een enkel teken zijn",
"Filename sanitization already started." : "Opschonen bestandsnaam is al actief",
"No filename sanitization in progress." : "Opschonen bestandsnaam niet actief",
"Favorite files" : "Favoriete bestanden",
"No favorites" : "Geen favorieten",
"More favorites" : "Meer favorieten",
@@ -109,6 +113,9 @@ OC.L10N.register(
"Name" : "Naam",
"File type" : "Bestandstype",
"Size" : "Grootte",
"{displayName}: failed on some elements" : "{displayName}: sommige onderdelen zijn mislukt",
"{displayName}: done" : "{displayName}: compleet",
"{displayName}: failed" : "{displayName}: mislukt",
"Actions" : "Acties",
"(selected)" : "(geselecteerd)",
"List of files and folders." : "Lijst van bestanden en mappen.",
@@ -117,7 +124,10 @@ OC.L10N.register(
"This list is not fully rendered for performance reasons. The files will be rendered as you navigate through the list." : "De lijst is niet volledig verwerkt om de prestatie niet te beperken. De bestanden worden verder verwerkt als je door de lijst navigeert.",
"File not found" : "Bestand niet gevonden",
"_{count} selected_::_{count} selected_" : ["{count} geselecteerd","{count} geselecteerd"],
"Search everywhere …" : "Zoek in alles …",
"Search here …" : "Zoek hier …",
"Search scope options" : "Zoek bereikopties",
"Search here" : "Zoek hier",
"{usedQuotaByte} used" : "{usedQuotaByte} gebruikt",
"{used} of {quota} used" : "{used} van {quota} gebruikt",
"{relative}% used" : "{relative}% gebruikt",
@@ -130,9 +140,26 @@ OC.L10N.register(
"This name is already in use." : "De naam is al in gebruik.",
"Create" : "Aanmaken",
"Files starting with a dot are hidden by default" : "Bestanden die met een punt beginnen, worden standaard verborgen",
"Failed to start filename sanitization." : "Opschonen bestandsnaam is mislukt.",
"Failed to refresh filename sanitization status." : "Update van opschonen bestandsnaam status mislukt",
"Filename sanitization in progress." : "Opschonen bestandsnaam wordt uitgevoerd.",
"Currently {processedUsers} of {totalUsers} accounts are already processed." : "{processedUsers} van {totalUsers} accounts zijn al verwerkt.",
"Preparing …" : "Voorbereiden …",
"Refresh" : "Verversen",
"All files have been santized for Windows filename support." : "Alle bestanden zijn opgeschoond voor ondersteuning van Windows bestandsnamen.",
"Some files could not be sanitized, please check your logs." : "Enkele bestanden kunnen niet opgeschoond worden, controleer je logs.",
"Sanitization errors" : "Opschoon fouten",
"Not sanitized filenames" : "Niet opgeschoonde bestanden",
"Windows filename support has been enabled." : "Ondersteuning voor Windows bestanden is ingeschakeld",
"While this blocks users from creating new files with unsupported filenames, existing files are not yet renamed and thus still may break sync on Windows." : "Ondanks dat dit gebruikers stopt om niet niet ondersteunde bestanden aan te maken, zijn bestaande bestanden nog niet hernoemd en kunnen dus de sync met Windows afbreken.",
"You can trigger a rename of files with invalid filenames, this will be done in the background and may take some time." : "Je kan het hernoemen van ongeldige bestandsnamen starten, dit wordt gedaan in de achtergrond en duurt mogelijk even.",
"Please note that this may cause high workload on the sync clients." : "Wees gewaarschuwd dat dit een hoge werklast voor het syncen van clients kan opleveren.",
"Limit" : "Limiet",
"This allows to configure how many users should be processed in one background job run." : "Met dit kan je configureren hoeveel gebruikers verwerkt worden tijdens een achtergrond taak. ",
"Sanitize filenames" : "Opschonen bestanden",
"(starting)" : "(begonnen)",
"Fill template fields" : "Vul de velden van het sjabloon in",
"Submitting fields …" : "Toevoegen velden …",
"Submit" : "Verwerken",
"Choose a file or folder to transfer" : "Kies een bestand of map om over te dragen",
"Transfer" : "Overdragen",
@@ -157,6 +184,7 @@ OC.L10N.register(
"Select file or folder to link to" : "Selecteer een bestand of map om naar te linken",
"Choose {file}" : "Kies {file}",
"Clipboard is not available" : "Klembord niet beschikbaar",
"WebDAV URL copied" : "WebDAV URL gekopieerd",
"Files settings" : "Instellingen voor bestanden",
"General" : "Algemeen",
"Default view" : "Standaardweergave",
@@ -168,24 +196,37 @@ OC.L10N.register(
"Appearance" : "Uiterlijk",
"Show hidden files" : "Toon verborgen bestanden",
"Show file type column" : "Toon bestandstypekolom",
"Show file extensions" : "Laat bestand extensies zien",
"Crop image previews" : "Snij afbeeldingvoorbeelden bij",
"Additional settings" : "Aanvullende instellingen",
"WebDAV" : "WebDAV",
"WebDAV URL" : "WebDAV URL",
"Copy" : "Kopiëren",
"How to access files using WebDAV" : "Hoe bestanden te benaderen met WebDAV",
"Two-Factor Authentication is enabled for your account, and therefore you need to use an app password to connect an external WebDAV client." : "Tweefactorauthenticatie is ingeschakeld voor jouw account en daarom moet je een app-wachtwoord gebruiken om een externe WebDAV-client aan te sluiten.",
"Warnings" : "Waarschuwingen",
"Warn before changing a file extension" : "Waarschuw voordat een bestand extensie wordt gewijzigd",
"Warn before deleting files" : "Waarschuw voordat bestanden worden verwijderd",
"Keyboard shortcuts" : "Toetsenbord sneltoetsen",
"File actions" : "Bestandsacties",
"Rename" : "Naam wijzigen",
"Delete" : "Verwijderen",
"Add or remove favorite" : "Verwijder of voeg een favoriet toe",
"Manage tags" : "Berichttags",
"Selection" : "Selectie",
"Select all files" : "Selecteer alle bestanden",
"Deselect all" : "Deselecteer alles",
"Select or deselect" : "Selecteren of deselecteren",
"Select a range" : "Selecteer een bereik",
"Navigation" : "Navigatie",
"Go to parent folder" : "Ga naar bovenliggende map",
"Go to file above" : "Ga naar bovenliggend bestand",
"Go to file below" : "Ga naar onderliggend bestand",
"Go left in grid" : "Ga naar links in raster",
"Go right in grid" : "Ga naar rechts in raster",
"View" : "Bekijken",
"Toggle grid view" : "Omschakelen roosterweergave",
"Open file sidebar" : "Open bestands zijbalk",
"Show those shortcuts" : "Toon die snelkoppelingen",
"Share" : "Delen",
"Shared by link" : "Gedeeld via link",
@@ -221,6 +262,7 @@ OC.L10N.register(
"Search for files" : "Zoeken naar bestanden",
"Allow to restrict filenames to ensure files can be synced with all clients. By default all filenames valid on POSIX (e.g. Linux or macOS) are allowed." : "Toestaan om bestandsnamen te beperken om te borgen dat bestanden met alle cliënts gesynchroniseerd kunnen worden. Standaard zijn alle bestandsnamen valide die zijn toegestaan op POSIX (zoals Linux en macOS.)",
"After enabling the Windows compatible filenames, existing files cannot be modified anymore but can be renamed to valid new names by their owner." : "Na inschakeling van Windows-compatibele bestandsnamen, kunnen bestaande bestanden niet meer worden gewijzigd, maar kunnen ze door de eigenaar worden hernoemd naar geldige nieuwe namen.",
"Failed to toggle Windows filename support" : "Omschakelen naar Windows bestand ondersteuning mislukt",
"Files compatibility" : "Bestandscompatibiliteit",
"Enforce Windows compatibility" : "Dwing Windows-compatibiliteit af",
"This will block filenames not valid on Windows systems, like using reserved names or special characters. But this will not enforce compatibility of case sensitivity." : "Dit zal bestandsnamen blokkeren die niet toegestaan zijn op Windows-systemen, zoals gereserveerde namen of speciale tekens. Dit dwingt niet tot compatibiliteit voor hoofd- en kleine letters.",
@@ -230,6 +272,8 @@ OC.L10N.register(
"Create a new file with the selected template" : "Maak een nieuw bestand met het geselecteerde sjabloon",
"Creating file" : "Maken bestand",
"Save as {displayName}" : "Opslaan als {displayName}",
"Save as …" : "Bewaar als …",
"Converting files …" : "Bestanden converteren …",
"Failed to convert files: {message}" : "Conversie van bestanden mislukt: {message} ",
"All files failed to be converted" : "De conversie van alle bestanden is mislukt",
"One file could not be converted: {message}" : "Een bestand kon niet worden geconverteerd: {message}",
@@ -237,6 +281,7 @@ OC.L10N.register(
"_One file successfully converted_::_%n files successfully converted_" : ["Een bestand succesvol geconverteerd","%n bestanden succesvol geconverteerd"],
"Files successfully converted" : "Bestanden succesvol geconverteerd",
"Failed to convert files" : "Conversie van bestanden mislukt",
"Converting file …" : "Bestand converteren …",
"File successfully converted" : "Bestand succesvol geconverteerd",
"Failed to convert file: {message}" : "Conversie van bestand mislukt: {message} ",
"Failed to convert file" : "Conversie van bestand mislukt",
@@ -255,6 +300,10 @@ OC.L10N.register(
"Confirm deletion" : "Bevestig verwijderen",
"Cancel" : "Annuleren",
"Download" : "Downloaden",
"The requested file is not available." : "Het gevraagde bestand is niet beschikbaar.",
"The requested files are not available." : "De gevraagde bestanden zijn niet beschikbaar.",
"Moving \"{source}\" to \"{destination}\" …" : "Verplaatsen \"{source}\" naar \"{destination}\" …",
"Copying \"{source}\" to \"{destination}\" …" : "Kopieren \"{source}\" naar \"{destination}\" …",
"Destination is not a folder" : "Bestemming is geen map",
"This file/folder is already in that directory" : "Dit bestand/deze map staat al in die map",
"You cannot move a file/folder onto itself or into a subfolder of itself" : "Je kan een bestand/map niet verplaatsen naar zichzelf of naar een subfolder van zichzelf.",
@@ -317,6 +366,7 @@ OC.L10N.register(
"The name \"{newName}\" is already used in the folder \"{dir}\". Please choose a different name." : "De naam \"{newName}\" bestaat al in map \"{dir}\". Kies een andere naam.",
"Could not rename \"{oldName}\"" : "Kon \"{oldName}\" niet hernoemen",
"This operation is forbidden" : "Deze taak is verboden",
"This folder is unavailable, please try again later or contact the administration" : "Deze map is niet beschikbaar, probeer het later nog eens of neem contact op met de beheerder",
"Storage is temporarily not available" : "Opslag is tijdelijk niet beschikbaar",
"Unexpected error: {error}" : "Onverwachte fout: {error}",
"_%n file_::_%n files_" : ["%n bestand","%n bestanden"],
@@ -393,6 +443,9 @@ OC.L10N.register(
"Photos and images" : "Foto's en afbeeldingen",
"New folder creation cancelled" : "Maken van nieuwe map geannuleerd",
"This directory is unavailable, please check the logs or contact the administrator" : "Deze map is niet beschikbaar. Verifieer de logs of neem contact op met de beheerder",
"All folders" : "Alle mappen"
"All folders" : "Alle mappen",
"Search everywhere …" : "Zoek in alles...",
"Search here …" : "Zoek hier ...",
"Preparing …" : "Voorbereiden ..."
},
"nplurals=2; plural=(n != 1);");

View File

@@ -11,7 +11,7 @@
"Restored by {user}" : "Hersteld door {user}",
"Renamed by {user}" : "Hernoemd door {user}",
"Moved by {user}" : "Verplaatst door {user}",
"\"remote account\"" : "\"remote account\"",
"\"remote account\"" : "\"extern account\"",
"You created {file}" : "Je creëerde {file}",
"You created an encrypted file in {file}" : "Je creëerde een versleuteld bestand in {file}",
"{user} created {file}" : "{user} creëerde {file}",
@@ -49,6 +49,10 @@
"You do not have permission to create a file at the specified location" : "Je hebt geen toestemming om een bestand aan te maken op de opgegeven locatie",
"The file could not be converted." : "Het bestand kon niet worden geconverteerd.",
"Could not get relative path to converted file" : "Kon geen relatief pad naar geconverteerd bestand achterhalen",
"Limit must be a positive integer." : "Limiet moet een positief integer getal zijn.",
"The replacement character may only be a single character." : "Het vervangende teken kan alleen maar een enkel teken zijn",
"Filename sanitization already started." : "Opschonen bestandsnaam is al actief",
"No filename sanitization in progress." : "Opschonen bestandsnaam niet actief",
"Favorite files" : "Favoriete bestanden",
"No favorites" : "Geen favorieten",
"More favorites" : "Meer favorieten",
@@ -107,6 +111,9 @@
"Name" : "Naam",
"File type" : "Bestandstype",
"Size" : "Grootte",
"{displayName}: failed on some elements" : "{displayName}: sommige onderdelen zijn mislukt",
"{displayName}: done" : "{displayName}: compleet",
"{displayName}: failed" : "{displayName}: mislukt",
"Actions" : "Acties",
"(selected)" : "(geselecteerd)",
"List of files and folders." : "Lijst van bestanden en mappen.",
@@ -115,7 +122,10 @@
"This list is not fully rendered for performance reasons. The files will be rendered as you navigate through the list." : "De lijst is niet volledig verwerkt om de prestatie niet te beperken. De bestanden worden verder verwerkt als je door de lijst navigeert.",
"File not found" : "Bestand niet gevonden",
"_{count} selected_::_{count} selected_" : ["{count} geselecteerd","{count} geselecteerd"],
"Search everywhere …" : "Zoek in alles …",
"Search here …" : "Zoek hier …",
"Search scope options" : "Zoek bereikopties",
"Search here" : "Zoek hier",
"{usedQuotaByte} used" : "{usedQuotaByte} gebruikt",
"{used} of {quota} used" : "{used} van {quota} gebruikt",
"{relative}% used" : "{relative}% gebruikt",
@@ -128,9 +138,26 @@
"This name is already in use." : "De naam is al in gebruik.",
"Create" : "Aanmaken",
"Files starting with a dot are hidden by default" : "Bestanden die met een punt beginnen, worden standaard verborgen",
"Failed to start filename sanitization." : "Opschonen bestandsnaam is mislukt.",
"Failed to refresh filename sanitization status." : "Update van opschonen bestandsnaam status mislukt",
"Filename sanitization in progress." : "Opschonen bestandsnaam wordt uitgevoerd.",
"Currently {processedUsers} of {totalUsers} accounts are already processed." : "{processedUsers} van {totalUsers} accounts zijn al verwerkt.",
"Preparing …" : "Voorbereiden …",
"Refresh" : "Verversen",
"All files have been santized for Windows filename support." : "Alle bestanden zijn opgeschoond voor ondersteuning van Windows bestandsnamen.",
"Some files could not be sanitized, please check your logs." : "Enkele bestanden kunnen niet opgeschoond worden, controleer je logs.",
"Sanitization errors" : "Opschoon fouten",
"Not sanitized filenames" : "Niet opgeschoonde bestanden",
"Windows filename support has been enabled." : "Ondersteuning voor Windows bestanden is ingeschakeld",
"While this blocks users from creating new files with unsupported filenames, existing files are not yet renamed and thus still may break sync on Windows." : "Ondanks dat dit gebruikers stopt om niet niet ondersteunde bestanden aan te maken, zijn bestaande bestanden nog niet hernoemd en kunnen dus de sync met Windows afbreken.",
"You can trigger a rename of files with invalid filenames, this will be done in the background and may take some time." : "Je kan het hernoemen van ongeldige bestandsnamen starten, dit wordt gedaan in de achtergrond en duurt mogelijk even.",
"Please note that this may cause high workload on the sync clients." : "Wees gewaarschuwd dat dit een hoge werklast voor het syncen van clients kan opleveren.",
"Limit" : "Limiet",
"This allows to configure how many users should be processed in one background job run." : "Met dit kan je configureren hoeveel gebruikers verwerkt worden tijdens een achtergrond taak. ",
"Sanitize filenames" : "Opschonen bestanden",
"(starting)" : "(begonnen)",
"Fill template fields" : "Vul de velden van het sjabloon in",
"Submitting fields …" : "Toevoegen velden …",
"Submit" : "Verwerken",
"Choose a file or folder to transfer" : "Kies een bestand of map om over te dragen",
"Transfer" : "Overdragen",
@@ -155,6 +182,7 @@
"Select file or folder to link to" : "Selecteer een bestand of map om naar te linken",
"Choose {file}" : "Kies {file}",
"Clipboard is not available" : "Klembord niet beschikbaar",
"WebDAV URL copied" : "WebDAV URL gekopieerd",
"Files settings" : "Instellingen voor bestanden",
"General" : "Algemeen",
"Default view" : "Standaardweergave",
@@ -166,24 +194,37 @@
"Appearance" : "Uiterlijk",
"Show hidden files" : "Toon verborgen bestanden",
"Show file type column" : "Toon bestandstypekolom",
"Show file extensions" : "Laat bestand extensies zien",
"Crop image previews" : "Snij afbeeldingvoorbeelden bij",
"Additional settings" : "Aanvullende instellingen",
"WebDAV" : "WebDAV",
"WebDAV URL" : "WebDAV URL",
"Copy" : "Kopiëren",
"How to access files using WebDAV" : "Hoe bestanden te benaderen met WebDAV",
"Two-Factor Authentication is enabled for your account, and therefore you need to use an app password to connect an external WebDAV client." : "Tweefactorauthenticatie is ingeschakeld voor jouw account en daarom moet je een app-wachtwoord gebruiken om een externe WebDAV-client aan te sluiten.",
"Warnings" : "Waarschuwingen",
"Warn before changing a file extension" : "Waarschuw voordat een bestand extensie wordt gewijzigd",
"Warn before deleting files" : "Waarschuw voordat bestanden worden verwijderd",
"Keyboard shortcuts" : "Toetsenbord sneltoetsen",
"File actions" : "Bestandsacties",
"Rename" : "Naam wijzigen",
"Delete" : "Verwijderen",
"Add or remove favorite" : "Verwijder of voeg een favoriet toe",
"Manage tags" : "Berichttags",
"Selection" : "Selectie",
"Select all files" : "Selecteer alle bestanden",
"Deselect all" : "Deselecteer alles",
"Select or deselect" : "Selecteren of deselecteren",
"Select a range" : "Selecteer een bereik",
"Navigation" : "Navigatie",
"Go to parent folder" : "Ga naar bovenliggende map",
"Go to file above" : "Ga naar bovenliggend bestand",
"Go to file below" : "Ga naar onderliggend bestand",
"Go left in grid" : "Ga naar links in raster",
"Go right in grid" : "Ga naar rechts in raster",
"View" : "Bekijken",
"Toggle grid view" : "Omschakelen roosterweergave",
"Open file sidebar" : "Open bestands zijbalk",
"Show those shortcuts" : "Toon die snelkoppelingen",
"Share" : "Delen",
"Shared by link" : "Gedeeld via link",
@@ -219,6 +260,7 @@
"Search for files" : "Zoeken naar bestanden",
"Allow to restrict filenames to ensure files can be synced with all clients. By default all filenames valid on POSIX (e.g. Linux or macOS) are allowed." : "Toestaan om bestandsnamen te beperken om te borgen dat bestanden met alle cliënts gesynchroniseerd kunnen worden. Standaard zijn alle bestandsnamen valide die zijn toegestaan op POSIX (zoals Linux en macOS.)",
"After enabling the Windows compatible filenames, existing files cannot be modified anymore but can be renamed to valid new names by their owner." : "Na inschakeling van Windows-compatibele bestandsnamen, kunnen bestaande bestanden niet meer worden gewijzigd, maar kunnen ze door de eigenaar worden hernoemd naar geldige nieuwe namen.",
"Failed to toggle Windows filename support" : "Omschakelen naar Windows bestand ondersteuning mislukt",
"Files compatibility" : "Bestandscompatibiliteit",
"Enforce Windows compatibility" : "Dwing Windows-compatibiliteit af",
"This will block filenames not valid on Windows systems, like using reserved names or special characters. But this will not enforce compatibility of case sensitivity." : "Dit zal bestandsnamen blokkeren die niet toegestaan zijn op Windows-systemen, zoals gereserveerde namen of speciale tekens. Dit dwingt niet tot compatibiliteit voor hoofd- en kleine letters.",
@@ -228,6 +270,8 @@
"Create a new file with the selected template" : "Maak een nieuw bestand met het geselecteerde sjabloon",
"Creating file" : "Maken bestand",
"Save as {displayName}" : "Opslaan als {displayName}",
"Save as …" : "Bewaar als …",
"Converting files …" : "Bestanden converteren …",
"Failed to convert files: {message}" : "Conversie van bestanden mislukt: {message} ",
"All files failed to be converted" : "De conversie van alle bestanden is mislukt",
"One file could not be converted: {message}" : "Een bestand kon niet worden geconverteerd: {message}",
@@ -235,6 +279,7 @@
"_One file successfully converted_::_%n files successfully converted_" : ["Een bestand succesvol geconverteerd","%n bestanden succesvol geconverteerd"],
"Files successfully converted" : "Bestanden succesvol geconverteerd",
"Failed to convert files" : "Conversie van bestanden mislukt",
"Converting file …" : "Bestand converteren …",
"File successfully converted" : "Bestand succesvol geconverteerd",
"Failed to convert file: {message}" : "Conversie van bestand mislukt: {message} ",
"Failed to convert file" : "Conversie van bestand mislukt",
@@ -253,6 +298,10 @@
"Confirm deletion" : "Bevestig verwijderen",
"Cancel" : "Annuleren",
"Download" : "Downloaden",
"The requested file is not available." : "Het gevraagde bestand is niet beschikbaar.",
"The requested files are not available." : "De gevraagde bestanden zijn niet beschikbaar.",
"Moving \"{source}\" to \"{destination}\" …" : "Verplaatsen \"{source}\" naar \"{destination}\" …",
"Copying \"{source}\" to \"{destination}\" …" : "Kopieren \"{source}\" naar \"{destination}\" …",
"Destination is not a folder" : "Bestemming is geen map",
"This file/folder is already in that directory" : "Dit bestand/deze map staat al in die map",
"You cannot move a file/folder onto itself or into a subfolder of itself" : "Je kan een bestand/map niet verplaatsen naar zichzelf of naar een subfolder van zichzelf.",
@@ -315,6 +364,7 @@
"The name \"{newName}\" is already used in the folder \"{dir}\". Please choose a different name." : "De naam \"{newName}\" bestaat al in map \"{dir}\". Kies een andere naam.",
"Could not rename \"{oldName}\"" : "Kon \"{oldName}\" niet hernoemen",
"This operation is forbidden" : "Deze taak is verboden",
"This folder is unavailable, please try again later or contact the administration" : "Deze map is niet beschikbaar, probeer het later nog eens of neem contact op met de beheerder",
"Storage is temporarily not available" : "Opslag is tijdelijk niet beschikbaar",
"Unexpected error: {error}" : "Onverwachte fout: {error}",
"_%n file_::_%n files_" : ["%n bestand","%n bestanden"],
@@ -391,6 +441,9 @@
"Photos and images" : "Foto's en afbeeldingen",
"New folder creation cancelled" : "Maken van nieuwe map geannuleerd",
"This directory is unavailable, please check the logs or contact the administrator" : "Deze map is niet beschikbaar. Verifieer de logs of neem contact op met de beheerder",
"All folders" : "Alle mappen"
"All folders" : "Alle mappen",
"Search everywhere …" : "Zoek in alles...",
"Search here …" : "Zoek hier ...",
"Preparing …" : "Voorbereiden ..."
},"pluralForm" :"nplurals=2; plural=(n != 1);"
}

View File

@@ -326,7 +326,7 @@ OC.L10N.register(
"The file should now open on your device. If it doesn't, please check that you have the desktop app installed." : "Тепер файл можна відкрити на вашому пристрої. Якщо він не відкривається, перевірте, що у вас встановлено настільний клієнт синхронізації.",
"Retry and close" : "Спробувати ще раз",
"Open online" : "Відкрити віддалено",
"Details" : еталі",
"Details" : окладно",
"View in folder" : "Переглянути у каталозі",
"Today" : "Сьогодні",
"Last 7 days" : "За останні 7 днів",
@@ -439,7 +439,7 @@ OC.L10N.register(
"Move cancelled" : "Переміщення скасовано",
"Cancelled move or copy of \"{filename}\"." : "Скасовано переміщення або копіювання \"{filename}\".",
"Cancelled move or copy operation" : "Переміщення або копіювання скасовано",
"Open details" : "Показати деталі",
"Open details" : "Показати докладно",
"Photos and images" : "Зображення",
"New folder creation cancelled" : "Створення нового каталогу скасовано",
"This directory is unavailable, please check the logs or contact the administrator" : "Каталог недоступний, будь ласка, перевірте файл журналу або зверніться до адміністратора ",

View File

@@ -324,7 +324,7 @@
"The file should now open on your device. If it doesn't, please check that you have the desktop app installed." : "Тепер файл можна відкрити на вашому пристрої. Якщо він не відкривається, перевірте, що у вас встановлено настільний клієнт синхронізації.",
"Retry and close" : "Спробувати ще раз",
"Open online" : "Відкрити віддалено",
"Details" : еталі",
"Details" : окладно",
"View in folder" : "Переглянути у каталозі",
"Today" : "Сьогодні",
"Last 7 days" : "За останні 7 днів",
@@ -437,7 +437,7 @@
"Move cancelled" : "Переміщення скасовано",
"Cancelled move or copy of \"{filename}\"." : "Скасовано переміщення або копіювання \"{filename}\".",
"Cancelled move or copy operation" : "Переміщення або копіювання скасовано",
"Open details" : "Показати деталі",
"Open details" : "Показати докладно",
"Photos and images" : "Зображення",
"New folder creation cancelled" : "Створення нового каталогу скасовано",
"This directory is unavailable, please check the logs or contact the administrator" : "Каталог недоступний, будь ласка, перевірте файл журналу або зверніться до адміністратора ",

View File

@@ -239,8 +239,8 @@ async function openFilePickerForAction(
if (action === MoveCopyAction.COPY || action === MoveCopyAction.MOVE_OR_COPY) {
buttons.push({
label: target ? t('files', 'Copy to {target}', { target }, undefined, { escape: false, sanitize: false }) : t('files', 'Copy'),
type: 'primary',
label: target ? t('files', 'Copy to {target}', { target }, { escape: false, sanitize: false }) : t('files', 'Copy'),
variant: 'primary',
icon: CopyIconSvg,
disabled: selection.some((node) => (node.permissions & Permission.CREATE) === 0),
async callback(destination: Node[]) {
@@ -271,7 +271,7 @@ async function openFilePickerForAction(
if (action === MoveCopyAction.MOVE || action === MoveCopyAction.MOVE_OR_COPY) {
buttons.push({
label: target ? t('files', 'Move to {target}', { target }, undefined, { escape: false, sanitize: false }) : t('files', 'Move'),
type: action === MoveCopyAction.MOVE ? 'primary' : 'secondary',
variant: action === MoveCopyAction.MOVE ? 'primary' : 'secondary',
icon: FolderMoveSvg,
async callback(destination: Node[]) {
resolve({

View File

@@ -98,7 +98,7 @@ async function confirmLocalEditDialog(): Promise<'online' | 'local' | false> {
.setButtons([
{
label: t('files', 'Retry and close'),
type: 'secondary',
variant: 'secondary',
callback: () => {
result = 'local'
},
@@ -106,7 +106,7 @@ async function confirmLocalEditDialog(): Promise<'online' | 'local' | false> {
{
label: t('files', 'Open online'),
icon: IconWeb,
type: 'primary',
variant: 'primary',
callback: () => {
result = 'online'
},

View File

@@ -24,8 +24,9 @@ const searchStore = useSearchStore()
* we need to clear the search box.
*/
onBeforeNavigation((to, from, next) => {
if (to.params.view !== VIEW_ID && from.params.view === VIEW_ID) {
// we are leaving the search view so unset the query
if (to.params.view !== VIEW_ID
&& (from.params.view === VIEW_ID || from.query.dir !== to.query.dir)) {
// we are leaving the search view or navigate to another directory -> unset the query
searchStore.query = ''
searchStore.scope = 'filter'
} else if (to.params.view === VIEW_ID && from.params.view === VIEW_ID) {

View File

@@ -1,55 +0,0 @@
/*!
* SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
import { defineComponent } from 'vue'
import { useFileListWidth } from './useFileListWidth.ts'
const ComponentMock = defineComponent({
template: '<div id="test-component" style="width: 100%;background: white;">{{ fileListWidth }}</div>',
setup() {
return {
fileListWidth: useFileListWidth(),
}
},
})
const FileListMock = defineComponent({
template: '<main id="app-content-vue" style="width: 100%;"><component-mock /></main>',
components: {
ComponentMock,
},
})
describe('composable: fileListWidth', () => {
it('Has initial value', () => {
cy.viewport(600, 400)
cy.mount(FileListMock, {})
cy.get('#app-content-vue')
.should('be.visible')
.and('contain.text', '600')
})
it('Is reactive to size change', () => {
cy.viewport(600, 400)
cy.mount(FileListMock)
cy.get('#app-content-vue').should('contain.text', '600')
cy.viewport(800, 400)
cy.screenshot()
cy.get('#app-content-vue').should('contain.text', '800')
})
it('Is reactive to style changes', () => {
cy.viewport(600, 400)
cy.mount(FileListMock)
cy.get('#app-content-vue')
.should('be.visible')
.and('contain.text', '600')
.invoke('attr', 'style', 'width: 100px')
cy.get('#app-content-vue')
.should('contain.text', '100')
})
})

View File

@@ -0,0 +1,80 @@
/*!
* SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
import { cleanup, render } from '@testing-library/vue'
import { configMocks, mockResizeObserver } from 'jsdom-testing-mocks'
import { afterAll, afterEach, beforeAll, beforeEach, describe, expect, it } from 'vitest'
import { defineComponent } from 'vue'
import { nextTick } from 'vue'
let resizeObserver: ReturnType<typeof mockResizeObserver>
describe('composable: fileListWidth', () => {
configMocks({ beforeAll, afterAll, beforeEach, afterEach })
beforeAll(() => {
resizeObserver = mockResizeObserver()
})
beforeEach(cleanup)
it('Has initial value', async () => {
const { component } = await getFileList()
expect(component.textContent).toBe('600')
})
it('observes the file list element', async () => {
const { fileList } = await getFileList()
expect(resizeObserver.getObservedElements()).toContain(fileList)
})
it('Is reactive to size change', async () => {
const { component, fileList } = await getFileList()
expect(component.textContent).toBe('600')
expect(resizeObserver.getObservedElements()).toHaveLength(1)
resizeObserver.mockElementSize(fileList, { contentBoxSize: { inlineSize: 800, blockSize: 300 } })
resizeObserver.resize(fileList)
// await rending
await nextTick()
expect(component.textContent).toBe('800')
})
})
async function getFileList() {
const { useFileListWidth } = await import('./useFileListWidth.ts')
const ComponentMock = defineComponent({
template: '<div data-testid="component" style="width: 100%;background: white;">{{ fileListWidth }}</div>',
setup() {
return {
fileListWidth: useFileListWidth(),
}
},
})
const FileListMock = defineComponent({
template: '<main id="app-content-vue" style="width: 100%;"><component-mock /></main>',
components: {
ComponentMock,
},
})
const root = render(FileListMock)
const fileList = root.baseElement.querySelector('#app-content-vue') as HTMLElement
// mock initial size
resizeObserver.mockElementSize(fileList, { contentBoxSize: { inlineSize: 600, blockSize: 200 } })
resizeObserver.resize()
// await rending
await nextTick()
return {
root,
component: root.getByTestId('component'),
fileList,
}
}

View File

@@ -5,7 +5,7 @@
import type { Node } from '@nextcloud/files'
import { spawnDialog } from '@nextcloud/dialogs'
import { spawnDialog } from '@nextcloud/vue/functions/dialog'
import NewNodeDialog from '../components/NewNodeDialog.vue'
interface ILabels {

View File

@@ -1,162 +0,0 @@
/*!
* SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
import { createTestingPinia } from '@pinia/testing'
import DialogConfirmFileExtension from './DialogConfirmFileExtension.vue'
import { useUserConfigStore } from '../store/userconfig.ts'
describe('DialogConfirmFileExtension', () => {
it('renders with both extensions', () => {
cy.mount(DialogConfirmFileExtension, {
propsData: {
oldExtension: '.old',
newExtension: '.new',
},
global: {
plugins: [createTestingPinia({
createSpy: cy.spy,
})],
},
})
cy.findByRole('dialog')
.as('dialog')
.should('be.visible')
cy.get('@dialog')
.findByRole('heading')
.should('contain.text', 'Change file extension')
cy.get('@dialog')
.findByRole('checkbox', { name: /Do not show this dialog again/i })
.should('exist')
.and('not.be.checked')
cy.get('@dialog')
.findByRole('button', { name: 'Keep .old' })
.should('be.visible')
cy.get('@dialog')
.findByRole('button', { name: 'Use .new' })
.should('be.visible')
})
it('renders without old extension', () => {
cy.mount(DialogConfirmFileExtension, {
propsData: {
newExtension: '.new',
},
global: {
plugins: [createTestingPinia({
createSpy: cy.spy,
})],
},
})
cy.findByRole('dialog')
.as('dialog')
.should('be.visible')
cy.get('@dialog')
.findByRole('button', { name: 'Keep without extension' })
.should('be.visible')
cy.get('@dialog')
.findByRole('button', { name: 'Use .new' })
.should('be.visible')
})
it('renders without new extension', () => {
cy.mount(DialogConfirmFileExtension, {
propsData: {
oldExtension: '.old',
},
global: {
plugins: [createTestingPinia({
createSpy: cy.spy,
})],
},
})
cy.findByRole('dialog')
.as('dialog')
.should('be.visible')
cy.get('@dialog')
.findByRole('button', { name: 'Keep .old' })
.should('be.visible')
cy.get('@dialog')
.findByRole('button', { name: 'Remove extension' })
.should('be.visible')
})
it('emits correct value on keep old', () => {
cy.mount(DialogConfirmFileExtension, {
propsData: {
oldExtension: '.old',
newExtension: '.new',
},
global: {
plugins: [createTestingPinia({
createSpy: cy.spy,
})],
},
}).as('component')
cy.findByRole('dialog')
.as('dialog')
.should('be.visible')
cy.get('@dialog')
.findByRole('button', { name: 'Keep .old' })
.click()
cy.get('@component')
.its('wrapper')
.should((wrapper) => expect(wrapper.emitted('close')).to.eql([[false]]))
})
it('emits correct value on use new', () => {
cy.mount(DialogConfirmFileExtension, {
propsData: {
oldExtension: '.old',
newExtension: '.new',
},
global: {
plugins: [createTestingPinia({
createSpy: cy.spy,
})],
},
}).as('component')
cy.findByRole('dialog')
.as('dialog')
.should('be.visible')
cy.get('@dialog')
.findByRole('button', { name: 'Use .new' })
.click()
cy.get('@component')
.its('wrapper')
.should((wrapper) => expect(wrapper.emitted('close')).to.eql([[true]]))
})
it('updates user config when checking the checkbox', () => {
const pinia = createTestingPinia({
createSpy: cy.spy,
})
cy.mount(DialogConfirmFileExtension, {
propsData: {
oldExtension: '.old',
newExtension: '.new',
},
global: {
plugins: [pinia],
},
}).as('component')
cy.findByRole('dialog')
.as('dialog')
.should('be.visible')
cy.get('@dialog')
.findByRole('checkbox', { name: /Do not show this dialog again/i })
.check({ force: true })
cy.wrap(useUserConfigStore())
.its('update')
.should('have.been.calledWith', 'show_dialog_file_extension', false)
})
})

View File

@@ -0,0 +1,132 @@
/*!
* SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
import { createTestingPinia } from '@pinia/testing'
import { cleanup, fireEvent, render } from '@testing-library/vue'
import { beforeEach, describe, expect, it, vi } from 'vitest'
import DialogConfirmFileExtension from './DialogConfirmFileExtension.vue'
import { useUserConfigStore } from '../store/userconfig.ts'
describe('DialogConfirmFileExtension', () => {
beforeEach(cleanup)
it('renders with both extensions', async () => {
const component = render(DialogConfirmFileExtension, {
props: {
oldExtension: '.old',
newExtension: '.new',
},
global: {
plugins: [createTestingPinia({
createSpy: vi.fn,
})],
},
})
await expect(component.findByRole('dialog', { name: 'Change file extension' })).resolves.not.toThrow()
expect((component.getByRole('checkbox', { name: /Do not show this dialog again/i }) as HTMLInputElement).checked).toBe(false)
await expect(component.findByRole('button', { name: 'Keep .old' })).resolves.not.toThrow()
await expect(component.findByRole('button', { name: 'Use .new' })).resolves.not.toThrow()
})
it('renders without old extension', async () => {
const component = render(DialogConfirmFileExtension, {
props: {
newExtension: '.new',
},
global: {
plugins: [createTestingPinia({
createSpy: vi.fn,
})],
},
})
await expect(component.findByRole('dialog', { name: 'Change file extension' })).resolves.not.toThrow()
await expect(component.findByRole('button', { name: 'Keep without extension' })).resolves.not.toThrow()
await expect(component.findByRole('button', { name: 'Use .new' })).resolves.not.toThrow()
})
it('renders without new extension', async () => {
const component = render(DialogConfirmFileExtension, {
props: {
oldExtension: '.old',
},
global: {
plugins: [createTestingPinia({
createSpy: vi.fn,
})],
},
})
await expect(component.findByRole('dialog', { name: 'Change file extension' })).resolves.not.toThrow()
await expect(component.findByRole('button', { name: 'Keep .old' })).resolves.not.toThrow()
await expect(component.findByRole('button', { name: 'Remove extension' })).resolves.not.toThrow()
})
it('emits correct value on keep old', async () => {
const onclose = vi.fn()
const component = render(DialogConfirmFileExtension, {
props: {
oldExtension: '.old',
newExtension: '.new',
},
listeners: {
close: onclose,
},
global: {
plugins: [createTestingPinia({
createSpy: vi.fn,
})],
},
})
await fireEvent.click(component.getByRole('button', { name: 'Keep .old' }))
expect(onclose).toHaveBeenCalledOnce()
expect(onclose).toHaveBeenCalledWith(false)
})
it('emits correct value on use new', async () => {
const onclose = vi.fn()
const component = render(DialogConfirmFileExtension, {
props: {
oldExtension: '.old',
newExtension: '.new',
},
listeners: {
close: onclose,
},
global: {
plugins: [createTestingPinia({
createSpy: vi.fn,
})],
},
})
await fireEvent.click(component.getByRole('button', { name: 'Use .new' }))
expect(onclose).toHaveBeenCalledOnce()
expect(onclose).toHaveBeenCalledWith(true)
})
it('updates user config when checking the checkbox', async () => {
const pinia = createTestingPinia({
createSpy: vi.fn,
})
const component = render(DialogConfirmFileExtension, {
props: {
oldExtension: '.old',
newExtension: '.new',
},
global: {
plugins: [pinia],
},
})
await fireEvent.click(component.getByRole('checkbox', { name: /Do not show this dialog again/i }))
const store = useUserConfigStore()
expect(store.update).toHaveBeenCalledOnce()
expect(store.update).toHaveBeenCalledWith('show_dialog_file_extension', false)
})
})

View File

@@ -29,13 +29,13 @@ const dontShowAgain = computed({
set: (value: boolean) => userConfigStore.update('show_dialog_file_extension', !value),
})
const buttons = computed<IDialogButton[]>(() => [
const buttons = computed(() => [
{
label: props.oldExtension
? t('files', 'Keep {old}', { old: props.oldExtension })
: t('files', 'Keep without extension'),
icon: svgIconCancel,
type: 'secondary',
variant: 'secondary',
callback: () => closeDialog(false),
},
{
@@ -43,10 +43,10 @@ const buttons = computed<IDialogButton[]>(() => [
? t('files', 'Use {new}', { new: props.newExtension })
: t('files', 'Remove extension'),
icon: svgIconCheck,
type: 'primary',
variant: 'primary',
callback: () => closeDialog(true),
},
])
] satisfies IDialogButton[])
/** Open state of the dialog */
const open = ref(true)

View File

@@ -4,88 +4,76 @@
-->
<template>
<div :id="containerId">
<FilePicker v-bind="filepickerOptions" @close="onClose" />
</div>
<div :id="containerId" />
</template>
<script lang="ts">
<script setup lang="ts">
import type { IFilePickerButton } from '@nextcloud/dialogs'
import type { Node as NcNode } from '@nextcloud/files'
import { FilePickerVue as FilePicker } from '@nextcloud/dialogs/filepicker.js'
import { translate as t } from '@nextcloud/l10n'
import { generateUrl } from '@nextcloud/router'
import { defineComponent } from 'vue'
import { FilePickerBuilder } from '@nextcloud/dialogs'
import { t } from '@nextcloud/l10n'
import { onMounted } from 'vue'
import { generateFileUrl } from '../../../files_sharing/src/utils/generateUrl.ts'
import logger from '../logger.ts'
export default defineComponent({
name: 'FileReferencePickerElement',
components: {
FilePicker,
},
defineProps<{
providerId: string
accessible: boolean
}>()
props: {
providerId: {
type: String,
required: true,
},
const emit = defineEmits<{
(e: 'submit', url: string): void
(e: 'cancel'): void
}>()
accessible: {
type: Boolean,
default: false,
},
},
const containerId = `filepicker-${Math.random().toString(36).slice(7)}`
computed: {
containerId() {
return `filepicker-${Math.random().toString(36).slice(7)}`
},
const filePicker = new FilePickerBuilder(t('files', 'Select file or folder to link to'))
.allowDirectories(true)
.setButtonFactory(buttonFactory)
.setContainer(`#${containerId}`)
.setMultiSelect(false)
.build()
filepickerOptions() {
return {
allowPickDirectory: true,
buttons: this.buttonFactory,
container: `#${this.containerId}`,
multiselect: false,
name: t('files', 'Select file or folder to link to'),
}
},
},
methods: {
t,
buttonFactory(selected: NcNode[]): IFilePickerButton[] {
const buttons = [] as IFilePickerButton[]
if (selected.length === 0) {
return []
}
const node = selected.at(0)
if (node.path === '/') {
return [] // Do not allow selecting the users root folder
}
buttons.push({
label: t('files', 'Choose {file}', { file: node.displayname }),
type: 'primary',
callback: this.onClose,
})
return buttons
},
onClose(nodes?: NcNode[]) {
if (nodes === undefined || nodes.length === 0) {
this.$emit('cancel')
} else {
this.onSubmit(nodes[0])
}
},
onSubmit(node: NcNode) {
const url = new URL(window.location.href)
url.pathname = generateUrl('/f/{fileId}', { fileId: node.fileid! })
url.search = ''
this.$emit('submit', url.href)
},
},
onMounted(async () => {
try {
const [node] = await filePicker.pickNodes()
onSubmit(node)
} catch (error) {
logger.debug('Aborted picking nodes:', { error })
emit('cancel')
}
})
/**
* Get buttons for the file picker dialog
*
* @param selected - currently selected nodes
*/
function buttonFactory(selected: NcNode[]): IFilePickerButton[] {
const buttons = [] as IFilePickerButton[]
const node = selected[0]
if (node === undefined) {
return []
}
if (node.path === '/') {
return [] // Do not allow selecting the users root folder
}
buttons.push({
label: t('files', 'Choose {file}', { file: node.displayname }),
variant: 'primary',
callback: () => {}, // handled by the pickNodes method
})
return buttons
}
/**
* @param node - selected node
*/
function onSubmit(node: NcNode) {
emit('submit', generateFileUrl(node.fileid!))
}
</script>

View File

@@ -1,262 +0,0 @@
/**
* SPDX-FileCopyrightText: 2022 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
import type { Folder, Navigation } from '@nextcloud/files'
import FolderSvg from '@mdi/svg/svg/folder.svg?raw'
import { getNavigation, View } from '@nextcloud/files'
import { createTestingPinia } from '@pinia/testing'
import NavigationView from './FilesNavigation.vue'
import router from '../router/router.ts'
import RouterService from '../services/RouterService.ts'
import { useViewConfigStore } from '../store/viewConfig.ts'
function resetNavigation() {
const nav = getNavigation()
;[...nav.views].forEach(({ id }) => nav.remove(id))
nav.setActive(null)
}
function createView(id: string, name: string, parent?: string) {
return new View({
id,
name,
getContents: async () => ({ folder: {} as Folder, contents: [] }),
icon: FolderSvg,
order: 1,
parent,
})
}
/**
*
*/
function mockWindow() {
window.OCP ??= {}
window.OCP.Files ??= {}
window.OCP.Files.Router = new RouterService(router)
}
describe('Navigation renders', () => {
before(async () => {
delete window._nc_navigation
mockWindow()
getNavigation().register(createView('files', 'Files'))
await router.replace({ name: 'filelist', params: { view: 'files' } })
cy.mockInitialState('files', 'storageStats', {
used: 1000 * 1000 * 1000,
quota: -1,
})
})
after(() => cy.unmockInitialState())
it('renders', () => {
cy.mount(NavigationView, {
router,
global: {
plugins: [createTestingPinia({
createSpy: cy.spy,
})],
},
})
cy.get('[data-cy-files-navigation]').should('be.visible')
cy.get('[data-cy-files-navigation-settings-quota]').should('be.visible')
cy.get('[data-cy-files-navigation-settings-button]').should('be.visible')
})
})
describe('Navigation API', () => {
let Navigation: Navigation
before(async () => {
delete window._nc_navigation
Navigation = getNavigation()
mockWindow()
await router.replace({ name: 'filelist', params: { view: 'files' } })
})
beforeEach(() => resetNavigation())
it('Check API entries rendering', () => {
Navigation.register(createView('files', 'Files'))
console.warn(Navigation.views)
cy.mount(NavigationView, {
router,
global: {
plugins: [
createTestingPinia({
createSpy: cy.spy,
}),
],
},
})
cy.get('[data-cy-files-navigation]').should('be.visible')
cy.get('[data-cy-files-navigation-item]').should('have.length', 1)
cy.get('[data-cy-files-navigation-item="files"]').should('be.visible')
cy.get('[data-cy-files-navigation-item="files"]').should('contain.text', 'Files')
})
it('Adds a new entry and render', () => {
Navigation.register(createView('files', 'Files'))
Navigation.register(createView('sharing', 'Sharing'))
cy.mount(NavigationView, {
router,
global: {
plugins: [createTestingPinia({
createSpy: cy.spy,
})],
},
})
cy.get('[data-cy-files-navigation]').should('be.visible')
cy.get('[data-cy-files-navigation-item]').should('have.length', 2)
cy.get('[data-cy-files-navigation-item="sharing"]').should('be.visible')
cy.get('[data-cy-files-navigation-item="sharing"]').should('contain.text', 'Sharing')
})
it('Adds a new children, render and open menu', () => {
Navigation.register(createView('files', 'Files'))
Navigation.register(createView('sharing', 'Sharing'))
Navigation.register(createView('sharingin', 'Shared with me', 'sharing'))
cy.mount(NavigationView, {
router,
global: {
plugins: [createTestingPinia({
createSpy: cy.spy,
})],
},
})
cy.wrap(useViewConfigStore()).as('viewConfigStore')
cy.get('[data-cy-files-navigation]').should('be.visible')
cy.get('[data-cy-files-navigation-item]').should('have.length', 3)
// Toggle the sharing entry children
cy.get('[data-cy-files-navigation-item="sharing"] button.icon-collapse').should('exist')
cy.get('[data-cy-files-navigation-item="sharing"] button.icon-collapse').click({ force: true })
// Expect store update to be called
cy.get('@viewConfigStore').its('update').should('have.been.calledWith', 'sharing', 'expanded', true)
// Validate children
cy.get('[data-cy-files-navigation-item="sharingin"]').should('be.visible')
cy.get('[data-cy-files-navigation-item="sharingin"]').should('contain.text', 'Shared with me')
// Toggle the sharing entry children 🇦again
cy.get('[data-cy-files-navigation-item="sharing"] button.icon-collapse').click({ force: true })
cy.get('[data-cy-files-navigation-item="sharingin"]').should('not.be.visible')
// Expect store update to be called
cy.get('@viewConfigStore').its('update').should('have.been.calledWith', 'sharing', 'expanded', false)
})
it('Throws when adding a duplicate entry', () => {
Navigation.register(createView('files', 'Files'))
expect(() => Navigation.register(createView('files', 'Files')))
.to.throw('View id files is already registered')
})
})
describe('Quota rendering', () => {
before(async () => {
delete window._nc_navigation
mockWindow()
getNavigation().register(createView('files', 'Files'))
await router.replace({ name: 'filelist', params: { view: 'files' } })
})
afterEach(() => cy.unmockInitialState())
it('Unknown quota', () => {
cy.mount(NavigationView, {
router,
global: {
plugins: [createTestingPinia({
createSpy: cy.spy,
})],
},
})
cy.get('[data-cy-files-navigation-settings-quota]').should('not.exist')
})
it('Unlimited quota', () => {
cy.mockInitialState('files', 'storageStats', {
used: 1024 * 1024 * 1024,
quota: -1,
total: 50 * 1024 * 1024 * 1024,
})
cy.mount(NavigationView, {
router,
global: {
plugins: [createTestingPinia({
createSpy: cy.spy,
})],
},
})
cy.get('[data-cy-files-navigation-settings-quota]').should('be.visible')
cy.get('[data-cy-files-navigation-settings-quota]').should('contain.text', '1 GB used')
cy.get('[data-cy-files-navigation-settings-quota] progress').should('not.exist')
})
it('Non-reached quota', () => {
cy.mockInitialState('files', 'storageStats', {
used: 1024 * 1024 * 1024,
quota: 5 * 1024 * 1024 * 1024,
total: 5 * 1024 * 1024 * 1024,
relative: 20, // percent
})
cy.mount(NavigationView, {
router,
global: {
plugins: [createTestingPinia({
createSpy: cy.spy,
})],
},
})
cy.get('[data-cy-files-navigation-settings-quota]').should('be.visible')
cy.get('[data-cy-files-navigation-settings-quota]').should('contain.text', '1 GB of 5 GB used')
cy.get('[data-cy-files-navigation-settings-quota] progress')
.should('exist')
.and('have.attr', 'value', '20')
})
it('Reached quota', () => {
cy.mockInitialState('files', 'storageStats', {
used: 5 * 1024 * 1024 * 1024,
quota: 1024 * 1024 * 1024,
total: 1024 * 1024 * 1024,
relative: 500, // percent
})
cy.mount(NavigationView, {
router,
global: {
plugins: [createTestingPinia({
createSpy: cy.spy,
})],
},
})
cy.get('[data-cy-files-navigation-settings-quota]').should('be.visible')
cy.get('[data-cy-files-navigation-settings-quota]').should('contain.text', '5 GB of 1 GB used')
cy.get('[data-cy-files-navigation-settings-quota] progress')
.should('exist')
.and('have.attr', 'value', '100') // progress max is 100
})
})

View File

@@ -0,0 +1,286 @@
/**
* SPDX-FileCopyrightText: 2022 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
import type { Folder, Navigation } from '@nextcloud/files'
import FolderSvg from '@mdi/svg/svg/folder.svg?raw'
import { getNavigation, View } from '@nextcloud/files'
import { createTestingPinia } from '@pinia/testing'
import { cleanup, fireEvent, getAllByRole, render } from '@testing-library/vue'
import { afterEach, beforeAll, beforeEach, describe, expect, it, vi } from 'vitest'
import NavigationView from './FilesNavigation.vue'
import router from '../router/router.ts'
import RouterService from '../services/RouterService.ts'
import { useViewConfigStore } from '../store/viewConfig.ts'
afterEach(() => removeInitialState())
beforeAll(async () => {
Object.defineProperty(document.documentElement, 'clientWidth', { value: 1920 })
await fireEvent.resize(window)
})
describe('Navigation', () => {
beforeEach(cleanup)
beforeEach(async () => {
delete window._nc_navigation
mockWindow()
getNavigation().register(createView('files', 'Files'))
await router.replace({ name: 'filelist', params: { view: 'files' } })
})
it('renders navigation with settings button and search', async () => {
const component = render(NavigationView, {
router,
global: {
plugins: [createTestingPinia({
createSpy: vi.fn,
})],
},
})
// see the navigation
await expect(component.findByRole('navigation', { name: 'Files' })).resolves.not.toThrow()
// see the search box
await expect(component.findByRole('searchbox', { name: /Search here/ })).resolves.not.toThrow()
// see the settings entry
await expect(component.findByRole('link', { name: /Files settings/ })).resolves.not.toThrow()
})
it('renders no quota without storage stats', () => {
const component = render(NavigationView, {
router,
global: {
plugins: [createTestingPinia({
createSpy: vi.fn,
})],
},
})
expect(component.baseElement.querySelector('[data-cy-files-navigation-settings-quota]')).toBeNull()
})
it('Unlimited quota shows used storage but no progressbar', async () => {
mockInitialState('files', 'storageStats', {
used: 1024 * 1024 * 1024,
quota: -1,
total: 50 * 1024 * 1024 * 1024,
})
const component = render(NavigationView, {
router,
global: {
plugins: [createTestingPinia({
createSpy: vi.fn,
})],
},
})
expect(component.baseElement.querySelector('[data-cy-files-navigation-settings-quota]')).not.toBeNull()
await expect(component.findByText('1 GB used')).resolves.not.toThrow()
await expect(component.findByRole('progressbar')).rejects.toThrow()
})
it('Non-reached quota shows stats and progress', async () => {
mockInitialState('files', 'storageStats', {
used: 1024 * 1024 * 1024,
quota: 5 * 1024 * 1024 * 1024,
total: 5 * 1024 * 1024 * 1024,
relative: 20, // percent
})
const component = render(NavigationView, {
router,
global: {
plugins: [createTestingPinia({
createSpy: vi.fn,
})],
},
})
await expect(component.findByText('1 GB of 5 GB used')).resolves.not.toThrow()
await expect(component.findByRole('progressbar')).resolves.not.toThrow()
expect((component.getByRole('progressbar') as HTMLProgressElement).value).toBe(20)
})
it('Reached quota', async () => {
mockInitialState('files', 'storageStats', {
used: 5 * 1024 * 1024 * 1024,
quota: 1024 * 1024 * 1024,
total: 1024 * 1024 * 1024,
relative: 500, // percent
})
const component = render(NavigationView, {
router,
global: {
plugins: [createTestingPinia({
createSpy: vi.fn,
})],
},
})
await expect(component.findByText('5 GB of 1 GB used')).resolves.not.toThrow()
await expect(component.findByRole('progressbar')).resolves.not.toThrow()
expect((component.getByRole('progressbar') as HTMLProgressElement).value).toBe(100)
})
})
describe('Navigation API', () => {
let Navigation: Navigation
beforeEach(async () => {
delete window._nc_navigation
Navigation = getNavigation()
mockWindow()
await router.replace({ name: 'filelist', params: { view: 'files' } })
})
beforeEach(resetNavigation)
beforeEach(cleanup)
it('Check API entries rendering', async () => {
Navigation.register(createView('files', 'Files'))
const component = render(NavigationView, {
router,
global: {
plugins: [
createTestingPinia({
createSpy: vi.fn,
}),
],
},
})
// see the navigation
await expect(component.findByRole('navigation', { name: 'Files' })).resolves.not.toThrow()
// see the views
await expect(component.findByRole('list', { name: 'Views' })).resolves.not.toThrow()
// see the entry
await expect(component.findByRole('link', { name: 'Files' })).resolves.not.toThrow()
// see that the entry has all props
const entry = component.getByRole('link', { name: 'Files' })
expect(entry.getAttribute('href')).toMatch(/\/apps\/files\/files$/)
expect(entry.getAttribute('aria-current')).toBe('page')
expect(entry.getAttribute('title')).toBe('Files')
})
it('Adds a new entry and render', async () => {
Navigation.register(createView('files', 'Files'))
Navigation.register(createView('sharing', 'Sharing'))
const component = render(NavigationView, {
router,
global: {
plugins: [
createTestingPinia({
createSpy: vi.fn,
}),
],
},
})
const list = component.getByRole('list', { name: 'Views' })
expect(getAllByRole(list, 'listitem')).toHaveLength(2)
await expect(component.findByRole('link', { name: 'Files' })).resolves.not.toThrow()
await expect(component.findByRole('link', { name: 'Sharing' })).resolves.not.toThrow()
// see that the entry has all props
const entry = component.getByRole('link', { name: 'Sharing' })
expect(entry.getAttribute('href')).toMatch(/\/apps\/files\/sharing$/)
expect(entry.getAttribute('aria-current')).toBeNull()
expect(entry.getAttribute('title')).toBe('Sharing')
})
it('Adds a new children, render and open menu', async () => {
Navigation.register(createView('files', 'Files'))
Navigation.register(createView('sharing', 'Sharing'))
Navigation.register(createView('sharingin', 'Shared with me', 'sharing'))
const component = render(NavigationView, {
router,
global: {
plugins: [
createTestingPinia({
createSpy: vi.fn,
}),
],
},
})
const viewConfigStore = useViewConfigStore()
const list = component.getByRole('list', { name: 'Views' })
expect(getAllByRole(list, 'listitem')).toHaveLength(3)
// Toggle the sharing entry children
const entry = component.getByRole('link', { name: 'Sharing' })
expect(entry.getAttribute('aria-expanded')).toBe('false')
await fireEvent.click(component.getByRole('button', { name: 'Open menu' }))
expect(entry.getAttribute('aria-expanded')).toBe('true')
// Expect store update to be called
expect(viewConfigStore.update).toHaveBeenCalled()
expect(viewConfigStore.update).toHaveBeenCalledWith('sharing', 'expanded', true)
// Validate children
await expect(component.findByRole('link', { name: 'Shared with me' })).resolves.not.toThrow()
await fireEvent.click(component.getByRole('button', { name: 'Collapse menu' }))
// Expect store update to be called
expect(viewConfigStore.update).toHaveBeenCalledWith('sharing', 'expanded', false)
})
})
/**
* Remove the mocked initial state
*/
function removeInitialState(): void {
document.querySelectorAll('input[type="hidden"]').forEach((el) => {
el.remove()
})
// clear the cache
delete globalThis._nc_initial_state
}
/**
* Helper to mock an initial state value
* @param app - The app
* @param key - The key
* @param value - The value
*/
function mockInitialState(app: string, key: string, value: unknown): void {
const el = document.createElement('input')
el.value = btoa(JSON.stringify(value))
el.id = `initial-state-${app}-${key}`
el.type = 'hidden'
document.head.appendChild(el)
}
function resetNavigation() {
const nav = getNavigation()
;[...nav.views].forEach(({ id }) => nav.remove(id))
nav.setActive(null)
}
function createView(id: string, name: string, parent?: string) {
return new View({
id,
name,
getContents: async () => ({ folder: {} as Folder, contents: [] }),
icon: FolderSvg,
order: 1,
parent,
})
}
function mockWindow() {
window.OCP ??= {}
window.OCP.Files ??= {}
window.OCP.Files.Router = new RouterService(router)
}

View File

@@ -67,6 +67,7 @@ import path from 'path'
import { defineComponent } from 'vue'
import FileIcon from 'vue-material-design-icons/File.vue'
import FolderIcon from 'vue-material-design-icons/Folder.vue'
import { generateFileUrl } from '../../../files_sharing/src/utils/generateUrl.ts'
import logger from '../logger.ts'
// see lib/private/Collaboration/Reference/File/FileReferenceProvider.php
@@ -234,14 +235,12 @@ export default defineComponent({
.addButton({
id: 'open',
label: this.t('settings', 'Open in files'),
callback(nodes: Node[]) {
if (nodes[0]) {
window.open(generateUrl('/f/{fileid}', {
fileid: nodes[0].fileid,
}))
callback([node]: Node[]) {
if (node) {
window.open(generateFileUrl(node.fileid!))
}
},
type: 'primary',
variant: 'primary',
})
.disableNavigation()
.startAt(this.richObject.path)

View File

@@ -57,12 +57,13 @@ import type { FileStat, ResponseDataDetailed } from 'webdav'
import type { TemplateFile } from '../types.ts'
import { getCurrentUser } from '@nextcloud/auth'
import { showError, spawnDialog } from '@nextcloud/dialogs'
import { showError } from '@nextcloud/dialogs'
import { emit } from '@nextcloud/event-bus'
import { File } from '@nextcloud/files'
import { getClient, getDefaultPropfind, getRootPath, resultToNode } from '@nextcloud/files/dav'
import { translate as t } from '@nextcloud/l10n'
import { generateRemoteUrl } from '@nextcloud/router'
import { spawnDialog } from '@nextcloud/vue/functions/dialog'
import { extname, join, normalize } from 'path'
import { defineComponent } from 'vue'
import NcEmptyContent from '@nextcloud/vue/components/NcEmptyContent'

View File

@@ -103,6 +103,7 @@ OC.L10N.register(
"Enter missing credentials" : "angiv manglende legitimationsoplysninger",
"Credentials successfully set" : "Legitimationsoplysningerne er angivet",
"Error while setting credentials: {error}" : "Fejl under indstilling af legitimationsoplysninger: {error}",
"Checking storage …" : "Tjekker lagerplads …",
"There was an error with this external storage." : "Der er en fejl med dette eksterne lager.",
"We were unable to check the external storage {basename}" : "Det var ikke muligt at kontrollerer det eksterne lager {basename}",
"Examine this faulty external storage configuration" : "Gennemgå fejl konfiguration af eksternt lager ",

View File

@@ -101,6 +101,7 @@
"Enter missing credentials" : "angiv manglende legitimationsoplysninger",
"Credentials successfully set" : "Legitimationsoplysningerne er angivet",
"Error while setting credentials: {error}" : "Fejl under indstilling af legitimationsoplysninger: {error}",
"Checking storage …" : "Tjekker lagerplads …",
"There was an error with this external storage." : "Der er en fejl med dette eksterne lager.",
"We were unable to check the external storage {basename}" : "Det var ikke muligt at kontrollerer det eksterne lager {basename}",
"Examine this faulty external storage configuration" : "Gennemgå fejl konfiguration af eksternt lager ",

View File

@@ -56,6 +56,7 @@ OC.L10N.register(
"Enable SSL" : "SSL-i kasutamine",
"Enable Path Style" : "Luba otsingtee stiilis",
"Legacy (v2) authentication" : "Pärandvormis autentimine (v2)",
"Enable multipart copy" : "Luba mitmeosaline kopeerimine",
"SSE-C encryption key" : "SSE-C krüptimisvõti",
"WebDAV" : "WebDAV",
"URL" : "Võrguaadress",
@@ -98,6 +99,7 @@ OC.L10N.register(
"Enter missing credentials" : "Lisa puuduvad kasutajanimi/salasõna",
"Credentials successfully set" : "Kasutajanime/salasõna lisamine õnnestus",
"Error while setting credentials: {error}" : "Viga kasutajanime/salasõna lisamisel: {error}",
"Checking storage …" : "Kontrollin andmeruumi…",
"There was an error with this external storage." : "Selle välis andmeruumi kontekstis tekkis viga.",
"We were unable to check the external storage {basename}" : "Meil ei õnnestunud kontrollida välist andmeruumi „{basename}“",
"Examine this faulty external storage configuration" : "Kontrolli uuesti selle vigase välise andmeruumi seadistusi",

View File

@@ -54,6 +54,7 @@
"Enable SSL" : "SSL-i kasutamine",
"Enable Path Style" : "Luba otsingtee stiilis",
"Legacy (v2) authentication" : "Pärandvormis autentimine (v2)",
"Enable multipart copy" : "Luba mitmeosaline kopeerimine",
"SSE-C encryption key" : "SSE-C krüptimisvõti",
"WebDAV" : "WebDAV",
"URL" : "Võrguaadress",
@@ -96,6 +97,7 @@
"Enter missing credentials" : "Lisa puuduvad kasutajanimi/salasõna",
"Credentials successfully set" : "Kasutajanime/salasõna lisamine õnnestus",
"Error while setting credentials: {error}" : "Viga kasutajanime/salasõna lisamisel: {error}",
"Checking storage …" : "Kontrollin andmeruumi…",
"There was an error with this external storage." : "Selle välis andmeruumi kontekstis tekkis viga.",
"We were unable to check the external storage {basename}" : "Meil ei õnnestunud kontrollida välist andmeruumi „{basename}“",
"Examine this faulty external storage configuration" : "Kontrolli uuesti selle vigase välise andmeruumi seadistusi",

View File

@@ -9,11 +9,12 @@ import type { StorageConfig } from '../services/externalStorage.ts'
import LoginSvg from '@mdi/svg/svg/login.svg?raw'
import axios from '@nextcloud/axios'
import { showError, showSuccess, spawnDialog } from '@nextcloud/dialogs'
import { showError, showSuccess } from '@nextcloud/dialogs'
import { DefaultType, FileAction } from '@nextcloud/files'
import { translate as t } from '@nextcloud/l10n'
import { t } from '@nextcloud/l10n'
import { addPasswordConfirmationInterceptors, PwdConfirmationMode } from '@nextcloud/password-confirmation'
import { generateUrl } from '@nextcloud/router'
import { spawnDialog } from '@nextcloud/vue/functions/dialog'
import Vue, { defineAsyncComponent } from 'vue'
import { isMissingAuthConfig, STORAGE_STATUS } from '../utils/credentialsUtils.ts'
import { isNodeExternalStorage } from '../utils/externalStorageUtils.ts'

View File

@@ -80,8 +80,8 @@ export default defineComponent({
dialogButtons() {
return [{
label: t('files_external', 'Confirm'),
type: 'primary',
nativeType: 'submit',
type: 'submit',
variant: 'primary',
}]
},
},

View File

@@ -201,7 +201,7 @@ OC.L10N.register(
"Via “{folder}”" : "Via “{folder}”",
"Unshare" : "Fjern deling",
"Cannot copy, please copy the link manually" : "Kan ikke kopiere, kopier venligst linket manuelt",
"Copy internal link" : "Kopier internt link",
"Copy internal link" : "Kopiér internt link",
"For people who already have access" : "For personer der allerede har adgang",
"Internal link" : "Internt link",
"{shareWith} by {initiator}" : "{shareWith} af {initiator}",
@@ -237,6 +237,9 @@ OC.L10N.register(
"Can edit" : "Kan redigere",
"Custom permissions" : "Brugerdefinerede rettigheder",
"Resharing is not allowed" : "Gendeling er ikke tilladt",
"Name or email …" : "Navn eller e-mail …",
"Name, email, or Federated Cloud ID …" : "Navn, e-mail eller Fødereret Cloud ID …",
"Searching …" : "Søger ...",
"No elements found." : "Ingen elementer fundet.",
"Search everywhere" : "Søg overalt",
"Guest" : "Gæst",
@@ -406,7 +409,7 @@ OC.L10N.register(
"Copy internal link to clipboard" : "Kopier internt link til klippebord",
"Only works for people with access to this folder" : "Virker kun for personer med adgang til denne mappe",
"Only works for people with access to this file" : "Virker kun for personer med adgang til denne fil",
"Copy public link of \"{title}\" to clipboard" : "Kopier offentligt link af \"{title}\" til udklipsholder",
"Copy public link of \"{title}\" to clipboard" : "Kopiér offentligt link af \"{title}\" til udklipsholder",
"Name or email …" : "Navne eller e-mail ...",
"Name, email, or Federated Cloud ID …" : "Navn, e-mail, eller sammenkoblings cloud ID …",
"Searching …" : "Søger ...",

View File

@@ -199,7 +199,7 @@
"Via “{folder}”" : "Via “{folder}”",
"Unshare" : "Fjern deling",
"Cannot copy, please copy the link manually" : "Kan ikke kopiere, kopier venligst linket manuelt",
"Copy internal link" : "Kopier internt link",
"Copy internal link" : "Kopiér internt link",
"For people who already have access" : "For personer der allerede har adgang",
"Internal link" : "Internt link",
"{shareWith} by {initiator}" : "{shareWith} af {initiator}",
@@ -235,6 +235,9 @@
"Can edit" : "Kan redigere",
"Custom permissions" : "Brugerdefinerede rettigheder",
"Resharing is not allowed" : "Gendeling er ikke tilladt",
"Name or email …" : "Navn eller e-mail …",
"Name, email, or Federated Cloud ID …" : "Navn, e-mail eller Fødereret Cloud ID …",
"Searching …" : "Søger ...",
"No elements found." : "Ingen elementer fundet.",
"Search everywhere" : "Søg overalt",
"Guest" : "Gæst",
@@ -404,7 +407,7 @@
"Copy internal link to clipboard" : "Kopier internt link til klippebord",
"Only works for people with access to this folder" : "Virker kun for personer med adgang til denne mappe",
"Only works for people with access to this file" : "Virker kun for personer med adgang til denne fil",
"Copy public link of \"{title}\" to clipboard" : "Kopier offentligt link af \"{title}\" til udklipsholder",
"Copy public link of \"{title}\" to clipboard" : "Kopiér offentligt link af \"{title}\" til udklipsholder",
"Name or email …" : "Navne eller e-mail ...",
"Name, email, or Federated Cloud ID …" : "Navn, e-mail, eller sammenkoblings cloud ID …",
"Searching …" : "Søger ...",

View File

@@ -237,6 +237,8 @@ OC.L10N.register(
"Can edit" : "Võib muuta",
"Custom permissions" : "Kohandatud õigused",
"Resharing is not allowed" : "Edasijagamine pole lubatud",
"Name or email …" : "Nimi või e-posti aadress…",
"Name, email, or Federated Cloud ID …" : "Nimi, e-posti aadress või liitpilve kasutajatunnus…",
"Searching …" : "Otsin...",
"No elements found." : "Elemente ei leidu.",
"Search everywhere" : "Otsi kõikjalt",
@@ -304,6 +306,7 @@ OC.L10N.register(
"Link shares" : "Jaoslingid",
"Shares" : "Jagamisi",
"Share files within your organization. Recipients who can already view the file can also use this link for easy access." : "Jagamine oma organisatsiooni sees. Need, kes juba saavad faili nähe, võivad ka mugavaks ligipääsuks otselinki kasutada.",
"Share files with others outside your organization via public links and email addresses. You can also share to {productName} accounts on other instances using their federated cloud ID." : "Jaga faile avalike linkide või e-postiga erinevate osalejatega väljaspool oma organisatsiooni. Lisaks saad kasutades liitpilve kasutajatunnust jagada kasutajatele {productName}i serverites.",
"Shares from apps or other sources which are not included in internal or external shares." : "Jagamine rakendustest ja muudest allikatest, mis pole sisemise või välise jaosmeedia osa.",
"Type names, teams, federated cloud IDs" : "Sisesta kasutajanimi, tiimi nimi, kasutajatunnus liitpilves",
"Type names or teams" : "Sisesta kasutajanimi või tiimi nimi",

View File

@@ -235,6 +235,8 @@
"Can edit" : "Võib muuta",
"Custom permissions" : "Kohandatud õigused",
"Resharing is not allowed" : "Edasijagamine pole lubatud",
"Name or email …" : "Nimi või e-posti aadress…",
"Name, email, or Federated Cloud ID …" : "Nimi, e-posti aadress või liitpilve kasutajatunnus…",
"Searching …" : "Otsin...",
"No elements found." : "Elemente ei leidu.",
"Search everywhere" : "Otsi kõikjalt",
@@ -302,6 +304,7 @@
"Link shares" : "Jaoslingid",
"Shares" : "Jagamisi",
"Share files within your organization. Recipients who can already view the file can also use this link for easy access." : "Jagamine oma organisatsiooni sees. Need, kes juba saavad faili nähe, võivad ka mugavaks ligipääsuks otselinki kasutada.",
"Share files with others outside your organization via public links and email addresses. You can also share to {productName} accounts on other instances using their federated cloud ID." : "Jaga faile avalike linkide või e-postiga erinevate osalejatega väljaspool oma organisatsiooni. Lisaks saad kasutades liitpilve kasutajatunnust jagada kasutajatele {productName}i serverites.",
"Shares from apps or other sources which are not included in internal or external shares." : "Jagamine rakendustest ja muudest allikatest, mis pole sisemise või välise jaosmeedia osa.",
"Type names, teams, federated cloud IDs" : "Sisesta kasutajanimi, tiimi nimi, kasutajatunnus liitpilves",
"Type names or teams" : "Sisesta kasutajanimi või tiimi nimi",

View File

@@ -237,6 +237,8 @@ OC.L10N.register(
"Can edit" : "Може редагувати",
"Custom permissions" : "Спеціальні дозволи",
"Resharing is not allowed" : "Надання спільного доступу іншим не дозволяється",
"Name or email …" : "Ім'я або ел.пошта …",
"Name, email, or Federated Cloud ID …" : "Ім'я або ел.пошта або ID об'єднаної хмари …",
"Searching …" : "Шукаю...",
"No elements found." : "Елементи не знайдено.",
"Search everywhere" : "Шукати всюди",

View File

@@ -235,6 +235,8 @@
"Can edit" : "Може редагувати",
"Custom permissions" : "Спеціальні дозволи",
"Resharing is not allowed" : "Надання спільного доступу іншим не дозволяється",
"Name or email …" : "Ім'я або ел.пошта …",
"Name, email, or Federated Cloud ID …" : "Ім'я або ел.пошта або ID об'єднаної хмари …",
"Searching …" : "Шукаю...",
"No elements found." : "Елементи не знайдено.",
"Search everywhere" : "Шукати всюди",

View File

@@ -34,7 +34,6 @@
<script>
import { basename } from '@nextcloud/paths'
import { generateUrl } from '@nextcloud/router'
import NcActionButton from '@nextcloud/vue/components/NcActionButton'
import NcActionLink from '@nextcloud/vue/components/NcActionLink'
import NcActionText from '@nextcloud/vue/components/NcActionText'
@@ -42,6 +41,7 @@ import NcAvatar from '@nextcloud/vue/components/NcAvatar'
import SharingEntrySimple from '../components/SharingEntrySimple.vue'
import SharesMixin from '../mixins/SharesMixin.js'
import Share from '../models/Share.js'
import { generateFileUrl } from '../utils/generateUrl.js'
export default {
name: 'SharingEntryInherited',
@@ -65,9 +65,7 @@ export default {
computed: {
viaFileTargetUrl() {
return generateUrl('/f/{fileid}', {
fileid: this.share.viaFileid,
})
return generateFileUrl(this.share.viaFileid)
},
viaFolderName() {

View File

@@ -31,12 +31,12 @@
<script>
import { showSuccess } from '@nextcloud/dialogs'
import { generateUrl } from '@nextcloud/router'
import NcActionButton from '@nextcloud/vue/components/NcActionButton'
import CheckIcon from 'vue-material-design-icons/Check.vue'
import ClipboardIcon from 'vue-material-design-icons/ContentCopy.vue'
import SharingEntrySimple from './SharingEntrySimple.vue'
import logger from '../services/logger.ts'
import { generateFileUrl } from '../utils/generateUrl.ts'
export default {
name: 'SharingEntryInternal',
@@ -69,7 +69,7 @@ export default {
* @return {string}
*/
internalLink() {
return window.location.protocol + '//' + window.location.host + generateUrl('/f/') + this.fileInfo.id
return generateFileUrl(this.fileInfo.id)
},
/**

View File

@@ -192,16 +192,6 @@
:file-info="fileInfo"
:share="share" />
<!-- external legacy sharing via url (social...) -->
<NcActionLink
v-for="({ icon, url, name }, actionIndex) in externalLegacyLinkActions"
:key="actionIndex"
:href="url(shareLink)"
:icon="icon"
target="_blank">
{{ name }}
</NcActionLink>
<NcActionButton
v-if="!isEmailShareType && canReshare"
class="new-share-link"
@@ -268,7 +258,6 @@ import { toRaw } from 'vue'
import NcActionButton from '@nextcloud/vue/components/NcActionButton'
import NcActionCheckbox from '@nextcloud/vue/components/NcActionCheckbox'
import NcActionInput from '@nextcloud/vue/components/NcActionInput'
import NcActionLink from '@nextcloud/vue/components/NcActionLink'
import NcActions from '@nextcloud/vue/components/NcActions'
import NcActionSeparator from '@nextcloud/vue/components/NcActionSeparator'
import NcActionText from '@nextcloud/vue/components/NcActionText'
@@ -301,7 +290,6 @@ export default {
NcActionButton,
NcActionCheckbox,
NcActionInput,
NcActionLink,
NcActionText,
NcActionSeparator,
NcAvatar,
@@ -352,7 +340,6 @@ export default {
// Are we waiting for password/expiration date
pending: false,
ExternalLegacyLinkActions: OCA.Sharing.ExternalLinkActions.state,
ExternalShareActions: OCA.Sharing.ExternalShareActions.state,
externalShareActions: getSidebarInlineActions(),
@@ -593,16 +580,6 @@ export default {
return t('files_sharing', 'Copy public link of "{title}"', { title: this.title })
},
/**
* External additionnai actions for the menu
*
* @deprecated use OCA.Sharing.ExternalShareActions
* @return {Array}
*/
externalLegacyLinkActions() {
return this.ExternalLegacyLinkActions.actions
},
/**
* Additional actions for the menu
*

View File

@@ -6,9 +6,9 @@
import type { Folder, NewMenuEntry, Node } from '@nextcloud/files'
import FileUploadSvg from '@mdi/svg/svg/file-upload-outline.svg?raw'
import { spawnDialog } from '@nextcloud/dialogs'
import { t } from '@nextcloud/l10n'
import { isPublicShare } from '@nextcloud/sharing/public'
import { spawnDialog } from '@nextcloud/vue/functions/dialog'
import { defineAsyncComponent } from 'vue'
import Config from '../services/ConfigService.ts'

View File

@@ -7,7 +7,6 @@ import ShareVariant from '@mdi/svg/svg/share-variant.svg?raw'
import { getCSPNonce } from '@nextcloud/auth'
import { n, t } from '@nextcloud/l10n'
import Vue from 'vue'
import ExternalLinkActions from './services/ExternalLinkActions.js'
import ExternalShareActions from './services/ExternalShareActions.js'
import ShareSearch from './services/ShareSearch.js'
import TabSections from './services/TabSections.js'
@@ -19,7 +18,6 @@ if (!window.OCA.Sharing) {
window.OCA.Sharing = {}
}
Object.assign(window.OCA.Sharing, { ShareSearch: new ShareSearch() })
Object.assign(window.OCA.Sharing, { ExternalLinkActions: new ExternalLinkActions() })
Object.assign(window.OCA.Sharing, { ExternalShareActions: new ExternalShareActions() })
Object.assign(window.OCA.Sharing, { ShareTabSections: new TabSections() })

View File

@@ -1,48 +0,0 @@
/**
* SPDX-FileCopyrightText: 2019 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
import logger from './logger.ts'
export default class ExternalLinkActions {
_state
constructor() {
// init empty state
this._state = {}
// init default values
this._state.actions = []
logger.debug('OCA.Sharing.ExternalLinkActions initialized')
}
/**
* Get the state
*
* @readonly
* @memberof ExternalLinkActions
* @return {object} the data state
*/
get state() {
return this._state
}
/**
* Register a new action for the link share
* Mostly used by the social sharing app.
*
* @param {object} action new action component to register
* @return {boolean}
*/
registerAction(action) {
logger.warn('OCA.Sharing.ExternalLinkActions is deprecated, use `registerSidebarAction` from `@nextcloud/sharing` instead')
if (typeof action === 'object' && action.icon && action.name && action.url) {
this._state.actions.push(action)
return true
}
logger.error('Invalid action provided', action)
return false
}
}

View File

@@ -0,0 +1,30 @@
/**
* SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
import { describe, expect, it, vi } from 'vitest'
import { generateFileUrl } from './generateUrl.ts'
const getCapabilities = vi.hoisted(() => vi.fn())
vi.mock('@nextcloud/capabilities', () => ({ getCapabilities }))
describe('generateFileUrl', () => {
it('should work without globalscale', () => {
getCapabilities.mockReturnValue({ globalscale: null })
const url = generateFileUrl(12345)
expect(url).toBe('http://nextcloud.local/index.php/f/12345')
})
it('should work with older globalscale', () => {
getCapabilities.mockReturnValue({ globalscale: { enabled: true } })
const url = generateFileUrl(12345)
expect(url).toBe('http://nextcloud.local/index.php/f/12345')
})
it('should work with globalscale', () => {
getCapabilities.mockReturnValue({ globalscale: { enabled: true, token: 'abc123' } })
const url = generateFileUrl(12345)
expect(url).toBe('http://nextcloud.local/index.php/gf/abc123/12345')
})
})

View File

@@ -0,0 +1,32 @@
/**
* SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
import { getCapabilities } from '@nextcloud/capabilities'
import { generateUrl } from '@nextcloud/router'
interface IGlobalScaleCapabilities {
token?: string
}
/**
* @param fileid - The file ID to generate the direct file link for
*/
export function generateFileUrl(fileid: number): string {
const baseURL = window.location.protocol + '//' + window.location.host
const { globalscale } = getCapabilities() as { globalscale?: IGlobalScaleCapabilities }
if (globalscale?.token) {
return generateUrl('/gf/{token}/{fileid}', {
token: globalscale.token,
fileid,
}, { baseURL })
}
return generateUrl('/f/{fileid}', {
fileid,
}, {
baseURL,
})
}

View File

@@ -1179,6 +1179,7 @@ export default {
return resultingShare
} catch (error) {
logger.error('Error while adding new share', { error })
throw error
} finally {
// this.loading = false // No loader here yet
}

View File

@@ -2,12 +2,10 @@
* SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
import type { Folder, Node, View } from '@nextcloud/files'
import {
DialogSeverity,
getDialogBuilder,
} from '@nextcloud/dialogs'
import { getDialogBuilder } from '@nextcloud/dialogs'
import { emit } from '@nextcloud/event-bus'
import { FileListAction } from '@nextcloud/files'
import { loadState } from '@nextcloud/initial-state'
@@ -41,18 +39,18 @@ export const emptyTrashAction = new FileListAction({
async exec(view: View, nodes: Node[]): Promise<null> {
const askConfirmation = new Promise<boolean>((resolve) => {
const dialog = getDialogBuilder(t('files_trashbin', 'Confirm permanent deletion'))
.setSeverity(DialogSeverity.Warning)
.setSeverity('warning')
// TODO Add note for groupfolders
.setText(t('files_trashbin', 'Are you sure you want to permanently delete all files and folders in the trash? This cannot be undone.'))
.setButtons([
{
label: t('files_trashbin', 'Cancel'),
type: 'secondary',
variant: 'secondary',
callback: () => resolve(false),
},
{
label: t('files_trashbin', 'Empty deleted files'),
type: 'error',
variant: 'error',
callback: () => resolve(true),
},
])

View File

@@ -71,8 +71,8 @@ export default defineComponent({
// If there is already a label set, offer to remove the version label
buttons.push({
label: t('files_versions', 'Remove version name'),
type: 'error',
nativeType: 'reset',
type: 'reset',
variant: 'error',
callback: () => { this.setVersionLabel('') },
})
}
@@ -80,9 +80,9 @@ export default defineComponent({
...buttons,
{
label: t('files_versions', 'Save version name'),
type: 'primary',
nativeType: 'submit',
icon: svgCheck,
type: 'submit',
variant: 'primary',
},
]
},

View File

@@ -30,6 +30,7 @@ OC.L10N.register(
"User is not a sub-admin of this group" : "Brugeren er ikke underadministrator for denne gruppe",
"Email address not available" : "E-mailadresse ikke tilgængelig",
"Sending email failed" : "Det lykkedes ikke at sende e-mailen",
"Logged in account is not mail address owner" : "Den indloggede konto er ikke ejeren af e-mailadressen",
"Email confirmation" : "E-mailbekræftelse",
"To enable the email address %s please click the button below." : "For at aktivere e-mailadressen %s, klik venligst på knappen nedenfor.",
"Confirm" : "Bekræft",

View File

@@ -28,6 +28,7 @@
"User is not a sub-admin of this group" : "Brugeren er ikke underadministrator for denne gruppe",
"Email address not available" : "E-mailadresse ikke tilgængelig",
"Sending email failed" : "Det lykkedes ikke at sende e-mailen",
"Logged in account is not mail address owner" : "Den indloggede konto er ikke ejeren af e-mailadressen",
"Email confirmation" : "E-mailbekræftelse",
"To enable the email address %s please click the button below." : "For at aktivere e-mailadressen %s, klik venligst på knappen nedenfor.",
"Confirm" : "Bekræft",

View File

@@ -135,6 +135,7 @@ return array(
'OCA\\Settings\\SetupChecks\\SupportedDatabase' => $baseDir . '/../lib/SetupChecks/SupportedDatabase.php',
'OCA\\Settings\\SetupChecks\\SystemIs64bit' => $baseDir . '/../lib/SetupChecks/SystemIs64bit.php',
'OCA\\Settings\\SetupChecks\\TaskProcessingPickupSpeed' => $baseDir . '/../lib/SetupChecks/TaskProcessingPickupSpeed.php',
'OCA\\Settings\\SetupChecks\\TaskProcessingSuccessRate' => $baseDir . '/../lib/SetupChecks/TaskProcessingSuccessRate.php',
'OCA\\Settings\\SetupChecks\\TempSpaceAvailable' => $baseDir . '/../lib/SetupChecks/TempSpaceAvailable.php',
'OCA\\Settings\\SetupChecks\\TransactionIsolation' => $baseDir . '/../lib/SetupChecks/TransactionIsolation.php',
'OCA\\Settings\\SetupChecks\\WellKnownUrls' => $baseDir . '/../lib/SetupChecks/WellKnownUrls.php',

View File

@@ -150,6 +150,7 @@ class ComposerStaticInitSettings
'OCA\\Settings\\SetupChecks\\SupportedDatabase' => __DIR__ . '/..' . '/../lib/SetupChecks/SupportedDatabase.php',
'OCA\\Settings\\SetupChecks\\SystemIs64bit' => __DIR__ . '/..' . '/../lib/SetupChecks/SystemIs64bit.php',
'OCA\\Settings\\SetupChecks\\TaskProcessingPickupSpeed' => __DIR__ . '/..' . '/../lib/SetupChecks/TaskProcessingPickupSpeed.php',
'OCA\\Settings\\SetupChecks\\TaskProcessingSuccessRate' => __DIR__ . '/..' . '/../lib/SetupChecks/TaskProcessingSuccessRate.php',
'OCA\\Settings\\SetupChecks\\TempSpaceAvailable' => __DIR__ . '/..' . '/../lib/SetupChecks/TempSpaceAvailable.php',
'OCA\\Settings\\SetupChecks\\TransactionIsolation' => __DIR__ . '/..' . '/../lib/SetupChecks/TransactionIsolation.php',
'OCA\\Settings\\SetupChecks\\WellKnownUrls' => __DIR__ . '/..' . '/../lib/SetupChecks/WellKnownUrls.php',

View File

@@ -875,9 +875,6 @@ OC.L10N.register(
"If you use third party applications to connect to Nextcloud, please make sure to create and configure an app password for each before enabling second factor authentication." : "إذا كنت تستخدم تطبيقات من طرفٍ ثالثٍ للاتصال بنكست كلاود، فالرجاء التأكد من إنشاء و تهيئة كلمة مرور التطبيق لكل منها قبل تمكين التحقق ثنائي العوامل من الهويّة 2FA.",
"Logged in account must be a subadmin" : "يجب أن يكون الحساب الذي تم تسجيل الدخول إليه مديراً فرعياً",
"- The `%1$s` HTTP header does not contain `%2$s`. This is a potential security or privacy risk, as it is recommended to adjust this setting accordingly." : "- ترويسة الـ HTTP ـ `%1$s` لا تحتوي على `%2$s`. يمكن أن يٌشكِّل هذا تهديداً محتملاً للأمن و الخصوصية بسبب عدم ضبط هذا الإعداد كما يجب.",
"If autocompletion \"same group\" and \"phone number integration\" are enabled a match in either is enough to show the user." : "إذا تمّ تمكين الإكمال التلقائي على أساس \"نفس المجموعة\" و \"تكامل رقم الهاتف\" ، فسيكون تمكين أي خيار منهما كافي لإظهار المستخدم.",
"Restrict account name autocompletion to users based on phone number integration" : "تقييد الإكمال التلقائي لاسم الحساب على المستخدمين بناءً على تكامل رقم الهاتف",
"Allow autocompletion when entering the full name or email address (ignoring missing phonebook match and being in the same group)" : "السماح بالإكمال التلقائي عند إدخال الاسم الكامل أو عنوان البريد الإلكتروني ( أي تجاهل شرط تطابق دفتر الهاتف و شرط الوجود في نفس المجموعة)",
"This app has no minimum Nextcloud version assigned. This will be an error in the future." : "هذا التطبيق لم يُحدّد فيه أقدم إصدار متوافق معه من نكست كلاود. هذا قد يسبب خطأ في المستقبل.",
"This app has no maximum Nextcloud version assigned. This will be an error in the future." : " لم يتم تعيين الحد الأقصى لهذا التطبيق لإصدار نكست كلاود. وهذا سيكون خطأ في المستقبل.",
"Loading accounts …" : "تحميل الحسابات ...",

View File

@@ -873,9 +873,6 @@
"If you use third party applications to connect to Nextcloud, please make sure to create and configure an app password for each before enabling second factor authentication." : "إذا كنت تستخدم تطبيقات من طرفٍ ثالثٍ للاتصال بنكست كلاود، فالرجاء التأكد من إنشاء و تهيئة كلمة مرور التطبيق لكل منها قبل تمكين التحقق ثنائي العوامل من الهويّة 2FA.",
"Logged in account must be a subadmin" : "يجب أن يكون الحساب الذي تم تسجيل الدخول إليه مديراً فرعياً",
"- The `%1$s` HTTP header does not contain `%2$s`. This is a potential security or privacy risk, as it is recommended to adjust this setting accordingly." : "- ترويسة الـ HTTP ـ `%1$s` لا تحتوي على `%2$s`. يمكن أن يٌشكِّل هذا تهديداً محتملاً للأمن و الخصوصية بسبب عدم ضبط هذا الإعداد كما يجب.",
"If autocompletion \"same group\" and \"phone number integration\" are enabled a match in either is enough to show the user." : "إذا تمّ تمكين الإكمال التلقائي على أساس \"نفس المجموعة\" و \"تكامل رقم الهاتف\" ، فسيكون تمكين أي خيار منهما كافي لإظهار المستخدم.",
"Restrict account name autocompletion to users based on phone number integration" : "تقييد الإكمال التلقائي لاسم الحساب على المستخدمين بناءً على تكامل رقم الهاتف",
"Allow autocompletion when entering the full name or email address (ignoring missing phonebook match and being in the same group)" : "السماح بالإكمال التلقائي عند إدخال الاسم الكامل أو عنوان البريد الإلكتروني ( أي تجاهل شرط تطابق دفتر الهاتف و شرط الوجود في نفس المجموعة)",
"This app has no minimum Nextcloud version assigned. This will be an error in the future." : "هذا التطبيق لم يُحدّد فيه أقدم إصدار متوافق معه من نكست كلاود. هذا قد يسبب خطأ في المستقبل.",
"This app has no maximum Nextcloud version assigned. This will be an error in the future." : " لم يتم تعيين الحد الأقصى لهذا التطبيق لإصدار نكست كلاود. وهذا سيكون خطأ في المستقبل.",
"Loading accounts …" : "تحميل الحسابات ...",

View File

@@ -85,6 +85,7 @@ OC.L10N.register(
"Unknown database platform" : "Невядомая платформа базы даных",
"Architecture" : "Архітэктура",
"64-bit" : "64-бітная",
"_No scheduled tasks in the last day._::_No scheduled tasks in the last %n days._" : ["Няма запланаваных заданняў за апошні дзень.","Няма запланаваных заданняў за апошнія %n дні.","Няма запланаваных заданняў за апошніх %n дзён.","Няма запланаваных заданняў за апошніх %n дзён."],
"Your database does not run with \"READ COMMITTED\" transaction isolation level. This can cause problems when multiple actions are executed in parallel." : "Ваша база даных не працуе з узроўнем ізаляцыі транзакцый \"READ COMMITTED\". Гэта можа выклікаць праблемы пры паралельным выкананні некалькіх дзеянняў.",
"Font file loading" : "Загрузка файла шрыфту",
"Profile information" : "Звесткі профілю",
@@ -109,6 +110,7 @@ OC.L10N.register(
"Allow apps to use the Share API" : "Дазволіць праграмам выкарыстоўваць API абагульвання",
"Allow users to share via link and emails" : "Дазволіць карыстальнікам абагульваць праз спасылку і электронную пошту",
"Allow public uploads" : "Дазволіць публічныя запампоўванні",
"Allow public shares to be added to other clouds by federation." : "Дазволіць абагульваць рэсурсы ў іншыя воблакі праз федэрацыю.",
"Always ask for a password" : "Заўсёды пытацца пароль",
"Exclude groups from password requirements" : "Выключыць групы з патрабаванняў да пароляў",
"Exclude groups from creating link shares" : "Выключыць групы з магчымасці стварэння абагуленых спасылак",
@@ -162,6 +164,7 @@ OC.L10N.register(
"All" : "Усе",
"No results" : "Няма вынікаў",
"Update to {version}" : "Абнавіць да {version}",
"Delete data on remove" : "Ачысціць даныя пры выдаленні",
"This app cannot be installed because the following dependencies are not fulfilled:" : "Гэта праграма не можа быць усталявана, бо не выкананы наступныя залежнасці:",
"Latest updated" : "Апошняе абнаўленне",
"Author" : "Аўтар",

View File

@@ -83,6 +83,7 @@
"Unknown database platform" : "Невядомая платформа базы даных",
"Architecture" : "Архітэктура",
"64-bit" : "64-бітная",
"_No scheduled tasks in the last day._::_No scheduled tasks in the last %n days._" : ["Няма запланаваных заданняў за апошні дзень.","Няма запланаваных заданняў за апошнія %n дні.","Няма запланаваных заданняў за апошніх %n дзён.","Няма запланаваных заданняў за апошніх %n дзён."],
"Your database does not run with \"READ COMMITTED\" transaction isolation level. This can cause problems when multiple actions are executed in parallel." : "Ваша база даных не працуе з узроўнем ізаляцыі транзакцый \"READ COMMITTED\". Гэта можа выклікаць праблемы пры паралельным выкананні некалькіх дзеянняў.",
"Font file loading" : "Загрузка файла шрыфту",
"Profile information" : "Звесткі профілю",
@@ -107,6 +108,7 @@
"Allow apps to use the Share API" : "Дазволіць праграмам выкарыстоўваць API абагульвання",
"Allow users to share via link and emails" : "Дазволіць карыстальнікам абагульваць праз спасылку і электронную пошту",
"Allow public uploads" : "Дазволіць публічныя запампоўванні",
"Allow public shares to be added to other clouds by federation." : "Дазволіць абагульваць рэсурсы ў іншыя воблакі праз федэрацыю.",
"Always ask for a password" : "Заўсёды пытацца пароль",
"Exclude groups from password requirements" : "Выключыць групы з патрабаванняў да пароляў",
"Exclude groups from creating link shares" : "Выключыць групы з магчымасці стварэння абагуленых спасылак",
@@ -160,6 +162,7 @@
"All" : "Усе",
"No results" : "Няма вынікаў",
"Update to {version}" : "Абнавіць да {version}",
"Delete data on remove" : "Ачысціць даныя пры выдаленні",
"This app cannot be installed because the following dependencies are not fulfilled:" : "Гэта праграма не можа быць усталявана, бо не выкананы наступныя залежнасці:",
"Latest updated" : "Апошняе абнаўленне",
"Author" : "Аўтар",

View File

@@ -461,8 +461,6 @@ OC.L10N.register(
"This community release of Nextcloud is unsupported and instant notifications are unavailable." : "Тази общностна версия на Nextcloud не се поддържа и не са налични незабавни известия.",
"Use a second factor besides your password to increase security for your account." : "Ползвайте двустепенно удостоверяване за да повишите сигурността на профила си.",
"If you use third party applications to connect to Nextcloud, please make sure to create and configure an app password for each before enabling second factor authentication." : "Ако използвате приложения на трети страни, за да се свържете с Nextcloud, моля, не забравяйте да създадете и конфигурирате парола за приложение за всяко едно от тях, преди да активирате удостоверяване на втория фактор.",
"If autocompletion \"same group\" and \"phone number integration\" are enabled a match in either is enough to show the user." : "Ако автоматичното довършване „същата група“ и „интегриране на телефонен номер“ са активирани, съвпадението в едното е достатъчно, за да се покаже на потребителя.",
"Allow autocompletion when entering the full name or email address (ignoring missing phonebook match and being in the same group)" : "Разрешаване на автоматично довършване при въвеждане на пълното име или имейл адрес (като игнорирате липсващото съвпадение в телефонния указател и сте в същата група)",
"This app has no minimum Nextcloud version assigned. This will be an error in the future." : "Това приложение няма присвоена минимална версия на Nextcloud. В бъдеще това ще бъде грешка.",
"This app has no maximum Nextcloud version assigned. This will be an error in the future." : "Това приложение няма зададена максимална версия на Nextcloud. В бъдеще това ще бъде грешка.",
"In case of lost device or exiting the organization, this can remotely wipe the Nextcloud data from all devices associated with {userid}. Only works if the devices are connected to the internet." : "В случай на изгубено устройство или излизане от организацията, това може отдалечено да изтрие данните на Nextcloud от всички устройства, свързани с {userid}. Работи, само ако устройствата са свързани към интернет.",

View File

@@ -459,8 +459,6 @@
"This community release of Nextcloud is unsupported and instant notifications are unavailable." : "Тази общностна версия на Nextcloud не се поддържа и не са налични незабавни известия.",
"Use a second factor besides your password to increase security for your account." : "Ползвайте двустепенно удостоверяване за да повишите сигурността на профила си.",
"If you use third party applications to connect to Nextcloud, please make sure to create and configure an app password for each before enabling second factor authentication." : "Ако използвате приложения на трети страни, за да се свържете с Nextcloud, моля, не забравяйте да създадете и конфигурирате парола за приложение за всяко едно от тях, преди да активирате удостоверяване на втория фактор.",
"If autocompletion \"same group\" and \"phone number integration\" are enabled a match in either is enough to show the user." : "Ако автоматичното довършване „същата група“ и „интегриране на телефонен номер“ са активирани, съвпадението в едното е достатъчно, за да се покаже на потребителя.",
"Allow autocompletion when entering the full name or email address (ignoring missing phonebook match and being in the same group)" : "Разрешаване на автоматично довършване при въвеждане на пълното име или имейл адрес (като игнорирате липсващото съвпадение в телефонния указател и сте в същата група)",
"This app has no minimum Nextcloud version assigned. This will be an error in the future." : "Това приложение няма присвоена минимална версия на Nextcloud. В бъдеще това ще бъде грешка.",
"This app has no maximum Nextcloud version assigned. This will be an error in the future." : "Това приложение няма зададена максимална версия на Nextcloud. В бъдеще това ще бъде грешка.",
"In case of lost device or exiting the organization, this can remotely wipe the Nextcloud data from all devices associated with {userid}. Only works if the devices are connected to the internet." : "В случай на изгубено устройство или излизане от организацията, това може отдалечено да изтрие данните на Nextcloud от всички устройства, свързани с {userid}. Работи, само ако устройствата са свързани към интернет.",

View File

@@ -866,9 +866,6 @@ OC.L10N.register(
"If you use third party applications to connect to Nextcloud, please make sure to create and configure an app password for each before enabling second factor authentication." : "Si utilitzeu aplicacions de tercers per a connectar-vos a Nextcloud, assegureu-vos de crear i configurar una contrasenya d'aplicació per a cadascuna abans d'habilitar l'autenticació de segon factor.",
"Logged in account must be a subadmin" : "El compte iniciat ha de ser un subadministrador",
"- The `%1$s` HTTP header does not contain `%2$s`. This is a potential security or privacy risk, as it is recommended to adjust this setting accordingly." : "- La capçalera HTTP `%1$s` no conté `%2$s`. Aquest és un risc potencial de seguretat o privadesa, ja que es recomana ajustar aquesta configuració en conseqüència.",
"If autocompletion \"same group\" and \"phone number integration\" are enabled a match in either is enough to show the user." : "Si la compleció automàtica \"mateix grup\" i \"integració de números de telèfon\" estan habilitats, n'hi ha prou amb una coincidència per mostrar a l'usuari.",
"Restrict account name autocompletion to users based on phone number integration" : "Restringeix l'emplenament automàtic del nom del compte als usuaris en funció de la integració del número de telèfon",
"Allow autocompletion when entering the full name or email address (ignoring missing phonebook match and being in the same group)" : "Permet l'emplenament automàtic en introduir el nom complet o l'adreça de correu electrònic (ignorant la coincidència de l'agenda i estar al mateix grup)",
"This app has no minimum Nextcloud version assigned. This will be an error in the future." : "Aquesta aplicació no té cap versió mínima de Nextcloud assignada. Això serà un error en el futur.",
"This app has no maximum Nextcloud version assigned. This will be an error in the future." : "Aquesta aplicació no té cap versió màxima de Nextcloud assignada. Això serà un error en el futur.",
"Loading accounts …" : "S'estan carregant els comptes …",

View File

@@ -864,9 +864,6 @@
"If you use third party applications to connect to Nextcloud, please make sure to create and configure an app password for each before enabling second factor authentication." : "Si utilitzeu aplicacions de tercers per a connectar-vos a Nextcloud, assegureu-vos de crear i configurar una contrasenya d'aplicació per a cadascuna abans d'habilitar l'autenticació de segon factor.",
"Logged in account must be a subadmin" : "El compte iniciat ha de ser un subadministrador",
"- The `%1$s` HTTP header does not contain `%2$s`. This is a potential security or privacy risk, as it is recommended to adjust this setting accordingly." : "- La capçalera HTTP `%1$s` no conté `%2$s`. Aquest és un risc potencial de seguretat o privadesa, ja que es recomana ajustar aquesta configuració en conseqüència.",
"If autocompletion \"same group\" and \"phone number integration\" are enabled a match in either is enough to show the user." : "Si la compleció automàtica \"mateix grup\" i \"integració de números de telèfon\" estan habilitats, n'hi ha prou amb una coincidència per mostrar a l'usuari.",
"Restrict account name autocompletion to users based on phone number integration" : "Restringeix l'emplenament automàtic del nom del compte als usuaris en funció de la integració del número de telèfon",
"Allow autocompletion when entering the full name or email address (ignoring missing phonebook match and being in the same group)" : "Permet l'emplenament automàtic en introduir el nom complet o l'adreça de correu electrònic (ignorant la coincidència de l'agenda i estar al mateix grup)",
"This app has no minimum Nextcloud version assigned. This will be an error in the future." : "Aquesta aplicació no té cap versió mínima de Nextcloud assignada. Això serà un error en el futur.",
"This app has no maximum Nextcloud version assigned. This will be an error in the future." : "Aquesta aplicació no té cap versió màxima de Nextcloud assignada. Això serà un error en el futur.",
"Loading accounts …" : "S'estan carregant els comptes …",

View File

@@ -312,9 +312,6 @@ OC.L10N.register(
"64-bit" : "64bit",
"It seems like you are running a 32-bit PHP version. Nextcloud needs 64-bit to run well. Please upgrade your OS and PHP to 64-bit!" : "Zdá se, že provozujete 32bitovou verzi PHP. Aby správně fungoval, potřebuje Nextcloud 64bit. Přejděte na 64bit instalaci operačního systému a PHP!",
"Task Processing pickup speed" : "Rychlost vyzvedávání zpracovávání úkolů",
"_No scheduled tasks in the last %n hour._::_No scheduled tasks in the last %n hours._" : ["Žádné naplánované úkoly v uplynulé %n hodině.","Žádné naplánované úkoly v uplynulých %n hodinách.","Žádné naplánované úkoly v uplynulých %n hodinách.","Žádné naplánované úkoly v uplynulých %n hodinách."],
"_The task pickup speed has been ok in the last %n hour._::_The task pickup speed has been ok in the last %n hours._" : ["Rychlost vyzvedávání úkolů byla ok za uplynulou %n hodinu.","Rychlost vyzvedávání úkolů byla ok za uplynulých %n hodin.","Rychlost vyzvedávání úkolů byla ok za uplynulých %n hodin.","Rychlost vyzvedávání úkolů byla ok za uplynulých %n hodin."],
"_The task pickup speed has been slow in the last %n hour. Many tasks took longer than 4 minutes to be picked up. Consider setting up a worker to process tasks in the background._::_The task pickup speed has been slow in the last %n hours. Many tasks took longer than 4 minutes to be picked up. Consider setting up a worker to process tasks in the background._" : ["Rychlost vyzvedávání byla nízká za uplynulou %n hodinu. U mnoha úkolů trvalo více než 4 minuty, než byly vyzvednuty. Zvažte nastavení zpracovávajícího procesu na pozadí.","Rychlost vyzvedávání byla nízká za uplynulé %n hodiny. U mnoha úkolů trvalo více než 4 minuty, než byly vyzvednuty. Zvažte nastavení zpracovávajícího procesu na pozadí.","Rychlost vyzvedávání byla nízká za uplynulých %n hodin. U mnoha úkolů trvalo více než 4 minuty, než byly vyzvednuty. Zvažte nastavení zpracovávajícího procesu na pozadí.","Rychlost vyzvedávání byla nízká za uplynulé %n hodiny. U mnoha úkolů trvalo více než 4 minuty, než byly vyzvednuty. Zvažte nastavení zpracovávajícího procesu na pozadí."],
"Temporary space available" : "Dočasný prostor k dispozici",
"Error while checking the temporary PHP path - it was not properly set to a directory. Returned value: %s" : "Chyba při kontrole popisu umístění dočasných souborů PHP nebylo správně nastaveno na složku. Vrácená hodnota: %s",
"The PHP function \"disk_free_space\" is disabled, which prevents the check for enough space in the temporary directories." : "PHP funkce „disk_free_space“ je vypnutá, což brání v kontrolách zda je k dispozici dostatek místa ve složkách pro dočasná data.",
@@ -932,9 +929,9 @@ OC.L10N.register(
"If you use third party applications to connect to Nextcloud, please make sure to create and configure an app password for each before enabling second factor authentication." : "Pokud pro připojování se k Nextcloud používáte aplikace třetích stran, nezapomeňte před zapnutím ověřování druhým faktorem vytvořit pro jednotlivé aplikace jejich hesla.",
"Logged in account must be a subadmin" : "Je třeba, aby přihlášený účet byl dílčím správcem",
"- The `%1$s` HTTP header does not contain `%2$s`. This is a potential security or privacy risk, as it is recommended to adjust this setting accordingly." : "- HTTP hlavička `%1$s` neobsahuje `%2$s`. To značí možné ohrožení bezpečnosti a soukromí a je doporučeno toto nastavení upravit.",
"If autocompletion \"same group\" and \"phone number integration\" are enabled a match in either is enough to show the user." : "V případě, že jsou zapnuté automatická dokončování „stejná skupina“ a „začlenění telefonním číslem“, postačí pro zobrazení uživatele shoda s jedním z toho.",
"Restrict account name autocompletion to users based on phone number integration" : "Omezit doplňování názvu účtu uživatelům na základě začlenění telefonním číslem",
"Allow autocompletion when entering the full name or email address (ignoring missing phonebook match and being in the same group)" : "Povolit automatické dokončování při zadávání celého jména nebo e-mailové adresy (při ignorování chybějící shody s telefonním seznamem a toho, že je ve stejné skupině)",
"_No scheduled tasks in the last %n hour._::_No scheduled tasks in the last %n hours._" : ["Žádné naplánované úkoly v uplynulé %n hodině.","Žádné naplánované úkoly v uplynulých %n hodinách.","Žádné naplánované úkoly v uplynulých %n hodinách.","Žádné naplánované úkoly v uplynulých %n hodinách."],
"_The task pickup speed has been ok in the last %n hour._::_The task pickup speed has been ok in the last %n hours._" : ["Rychlost vyzvedávání úkolů byla ok za uplynulou %n hodinu.","Rychlost vyzvedávání úkolů byla ok za uplynulých %n hodin.","Rychlost vyzvedávání úkolů byla ok za uplynulých %n hodin.","Rychlost vyzvedávání úkolů byla ok za uplynulých %n hodin."],
"_The task pickup speed has been slow in the last %n hour. Many tasks took longer than 4 minutes to be picked up. Consider setting up a worker to process tasks in the background._::_The task pickup speed has been slow in the last %n hours. Many tasks took longer than 4 minutes to be picked up. Consider setting up a worker to process tasks in the background._" : ["Rychlost vyzvedávání byla nízká za uplynulou %n hodinu. U mnoha úkolů trvalo více než 4 minuty, než byly vyzvednuty. Zvažte nastavení zpracovávajícího procesu na pozadí.","Rychlost vyzvedávání byla nízká za uplynulé %n hodiny. U mnoha úkolů trvalo více než 4 minuty, než byly vyzvednuty. Zvažte nastavení zpracovávajícího procesu na pozadí.","Rychlost vyzvedávání byla nízká za uplynulých %n hodin. U mnoha úkolů trvalo více než 4 minuty, než byly vyzvednuty. Zvažte nastavení zpracovávajícího procesu na pozadí.","Rychlost vyzvedávání byla nízká za uplynulé %n hodiny. U mnoha úkolů trvalo více než 4 minuty, než byly vyzvednuty. Zvažte nastavení zpracovávajícího procesu na pozadí."],
"This app has no minimum Nextcloud version assigned. This will be an error in the future." : "Tato aplikace nemá nastavený žádný požadavek na minimální verzi Nextcloud. To v budoucnu bude hodnoceno jako chyba.",
"This app has no maximum Nextcloud version assigned. This will be an error in the future." : "Tato aplikace nemá nastavenou žádnou nejvyšší podporovanou verzi Nextcloud. To v budoucnu bude hodnoceno jako chyba.",
"Loading accounts …" : "Načítání účtů…",

View File

@@ -310,9 +310,6 @@
"64-bit" : "64bit",
"It seems like you are running a 32-bit PHP version. Nextcloud needs 64-bit to run well. Please upgrade your OS and PHP to 64-bit!" : "Zdá se, že provozujete 32bitovou verzi PHP. Aby správně fungoval, potřebuje Nextcloud 64bit. Přejděte na 64bit instalaci operačního systému a PHP!",
"Task Processing pickup speed" : "Rychlost vyzvedávání zpracovávání úkolů",
"_No scheduled tasks in the last %n hour._::_No scheduled tasks in the last %n hours._" : ["Žádné naplánované úkoly v uplynulé %n hodině.","Žádné naplánované úkoly v uplynulých %n hodinách.","Žádné naplánované úkoly v uplynulých %n hodinách.","Žádné naplánované úkoly v uplynulých %n hodinách."],
"_The task pickup speed has been ok in the last %n hour._::_The task pickup speed has been ok in the last %n hours._" : ["Rychlost vyzvedávání úkolů byla ok za uplynulou %n hodinu.","Rychlost vyzvedávání úkolů byla ok za uplynulých %n hodin.","Rychlost vyzvedávání úkolů byla ok za uplynulých %n hodin.","Rychlost vyzvedávání úkolů byla ok za uplynulých %n hodin."],
"_The task pickup speed has been slow in the last %n hour. Many tasks took longer than 4 minutes to be picked up. Consider setting up a worker to process tasks in the background._::_The task pickup speed has been slow in the last %n hours. Many tasks took longer than 4 minutes to be picked up. Consider setting up a worker to process tasks in the background._" : ["Rychlost vyzvedávání byla nízká za uplynulou %n hodinu. U mnoha úkolů trvalo více než 4 minuty, než byly vyzvednuty. Zvažte nastavení zpracovávajícího procesu na pozadí.","Rychlost vyzvedávání byla nízká za uplynulé %n hodiny. U mnoha úkolů trvalo více než 4 minuty, než byly vyzvednuty. Zvažte nastavení zpracovávajícího procesu na pozadí.","Rychlost vyzvedávání byla nízká za uplynulých %n hodin. U mnoha úkolů trvalo více než 4 minuty, než byly vyzvednuty. Zvažte nastavení zpracovávajícího procesu na pozadí.","Rychlost vyzvedávání byla nízká za uplynulé %n hodiny. U mnoha úkolů trvalo více než 4 minuty, než byly vyzvednuty. Zvažte nastavení zpracovávajícího procesu na pozadí."],
"Temporary space available" : "Dočasný prostor k dispozici",
"Error while checking the temporary PHP path - it was not properly set to a directory. Returned value: %s" : "Chyba při kontrole popisu umístění dočasných souborů PHP nebylo správně nastaveno na složku. Vrácená hodnota: %s",
"The PHP function \"disk_free_space\" is disabled, which prevents the check for enough space in the temporary directories." : "PHP funkce „disk_free_space“ je vypnutá, což brání v kontrolách zda je k dispozici dostatek místa ve složkách pro dočasná data.",
@@ -930,9 +927,9 @@
"If you use third party applications to connect to Nextcloud, please make sure to create and configure an app password for each before enabling second factor authentication." : "Pokud pro připojování se k Nextcloud používáte aplikace třetích stran, nezapomeňte před zapnutím ověřování druhým faktorem vytvořit pro jednotlivé aplikace jejich hesla.",
"Logged in account must be a subadmin" : "Je třeba, aby přihlášený účet byl dílčím správcem",
"- The `%1$s` HTTP header does not contain `%2$s`. This is a potential security or privacy risk, as it is recommended to adjust this setting accordingly." : "- HTTP hlavička `%1$s` neobsahuje `%2$s`. To značí možné ohrožení bezpečnosti a soukromí a je doporučeno toto nastavení upravit.",
"If autocompletion \"same group\" and \"phone number integration\" are enabled a match in either is enough to show the user." : "V případě, že jsou zapnuté automatická dokončování „stejná skupina“ a „začlenění telefonním číslem“, postačí pro zobrazení uživatele shoda s jedním z toho.",
"Restrict account name autocompletion to users based on phone number integration" : "Omezit doplňování názvu účtu uživatelům na základě začlenění telefonním číslem",
"Allow autocompletion when entering the full name or email address (ignoring missing phonebook match and being in the same group)" : "Povolit automatické dokončování při zadávání celého jména nebo e-mailové adresy (při ignorování chybějící shody s telefonním seznamem a toho, že je ve stejné skupině)",
"_No scheduled tasks in the last %n hour._::_No scheduled tasks in the last %n hours._" : ["Žádné naplánované úkoly v uplynulé %n hodině.","Žádné naplánované úkoly v uplynulých %n hodinách.","Žádné naplánované úkoly v uplynulých %n hodinách.","Žádné naplánované úkoly v uplynulých %n hodinách."],
"_The task pickup speed has been ok in the last %n hour._::_The task pickup speed has been ok in the last %n hours._" : ["Rychlost vyzvedávání úkolů byla ok za uplynulou %n hodinu.","Rychlost vyzvedávání úkolů byla ok za uplynulých %n hodin.","Rychlost vyzvedávání úkolů byla ok za uplynulých %n hodin.","Rychlost vyzvedávání úkolů byla ok za uplynulých %n hodin."],
"_The task pickup speed has been slow in the last %n hour. Many tasks took longer than 4 minutes to be picked up. Consider setting up a worker to process tasks in the background._::_The task pickup speed has been slow in the last %n hours. Many tasks took longer than 4 minutes to be picked up. Consider setting up a worker to process tasks in the background._" : ["Rychlost vyzvedávání byla nízká za uplynulou %n hodinu. U mnoha úkolů trvalo více než 4 minuty, než byly vyzvednuty. Zvažte nastavení zpracovávajícího procesu na pozadí.","Rychlost vyzvedávání byla nízká za uplynulé %n hodiny. U mnoha úkolů trvalo více než 4 minuty, než byly vyzvednuty. Zvažte nastavení zpracovávajícího procesu na pozadí.","Rychlost vyzvedávání byla nízká za uplynulých %n hodin. U mnoha úkolů trvalo více než 4 minuty, než byly vyzvednuty. Zvažte nastavení zpracovávajícího procesu na pozadí.","Rychlost vyzvedávání byla nízká za uplynulé %n hodiny. U mnoha úkolů trvalo více než 4 minuty, než byly vyzvednuty. Zvažte nastavení zpracovávajícího procesu na pozadí."],
"This app has no minimum Nextcloud version assigned. This will be an error in the future." : "Tato aplikace nemá nastavený žádný požadavek na minimální verzi Nextcloud. To v budoucnu bude hodnoceno jako chyba.",
"This app has no maximum Nextcloud version assigned. This will be an error in the future." : "Tato aplikace nemá nastavenou žádnou nejvyšší podporovanou verzi Nextcloud. To v budoucnu bude hodnoceno jako chyba.",
"Loading accounts …" : "Načítání účtů…",

View File

@@ -312,9 +312,6 @@ OC.L10N.register(
"64-bit" : "64-bit",
"It seems like you are running a 32-bit PHP version. Nextcloud needs 64-bit to run well. Please upgrade your OS and PHP to 64-bit!" : "Det ser ud til at du kører en 32-bit PHP version. Nextcloud skal bruge 64-bit for at køre ordentligt. Opgrader venligst dit OS og PHP til 64-bit!",
"Task Processing pickup speed" : "Opstarts-hastighed for opgavebehandling",
"_No scheduled tasks in the last %n hour._::_No scheduled tasks in the last %n hours._" : ["Ingen planlagte opgaver i den seneste %n time.","Ingen planlagte opgaver i de seneste %n timer."],
"_The task pickup speed has been ok in the last %n hour._::_The task pickup speed has been ok in the last %n hours._" : ["Opstarts-hastigheden for har været ok i den senest %n time.","Opstarts-hastigheden for har været ok i de seneste %n timer."],
"_The task pickup speed has been slow in the last %n hour. Many tasks took longer than 4 minutes to be picked up. Consider setting up a worker to process tasks in the background._::_The task pickup speed has been slow in the last %n hours. Many tasks took longer than 4 minutes to be picked up. Consider setting up a worker to process tasks in the background._" : ["Opgave-start hastigheden har været langsom de seneste %n timer. Mange opgaver tog længere end 4 minutter om at starte op. Overvej at opsætte en arbejdstråd der kan processerer opgaverne i baggrunden.","Opgave-start hastigheden er blevet langsom de seneste %n timer. Mange opgaver tog længere end 4 minutter om at blive startet. Overvej at opsætte en systemtjeneste, for at processere opgaverne i baggrunden."],
"Temporary space available" : "Tilgængeligt midlertidig plads",
"Error while checking the temporary PHP path - it was not properly set to a directory. Returned value: %s" : "Fejl under kontrol af den midlertidige PHP sti - den er ikke korrekt sat til en mappe. Returneret værdi: %s",
"The PHP function \"disk_free_space\" is disabled, which prevents the check for enough space in the temporary directories." : "PHP funktionen \"disk_free_space\" er deaktiveret, hvilket forhindrer kontrollen af tilstrækkelig plads i de midlertidige mapper.",
@@ -472,7 +469,7 @@ OC.L10N.register(
"GPUs support" : "GPUer understøttelse",
"Compute device" : "Beregningsapparat",
"Advanced deploy options" : "Avancerede udrulningsindstillinger",
"Edit ExApp deploy options before installation" : "Rediger ExApp udrulningsindstillinger før installation",
"Edit ExApp deploy options before installation" : "Redigér ExApp udrulningsindstillinger før installation",
"Configured ExApp deploy options. Can be set only during installation" : "Konfigurerede ExApp udrulningsindstillinger. Kan kun indstilles under installationen",
"Learn more" : "Lær mere",
"Environment variables" : "Miljøvariabler",
@@ -711,6 +708,7 @@ OC.L10N.register(
"Other languages" : "Andre sprog",
"Password change is disabled because the master key is disabled" : "Adgangskodeændring er deaktiveret, fordi hovednøglen er deaktiveret",
"No accounts" : "Ingen konti",
"Loading accounts …" : "Indlæser konti ...",
"List of accounts. This list is not fully rendered for performance reasons. The accounts will be rendered as you navigate through the list." : "Liste over konti. Hele listen er ikke gengivet, af hensyn til performance. Listen vil blive hentet løbende efterhånden som du navigerer igennem listen.",
"Manager" : "Administrator",
"Set line manager" : "Sæt linje administrator",
@@ -727,11 +725,13 @@ OC.L10N.register(
"Member of the following groups" : "Medlem af de følgende grupper",
"Set account groups" : "Indstil kontogrupper",
"Admin of the following groups" : "Administrator for følgende grupper",
"Set account as admin for …" : "Sæt konto som admin for ...",
"Quota" : "Kvote",
"Set account quota" : "Sæt konto kvote",
"Language" : "Sprog",
"Set default language" : "Vælg standard sprog",
"Add new account" : "Tilføj ny konto",
"_{userCount} account …_::_{userCount} accounts …_" : ["{userCount} konto …","{userCount} konti …"],
"_{userCount} account_::_{userCount} accounts_" : ["{userCount} konto","{userCount} konti"],
"Total rows summary" : "Samlet rækkeantal",
"Scroll to load more rows" : "Rul for at indlæse flere rækker",
@@ -766,6 +766,7 @@ OC.L10N.register(
"Email can't be empty" : "E-mail kan ikke være tom",
"Email was successfully changed" : "E-mail adresse er ændret",
"Welcome mail sent!" : "Velkomst-email sendt!",
"Loading account …" : "Indlæser konto ...",
"Change display name" : "Redigér vist navn",
"Set new password" : "Angiv ny adgangskode",
"You do not have permissions to see the details of this account" : "Du har ikke tilladelse til at se detaljer for denne konto",
@@ -799,6 +800,7 @@ OC.L10N.register(
"Passwordless authentication requires a secure connection." : "Adgangskodefri godkendelse kræver en sikker forbindelse.",
"Add WebAuthn device" : "Tilføj WebAuthn-enhed",
"Please authorize your WebAuthn device." : "Godkend venligst din WebAuthn-enhed.",
"Adding your device …" : "Tilføjer din enhed ...",
"Unnamed device" : "Unavngiven enhed",
"Passwordless Authentication" : "Adgangskodeløs godkendelse",
"Set up your account for passwordless authentication following the FIDO2 standard." : "Konfigurer din konto til adgangskodefri godkendelse efter FIDO2-standarden.",
@@ -875,6 +877,8 @@ OC.L10N.register(
"Show to logged in accounts only" : "Vis kun til påloggede konti",
"Hide" : "Skjul",
"Manually installed apps cannot be updated" : "Manuelt installerede apps kan ikke opdateres",
"{progress}% Deploying …" : "{progress}% udruller …",
"{progress}% Initializing …" : "{progress}% starter …",
"Health checking" : "Sundhedskontrol",
"Deploy and Enable" : "Udrul og aktiver",
"Download and enable" : "Download og aktiver",
@@ -938,9 +942,10 @@ OC.L10N.register(
"If you use third party applications to connect to Nextcloud, please make sure to create and configure an app password for each before enabling second factor authentication." : "Hvis du bruger tredjepartsapplikationer til at oprette forbindelse til Nextcloud, så skal du sørge for at oprette og konfigurere en app-adgangskode for hver applikation, før du aktiverer to-faktor-godkendelse.",
"Logged in account must be a subadmin" : "På-logget konto skal være en subadmin",
"- The `%1$s` HTTP header does not contain `%2$s`. This is a potential security or privacy risk, as it is recommended to adjust this setting accordingly." : "- HTTP- headeren ' %1$s' indeholder ikke ' %2$s'. Dette er en potentiel sikkerheds- eller fortrolighedsrisiko, da det anbefales at justere denne indstilling i overensstemmelse hermed.",
"If autocompletion \"same group\" and \"phone number integration\" are enabled a match in either is enough to show the user." : "Hvis autofuldførelse \"samme gruppe\" og \"telefonnummerintegration\" er aktiveret, så er et match i en af dem, nok til at vise brugeren.",
"Restrict account name autocompletion to users based on phone number integration" : "Begræns autofuldførelse af kontonavn til brugere baseret på telefonnummerintegration",
"Allow autocompletion when entering the full name or email address (ignoring missing phonebook match and being in the same group)" : "Tillad autofuldførelse, når du indtaster det fulde navn eller e-mailadresse (ignorerer manglende telefonbogsmatch og at man er i samme gruppe)",
"_No scheduled tasks in the last %n hour._::_No scheduled tasks in the last %n hours._" : ["Ingen planlagte opgaver i den seneste %n time.","Ingen planlagte opgaver i de seneste %n timer."],
"_The task pickup speed has been ok in the last %n hour._::_The task pickup speed has been ok in the last %n hours._" : ["Opstarts-hastigheden for har været ok i den senest %n time.","Opstarts-hastigheden for har været ok i de seneste %n timer."],
"_The task pickup speed has been slow in the last %n hour. Many tasks took longer than 4 minutes to be picked up. Consider setting up a worker to process tasks in the background._::_The task pickup speed has been slow in the last %n hours. Many tasks took longer than 4 minutes to be picked up. Consider setting up a worker to process tasks in the background._" : ["Opgave-start hastigheden har været langsom de seneste %n timer. Mange opgaver tog længere end 4 minutter om at starte op. Overvej at opsætte en arbejdstråd der kan processerer opgaverne i baggrunden.","Opgave-start hastigheden er blevet langsom de seneste %n timer. Mange opgaver tog længere end 4 minutter om at blive startet. Overvej at opsætte en systemtjeneste, for at processere opgaverne i baggrunden."],
"Also allow autocompletion on full match of the user id" : "Tillad også autofuldførsel ved fuldt match på bruger id",
"This app has no minimum Nextcloud version assigned. This will be an error in the future." : "Denne app har ikke angivet en minimums understøttet version af Nextcloud. I fremtiden vil dette medføre en fejl.",
"This app has no maximum Nextcloud version assigned. This will be an error in the future." : "Denne app har ikke angivet en maksimums understøttet version af Nextcloud. I fremtiden vil dette medføre en fejl.",
"Loading accounts …" : "Indlæser konti ...",

View File

@@ -310,9 +310,6 @@
"64-bit" : "64-bit",
"It seems like you are running a 32-bit PHP version. Nextcloud needs 64-bit to run well. Please upgrade your OS and PHP to 64-bit!" : "Det ser ud til at du kører en 32-bit PHP version. Nextcloud skal bruge 64-bit for at køre ordentligt. Opgrader venligst dit OS og PHP til 64-bit!",
"Task Processing pickup speed" : "Opstarts-hastighed for opgavebehandling",
"_No scheduled tasks in the last %n hour._::_No scheduled tasks in the last %n hours._" : ["Ingen planlagte opgaver i den seneste %n time.","Ingen planlagte opgaver i de seneste %n timer."],
"_The task pickup speed has been ok in the last %n hour._::_The task pickup speed has been ok in the last %n hours._" : ["Opstarts-hastigheden for har været ok i den senest %n time.","Opstarts-hastigheden for har været ok i de seneste %n timer."],
"_The task pickup speed has been slow in the last %n hour. Many tasks took longer than 4 minutes to be picked up. Consider setting up a worker to process tasks in the background._::_The task pickup speed has been slow in the last %n hours. Many tasks took longer than 4 minutes to be picked up. Consider setting up a worker to process tasks in the background._" : ["Opgave-start hastigheden har været langsom de seneste %n timer. Mange opgaver tog længere end 4 minutter om at starte op. Overvej at opsætte en arbejdstråd der kan processerer opgaverne i baggrunden.","Opgave-start hastigheden er blevet langsom de seneste %n timer. Mange opgaver tog længere end 4 minutter om at blive startet. Overvej at opsætte en systemtjeneste, for at processere opgaverne i baggrunden."],
"Temporary space available" : "Tilgængeligt midlertidig plads",
"Error while checking the temporary PHP path - it was not properly set to a directory. Returned value: %s" : "Fejl under kontrol af den midlertidige PHP sti - den er ikke korrekt sat til en mappe. Returneret værdi: %s",
"The PHP function \"disk_free_space\" is disabled, which prevents the check for enough space in the temporary directories." : "PHP funktionen \"disk_free_space\" er deaktiveret, hvilket forhindrer kontrollen af tilstrækkelig plads i de midlertidige mapper.",
@@ -470,7 +467,7 @@
"GPUs support" : "GPUer understøttelse",
"Compute device" : "Beregningsapparat",
"Advanced deploy options" : "Avancerede udrulningsindstillinger",
"Edit ExApp deploy options before installation" : "Rediger ExApp udrulningsindstillinger før installation",
"Edit ExApp deploy options before installation" : "Redigér ExApp udrulningsindstillinger før installation",
"Configured ExApp deploy options. Can be set only during installation" : "Konfigurerede ExApp udrulningsindstillinger. Kan kun indstilles under installationen",
"Learn more" : "Lær mere",
"Environment variables" : "Miljøvariabler",
@@ -709,6 +706,7 @@
"Other languages" : "Andre sprog",
"Password change is disabled because the master key is disabled" : "Adgangskodeændring er deaktiveret, fordi hovednøglen er deaktiveret",
"No accounts" : "Ingen konti",
"Loading accounts …" : "Indlæser konti ...",
"List of accounts. This list is not fully rendered for performance reasons. The accounts will be rendered as you navigate through the list." : "Liste over konti. Hele listen er ikke gengivet, af hensyn til performance. Listen vil blive hentet løbende efterhånden som du navigerer igennem listen.",
"Manager" : "Administrator",
"Set line manager" : "Sæt linje administrator",
@@ -725,11 +723,13 @@
"Member of the following groups" : "Medlem af de følgende grupper",
"Set account groups" : "Indstil kontogrupper",
"Admin of the following groups" : "Administrator for følgende grupper",
"Set account as admin for …" : "Sæt konto som admin for ...",
"Quota" : "Kvote",
"Set account quota" : "Sæt konto kvote",
"Language" : "Sprog",
"Set default language" : "Vælg standard sprog",
"Add new account" : "Tilføj ny konto",
"_{userCount} account …_::_{userCount} accounts …_" : ["{userCount} konto …","{userCount} konti …"],
"_{userCount} account_::_{userCount} accounts_" : ["{userCount} konto","{userCount} konti"],
"Total rows summary" : "Samlet rækkeantal",
"Scroll to load more rows" : "Rul for at indlæse flere rækker",
@@ -764,6 +764,7 @@
"Email can't be empty" : "E-mail kan ikke være tom",
"Email was successfully changed" : "E-mail adresse er ændret",
"Welcome mail sent!" : "Velkomst-email sendt!",
"Loading account …" : "Indlæser konto ...",
"Change display name" : "Redigér vist navn",
"Set new password" : "Angiv ny adgangskode",
"You do not have permissions to see the details of this account" : "Du har ikke tilladelse til at se detaljer for denne konto",
@@ -797,6 +798,7 @@
"Passwordless authentication requires a secure connection." : "Adgangskodefri godkendelse kræver en sikker forbindelse.",
"Add WebAuthn device" : "Tilføj WebAuthn-enhed",
"Please authorize your WebAuthn device." : "Godkend venligst din WebAuthn-enhed.",
"Adding your device …" : "Tilføjer din enhed ...",
"Unnamed device" : "Unavngiven enhed",
"Passwordless Authentication" : "Adgangskodeløs godkendelse",
"Set up your account for passwordless authentication following the FIDO2 standard." : "Konfigurer din konto til adgangskodefri godkendelse efter FIDO2-standarden.",
@@ -873,6 +875,8 @@
"Show to logged in accounts only" : "Vis kun til påloggede konti",
"Hide" : "Skjul",
"Manually installed apps cannot be updated" : "Manuelt installerede apps kan ikke opdateres",
"{progress}% Deploying …" : "{progress}% udruller …",
"{progress}% Initializing …" : "{progress}% starter …",
"Health checking" : "Sundhedskontrol",
"Deploy and Enable" : "Udrul og aktiver",
"Download and enable" : "Download og aktiver",
@@ -936,9 +940,10 @@
"If you use third party applications to connect to Nextcloud, please make sure to create and configure an app password for each before enabling second factor authentication." : "Hvis du bruger tredjepartsapplikationer til at oprette forbindelse til Nextcloud, så skal du sørge for at oprette og konfigurere en app-adgangskode for hver applikation, før du aktiverer to-faktor-godkendelse.",
"Logged in account must be a subadmin" : "På-logget konto skal være en subadmin",
"- The `%1$s` HTTP header does not contain `%2$s`. This is a potential security or privacy risk, as it is recommended to adjust this setting accordingly." : "- HTTP- headeren ' %1$s' indeholder ikke ' %2$s'. Dette er en potentiel sikkerheds- eller fortrolighedsrisiko, da det anbefales at justere denne indstilling i overensstemmelse hermed.",
"If autocompletion \"same group\" and \"phone number integration\" are enabled a match in either is enough to show the user." : "Hvis autofuldførelse \"samme gruppe\" og \"telefonnummerintegration\" er aktiveret, så er et match i en af dem, nok til at vise brugeren.",
"Restrict account name autocompletion to users based on phone number integration" : "Begræns autofuldførelse af kontonavn til brugere baseret på telefonnummerintegration",
"Allow autocompletion when entering the full name or email address (ignoring missing phonebook match and being in the same group)" : "Tillad autofuldførelse, når du indtaster det fulde navn eller e-mailadresse (ignorerer manglende telefonbogsmatch og at man er i samme gruppe)",
"_No scheduled tasks in the last %n hour._::_No scheduled tasks in the last %n hours._" : ["Ingen planlagte opgaver i den seneste %n time.","Ingen planlagte opgaver i de seneste %n timer."],
"_The task pickup speed has been ok in the last %n hour._::_The task pickup speed has been ok in the last %n hours._" : ["Opstarts-hastigheden for har været ok i den senest %n time.","Opstarts-hastigheden for har været ok i de seneste %n timer."],
"_The task pickup speed has been slow in the last %n hour. Many tasks took longer than 4 minutes to be picked up. Consider setting up a worker to process tasks in the background._::_The task pickup speed has been slow in the last %n hours. Many tasks took longer than 4 minutes to be picked up. Consider setting up a worker to process tasks in the background._" : ["Opgave-start hastigheden har været langsom de seneste %n timer. Mange opgaver tog længere end 4 minutter om at starte op. Overvej at opsætte en arbejdstråd der kan processerer opgaverne i baggrunden.","Opgave-start hastigheden er blevet langsom de seneste %n timer. Mange opgaver tog længere end 4 minutter om at blive startet. Overvej at opsætte en systemtjeneste, for at processere opgaverne i baggrunden."],
"Also allow autocompletion on full match of the user id" : "Tillad også autofuldførsel ved fuldt match på bruger id",
"This app has no minimum Nextcloud version assigned. This will be an error in the future." : "Denne app har ikke angivet en minimums understøttet version af Nextcloud. I fremtiden vil dette medføre en fejl.",
"This app has no maximum Nextcloud version assigned. This will be an error in the future." : "Denne app har ikke angivet en maksimums understøttet version af Nextcloud. I fremtiden vil dette medføre en fejl.",
"Loading accounts …" : "Indlæser konti ...",

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