├── .editorconfig ├── .env.development ├── .eslintrc.json ├── .github ├── ISSUE_TEMPLATE │ ├── 1-bug_report.md │ ├── 1-bug_report.md.license │ ├── 2-feature_request.md │ ├── 2-feature_request.md.license │ └── config.yml ├── dependabot.yml └── workflows │ ├── appstore-build-publish.yml │ ├── dependabot-approve-merge.yml │ ├── fixup.yml │ ├── lint-eslint.yml │ ├── lint-info-xml.yml │ ├── lint-php-cs.yml │ ├── lint-php.yml │ ├── lint-prettier.yml │ ├── node-test.yml │ ├── openapi.yml │ ├── phpunit-mariadb.yml │ ├── phpunit-mysql.yml │ ├── phpunit-oci.yml │ ├── phpunit-pgsql.yml │ ├── phpunit-sqlite.yml │ ├── playwright.yml │ ├── pr-feedback.yml │ ├── psalm-matrix.yml │ └── reuse.yml ├── .gitignore ├── .php-cs-fixer.dist.php ├── .prettierignore ├── .prettierrc.json ├── .tx ├── backport └── config ├── AUTHORS.md ├── CHANGELOG.en.md ├── CHANGELOG.md ├── CODE_OF_CONDUCT.md ├── COPYING ├── LICENSE ├── LICENSES ├── AGPL-3.0-only.txt ├── AGPL-3.0-or-later.txt ├── Apache-2.0.txt ├── CC0-1.0.txt └── MIT.txt ├── Makefile ├── README.md ├── REUSE.toml ├── appinfo └── info.xml ├── codecov.yml ├── composer.json ├── composer.lock ├── css ├── embedded.css ├── forms.css └── public.css ├── docs ├── API_v3.md ├── DataStructure.md └── Embedding.md ├── img ├── clock_loader_20.svg ├── clock_loader_80.svg ├── event.svg ├── favicon-mask.svg ├── favicon-touch.png ├── favicon-touch.svg ├── favicon.ico ├── favicon.png ├── favicon.svg ├── forms-dark.svg ├── forms.svg └── today.svg ├── l10n ├── .gitkeep ├── af.js ├── af.json ├── ar.js ├── ar.json ├── ast.js ├── ast.json ├── az.js ├── az.json ├── bg.js ├── bg.json ├── bn_BD.js ├── bn_BD.json ├── br.js ├── br.json ├── bs.js ├── bs.json ├── ca.js ├── ca.json ├── cs.js ├── cs.json ├── cy_GB.js ├── cy_GB.json ├── da.js ├── da.json ├── de.js ├── de.json ├── de_DE.js ├── de_DE.json ├── el.js ├── el.json ├── en_GB.js ├── en_GB.json ├── eo.js ├── eo.json ├── es.js ├── es.json ├── es_419.js ├── es_419.json ├── es_AR.js ├── es_AR.json ├── es_CL.js ├── es_CL.json ├── es_CO.js ├── es_CO.json ├── es_CR.js ├── es_CR.json ├── es_DO.js ├── es_DO.json ├── es_EC.js ├── es_EC.json ├── es_GT.js ├── es_GT.json ├── es_HN.js ├── es_HN.json ├── es_MX.js ├── es_MX.json ├── es_NI.js ├── es_NI.json ├── es_PA.js ├── es_PA.json ├── es_PE.js ├── es_PE.json ├── es_PR.js ├── es_PR.json ├── es_PY.js ├── es_PY.json ├── es_SV.js ├── es_SV.json ├── es_UY.js ├── es_UY.json ├── et_EE.js ├── et_EE.json ├── eu.js ├── eu.json ├── fa.js ├── fa.json ├── fi.js ├── fi.json ├── fr.js ├── fr.json ├── ga.js ├── ga.json ├── gl.js ├── gl.json ├── he.js ├── he.json ├── hr.js ├── hr.json ├── hu.js ├── hu.json ├── hy.js ├── hy.json ├── ia.js ├── ia.json ├── id.js ├── id.json ├── is.js ├── is.json ├── it.js ├── it.json ├── ja.js ├── ja.json ├── ka.js ├── ka.json ├── ka_GE.js ├── ka_GE.json ├── kab.js ├── kab.json ├── km.js ├── km.json ├── kn.js ├── kn.json ├── ko.js ├── ko.json ├── lb.js ├── lb.json ├── lo.js ├── lo.json ├── lt_LT.js ├── lt_LT.json ├── lv.js ├── lv.json ├── mk.js ├── mk.json ├── mn.js ├── mn.json ├── nb.js ├── nb.json ├── nl.js ├── nl.json ├── nn_NO.js ├── nn_NO.json ├── oc.js ├── oc.json ├── pl.js ├── pl.json ├── pt_BR.js ├── pt_BR.json ├── pt_PT.js ├── pt_PT.json ├── ro.js ├── ro.json ├── ru.js ├── ru.json ├── sc.js ├── sc.json ├── si.js ├── si.json ├── sk.js ├── sk.json ├── sl.js ├── sl.json ├── sq.js ├── sq.json ├── sr.js ├── sr.json ├── sr@latin.js ├── sr@latin.json ├── sv.js ├── sv.json ├── ta.js ├── ta.json ├── th.js ├── th.json ├── tr.js ├── tr.json ├── ug.js ├── ug.json ├── uk.js ├── uk.json ├── uz.js ├── uz.json ├── vi.js ├── vi.json ├── zh_CN.js ├── zh_CN.json ├── zh_HK.js ├── zh_HK.json ├── zh_TW.js └── zh_TW.json ├── lib ├── Activity │ ├── ActivityConstants.php │ ├── ActivityManager.php │ ├── Filter.php │ ├── Provider.php │ └── Settings │ │ ├── FormsActivitySettings.php │ │ ├── NewShare.php │ │ ├── NewSharedSubmission.php │ │ └── NewSubmission.php ├── Analytics │ └── AnalyticsDatasource.php ├── AppInfo │ └── Application.php ├── BackgroundJob │ ├── CleanupUploadedFilesJob.php │ ├── SyncSubmissionsWithLinkedFileJob.php │ └── UserDeletedJob.php ├── Capabilities.php ├── Constants.php ├── Controller │ ├── ApiController.php │ ├── ConfigController.php │ ├── PageController.php │ └── ShareApiController.php ├── Db │ ├── Answer.php │ ├── AnswerMapper.php │ ├── Form.php │ ├── FormMapper.php │ ├── Option.php │ ├── OptionMapper.php │ ├── Question.php │ ├── QuestionMapper.php │ ├── Share.php │ ├── ShareMapper.php │ ├── Submission.php │ ├── SubmissionMapper.php │ ├── UploadedFile.php │ └── UploadedFileMapper.php ├── Events │ ├── AbstractFormEvent.php │ └── FormSubmittedEvent.php ├── Exception │ └── NoSuchFormException.php ├── FormsMigrator.php ├── Listener │ ├── AnalyticsDatasourceListener.php │ └── UserDeletedListener.php ├── Middleware │ └── ThrottleFormAccessMiddleware.php ├── Migration │ ├── Version0010Date20190000000007.php │ ├── Version010102Date20200323120846.php │ ├── Version010200Date20200323141300.php │ ├── Version020002Date20200729205932.php │ ├── Version020200Date20210120082018.php │ ├── Version020202Date20210311150843.php │ ├── Version020300Date20210403214012.php │ ├── Version020300Date20210406114130.php │ ├── Version020300Date20210406133704.php │ ├── Version030000Date20211206213004.php │ ├── Version030000Date20220402100057.php │ ├── Version030000Date20220402151229.php │ ├── Version030000Date20220414203511.php │ ├── Version030000Date20220705192811.php │ ├── Version030000Date20220707130109.php │ ├── Version030000Date20220831195000.php │ ├── Version030000Date20220926200602.php │ ├── Version030100Date20221231100426.php │ ├── Version030100Date20230115214242.php │ ├── Version030100Date20230123182700.php │ ├── Version030100Date20230202175747.php │ ├── Version030200Date20230307141800.php │ ├── Version030400Date20230628011500.php │ ├── Version040010Date20240122133700.php │ ├── Version040200Date20240219201500.php │ ├── Version040200Date20240402200139.php │ ├── Version040200Date20240402224725.php │ ├── Version040300Date20240420155356.php │ ├── Version040300Date20240523123456.php │ ├── Version040300Date20240708163401.php │ ├── Version050000Date20241005173955.php │ ├── Version050004Date20250319180638.php │ └── Version050200Date20250109201500.php ├── ResponseDefinitions.php ├── Search │ ├── FormsSearchResultEntry.php │ └── SearchProvider.php ├── Service │ ├── CirclesService.php │ ├── ConfigService.php │ ├── FormsService.php │ └── SubmissionService.php └── Settings │ ├── Settings.php │ └── SettingsSection.php ├── license.php ├── openapi.json ├── package-lock.json ├── package.json ├── playwright.config.ts ├── playwright ├── e2e │ ├── create-empty-form.spec.ts │ ├── form-description.spec.ts │ └── ime-input.spec.ts ├── start-nextcloud-server.mjs └── support │ ├── fixtures │ ├── form.ts │ ├── navigation.ts │ ├── random-user.ts │ └── topBar.ts │ ├── sections │ ├── AppNavigationSection.ts │ ├── FormSection.ts │ ├── QuestionSection.ts │ ├── QuestionType.ts │ └── TopBarSection.ts │ └── setup.ts ├── psalm.xml ├── screenshots ├── forms1.png ├── forms2.png └── forms3.png ├── src ├── Forms.vue ├── FormsEmptyContent.vue ├── FormsSettings.vue ├── FormsSubmit.vue ├── components │ ├── AppNavigationForm.vue │ ├── ArchivedFormsModal.vue │ ├── Icons │ │ ├── FormsIcon.vue │ │ ├── IconCopyAll.vue │ │ ├── IconDragIndicator.vue │ │ ├── IconLinearScale.vue │ │ └── IconOverlay.vue │ ├── OptionInputDialog.vue │ ├── PaginationToolbar.vue │ ├── PillMenu.vue │ ├── QRDialog.vue │ ├── Questions │ │ ├── AnswerInput.vue │ │ ├── Question.vue │ │ ├── QuestionDate.vue │ │ ├── QuestionDropdown.vue │ │ ├── QuestionFile.vue │ │ ├── QuestionLinearScale.vue │ │ ├── QuestionLong.vue │ │ ├── QuestionMultiple.vue │ │ └── QuestionShort.vue │ ├── Results │ │ ├── Answer.vue │ │ ├── ResultsSummary.vue │ │ └── Submission.vue │ ├── SidebarTabs │ │ ├── SettingsSidebarTab.vue │ │ ├── SharingSearchDiv.vue │ │ ├── SharingShareDiv.vue │ │ ├── SharingSidebarTab.vue │ │ └── TransferOwnership.vue │ └── TopBar.vue ├── emptyContent.js ├── main.js ├── mixins │ ├── PermissionTypes.js │ ├── QuestionMixin.js │ ├── QuestionMultipleMixin.ts │ ├── ShareLinkMixin.js │ ├── ShareTypes.js │ ├── UserSearchMixin.js │ └── ViewsMixin.js ├── models │ ├── AnswerTypes.js │ ├── Constants.ts │ ├── Entities.d.ts │ ├── FileTypes.js │ └── ValidationTypes.js ├── router.js ├── scssmixins │ └── markdownOutput.scss ├── settings.js ├── submit.js ├── utils │ ├── CancelableRequest.js │ ├── Logger.js │ ├── OcsResponse2Data.js │ ├── RegularExpression.js │ └── SetWindowTitle.js └── views │ ├── Create.vue │ ├── Results.vue │ ├── Sidebar.vue │ └── Submit.vue ├── stylelint.config.cjs ├── templates ├── main.php └── settings.php ├── tests ├── Integration │ ├── Api │ │ ├── ApiV3Test.php │ │ └── RespectAdminSettingsTest.php │ ├── DB │ │ ├── SharedFormsTest.php │ │ └── SubmissionMapperTest.php │ └── IntegrationBase.php ├── Unit │ ├── Activity │ │ ├── ActivityManagerTest.php │ │ ├── FilterTest.php │ │ ├── ProviderTest.php │ │ └── Settings │ │ │ ├── FormsActivitySettingsTest.php │ │ │ ├── NewShareTest.php │ │ │ ├── NewSharedSubmissionTest.php │ │ │ └── NewSubmissionTest.php │ ├── Analytics │ │ └── AnalyticsDatasourceTest.php │ ├── BackgroundJob │ │ ├── CleanupUploadedFilesJobTest.php │ │ ├── SyncSubmissionsWithLinkedFileJobTest.php │ │ └── UserDeletedJobTest.php │ ├── Controller │ │ ├── ApiControllerTest.php │ │ ├── ConfigControllerTest.php │ │ ├── PageControllerTest.php │ │ └── ShareApiControllerTest.php │ ├── FormsMigratorTest.php │ ├── Listener │ │ └── UserDeletedListenerTest.php │ ├── MockedMapperException.php │ └── Service │ │ ├── CirclesServiceTest.php │ │ ├── ConfigServiceTest.php │ │ ├── FormsServiceTest.php │ │ └── SubmissionServiceTest.php ├── bootstrap.php ├── phpunit.integration.xml ├── phpunit.xml ├── psalm-baseline.xml └── stubs │ ├── oc_hooks_emitter.php │ └── oca-analytics-idatasource.php ├── tsconfig.json ├── vendor-bin ├── cs-fixer │ ├── composer.json │ └── composer.lock ├── openapi-extractor │ ├── composer.json │ └── composer.lock └── psalm │ ├── composer.json │ └── composer.lock └── vite.config.js /.editorconfig: -------------------------------------------------------------------------------- 1 | /** 2 | * SPDX-FileCopyrightText: 2019 Nextcloud GmbH and Nextcloud contributors 3 | * SPDX-License-Identifier: AGPL-3.0-or-later 4 | */ 5 | 6 | root = true 7 | 8 | [*] 9 | charset = utf-8 10 | indent_style = tab 11 | indent_size = 4 12 | end_of_line = lf 13 | insert_final_newline = true 14 | trim_trailing_whitespace = true -------------------------------------------------------------------------------- /.env.development: -------------------------------------------------------------------------------- 1 | NODE_ENV=development 2 | -------------------------------------------------------------------------------- /.eslintrc.json: -------------------------------------------------------------------------------- 1 | /** 2 | * SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors 3 | * SPDX-License-Identifier: AGPL-3.0-or-later 4 | */ 5 | 6 | { 7 | "globals": { 8 | "appName": true 9 | }, 10 | "extends": [ 11 | "@nextcloud", 12 | "prettier" // < this needs to be the last one to override all previous 13 | ], 14 | "rules": { 15 | // We are using the @nextcloud/logger 16 | "no-console": "error", 17 | "import/no-unresolved": ["error", { "ignore": ["\\?raw"] }] 18 | }, 19 | "overrides": [ 20 | { 21 | "files": ["**/*.vue"], 22 | "rules": { 23 | "vue/first-attribute-linebreak": [ 24 | "error", 25 | { "multiline": "below", "singleline": "ignore" } 26 | ] 27 | } 28 | } 29 | ] 30 | } 31 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/1-bug_report.md.license: -------------------------------------------------------------------------------- 1 | SPDX-FileCopyrightText: 2018-2025 Nextcloud GmbH and Nextcloud contributors 2 | SPDX-License-Identifier: AGPL-3.0-or-later 3 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/2-feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: 0. Needs triage, enhancement 6 | type: 'Enhancement' 7 | assignees: '' 8 | --- 9 | 10 | **Nextcloud (please complete the following information):** 11 | 12 | - Nextcloud-Version: [e.g. 19.0.0] 13 | - Forms-Version: [e.g. 2.0.0-beta4] 14 | 15 | **Is your feature request related to a problem? Please describe.** 16 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 17 | 18 | **Describe the solution you'd like** 19 | A clear and concise description of what you want to happen. 20 | 21 | **Describe alternatives you've considered** 22 | A clear and concise description of any alternative solutions or features you've considered. 23 | 24 | **Additional context** 25 | Add any other context or screenshots about the feature request here. 26 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/2-feature_request.md.license: -------------------------------------------------------------------------------- 1 | SPDX-FileCopyrightText: 2018-2025 Nextcloud GmbH and Nextcloud contributors 2 | SPDX-License-Identifier: AGPL-3.0-or-later 3 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/config.yml: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: 2020 Nextcloud GmbH and Nextcloud contributors 2 | # SPDX-License-Identifier: AGPL-3.0-or-later 3 | blank_issues_enabled: false 4 | contact_links: 5 | - name: 🚨 Report a security or privacy issue 6 | url: https://hackerone.com/nextcloud 7 | about: Report security and privacy related issues privately to the Nextcloud team, so we can coordinate the fix and release without potentially exposing all Nextcloud servers and users in the meantime. 8 | - name: ❓ Community Support and Help 9 | url: https://help.nextcloud.com/ 10 | about: Configuration, webserver/proxy or performance issues and other questions 11 | - name: 💼 Nextcloud Enterprise 12 | url: https://portal.nextcloud.com/ 13 | about: If you are a Nextcloud Enterprise customer, or need Professional support, so it can be resolved directly by our dedicated engineers more quickly 14 | -------------------------------------------------------------------------------- /.github/workflows/dependabot-approve-merge.yml: -------------------------------------------------------------------------------- 1 | # This workflow is provided via the organization template repository 2 | # 3 | # https://github.com/nextcloud/.github 4 | # https://docs.github.com/en/actions/learn-github-actions/sharing-workflows-with-your-organization 5 | # 6 | # SPDX-FileCopyrightText: 2021-2024 Nextcloud GmbH and Nextcloud contributors 7 | # SPDX-License-Identifier: MIT 8 | 9 | name: Dependabot 10 | 11 | on: 12 | pull_request_target: 13 | branches: 14 | - main 15 | - master 16 | - stable* 17 | 18 | permissions: 19 | contents: read 20 | 21 | concurrency: 22 | group: dependabot-approve-merge-${{ github.head_ref || github.run_id }} 23 | cancel-in-progress: true 24 | 25 | jobs: 26 | auto-approve-merge: 27 | if: github.actor == 'dependabot[bot]' || github.actor == 'renovate[bot]' 28 | runs-on: ubuntu-latest-low 29 | permissions: 30 | # for hmarr/auto-approve-action to approve PRs 31 | pull-requests: write 32 | 33 | steps: 34 | - name: Disabled on forks 35 | if: ${{ github.event.pull_request.head.repo.full_name != github.repository }} 36 | run: | 37 | echo 'Can not approve PRs from forks' 38 | exit 1 39 | 40 | # GitHub actions bot approve 41 | - uses: hmarr/auto-approve-action@b40d6c9ed2fa10c9a2749eca7eb004418a705501 # v2 42 | with: 43 | github-token: ${{ secrets.GITHUB_TOKEN }} 44 | 45 | # Nextcloud bot approve and merge request 46 | - uses: ahmadnassri/action-dependabot-auto-merge@45fc124d949b19b6b8bf6645b6c9d55f4f9ac61a # v2 47 | with: 48 | target: minor 49 | github-token: ${{ secrets.DEPENDABOT_AUTOMERGE_TOKEN }} 50 | -------------------------------------------------------------------------------- /.github/workflows/fixup.yml: -------------------------------------------------------------------------------- 1 | # This workflow is provided via the organization template repository 2 | # 3 | # https://github.com/nextcloud/.github 4 | # https://docs.github.com/en/actions/learn-github-actions/sharing-workflows-with-your-organization 5 | # 6 | # SPDX-FileCopyrightText: 2021-2024 Nextcloud GmbH and Nextcloud contributors 7 | # SPDX-License-Identifier: MIT 8 | 9 | name: Block fixup and squash commits 10 | 11 | on: 12 | pull_request: 13 | types: [opened, ready_for_review, reopened, synchronize] 14 | 15 | permissions: 16 | contents: read 17 | 18 | concurrency: 19 | group: fixup-${{ github.head_ref || github.run_id }} 20 | cancel-in-progress: true 21 | 22 | jobs: 23 | commit-message-check: 24 | if: github.event.pull_request.draft == false 25 | 26 | permissions: 27 | pull-requests: write 28 | name: Block fixup and squash commits 29 | 30 | runs-on: ubuntu-latest-low 31 | 32 | steps: 33 | - name: Run check 34 | uses: skjnldsv/block-fixup-merge-action@c138ea99e45e186567b64cf065ce90f7158c236a # v2 35 | with: 36 | repo-token: ${{ secrets.GITHUB_TOKEN }} 37 | -------------------------------------------------------------------------------- /.github/workflows/lint-info-xml.yml: -------------------------------------------------------------------------------- 1 | # This workflow is provided via the organization template repository 2 | # 3 | # https://github.com/nextcloud/.github 4 | # https://docs.github.com/en/actions/learn-github-actions/sharing-workflows-with-your-organization 5 | # 6 | # SPDX-FileCopyrightText: 2021-2024 Nextcloud GmbH and Nextcloud contributors 7 | # SPDX-License-Identifier: MIT 8 | 9 | name: Lint info.xml 10 | 11 | on: pull_request 12 | 13 | permissions: 14 | contents: read 15 | 16 | concurrency: 17 | group: lint-info-xml-${{ github.head_ref || github.run_id }} 18 | cancel-in-progress: true 19 | 20 | jobs: 21 | xml-linters: 22 | runs-on: ubuntu-latest-low 23 | 24 | name: info.xml lint 25 | steps: 26 | - name: Checkout 27 | uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 28 | 29 | - name: Download schema 30 | run: wget https://raw.githubusercontent.com/nextcloud/appstore/master/nextcloudappstore/api/v1/release/info.xsd 31 | 32 | - name: Lint info.xml 33 | uses: ChristophWurst/xmllint-action@36f2a302f84f8c83fceea0b9c59e1eb4a616d3c1 # v1.2 34 | with: 35 | xml-file: ./appinfo/info.xml 36 | xml-schema-file: ./info.xsd 37 | -------------------------------------------------------------------------------- /.github/workflows/reuse.yml: -------------------------------------------------------------------------------- 1 | # This workflow is provided via the organization template repository 2 | # 3 | # https://github.com/nextcloud/.github 4 | # https://docs.github.com/en/actions/learn-github-actions/sharing-workflows-with-your-organization 5 | 6 | # SPDX-FileCopyrightText: 2022 Free Software Foundation Europe e.V. 7 | # 8 | # SPDX-License-Identifier: CC0-1.0 9 | 10 | name: REUSE Compliance Check 11 | 12 | on: [pull_request] 13 | 14 | permissions: 15 | contents: read 16 | 17 | jobs: 18 | reuse-compliance-check: 19 | runs-on: ubuntu-latest 20 | steps: 21 | - name: Checkout 22 | uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 23 | with: 24 | persist-credentials: false 25 | 26 | - name: REUSE Compliance Check 27 | uses: fsfe/reuse-action@bb774aa972c2a89ff34781233d275075cbddf542 # v5.0.0 28 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: 2019 Nextcloud GmbH and Nextcloud contributors 2 | # SPDX-License-Identifier: AGPL-3.0-only 3 | .DS_Store 4 | node_modules/ 5 | vendor/ 6 | /vendor-bin/*/vendor 7 | npm-debug.log* 8 | yarn-debug.log* 9 | yarn-error.log* 10 | 11 | # Editor directories and files 12 | .idea 13 | .vscode 14 | *.suo 15 | *.ntvs* 16 | *.njsproj 17 | *.sln 18 | 19 | .marginalia 20 | 21 | build/ 22 | coverage/ 23 | 24 | cypress/screenshots 25 | cypress/snapshots 26 | 27 | # Compiled files 28 | js/ 29 | css/forms-style.css 30 | 31 | # Compile-Cache 32 | v8-compile-cache-0/ 33 | 34 | # php-cs cache 35 | .php-cs-fixer.cache 36 | 37 | # phpunit results 38 | .phpunit.result.cache 39 | clover.unit.xml 40 | clover.integration.xml 41 | /test-results/ 42 | /playwright-report/ 43 | /blob-report/ 44 | /playwright/.cache/ 45 | -------------------------------------------------------------------------------- /.php-cs-fixer.dist.php: -------------------------------------------------------------------------------- 1 | getFinder() 17 | ->notPath('build') 18 | ->notPath('l10n') 19 | ->notPath('node_modules') 20 | ->notPath('src') 21 | ->notPath('vendor') 22 | ->in(__DIR__); 23 | return $config; 24 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors 2 | # SPDX-License-Identifier: AGPL-3.0-only 3 | 4 | # version control systems directories 5 | **/.git 6 | **/.svn 7 | **/.hg 8 | 9 | # Github workflows 10 | .github/workflows/ 11 | 12 | # 3rdparty dependencies 13 | **/node_modules 14 | **/vendor 15 | 16 | # Compiled JS output 17 | js/ 18 | 19 | # Handled by transifex 20 | l10n/ 21 | 22 | # OpenAPI 23 | openapi.json 24 | 25 | # PHP 26 | lib/ 27 | **/*.php 28 | composer.json 29 | composer.lock 30 | -------------------------------------------------------------------------------- /.prettierrc.json: -------------------------------------------------------------------------------- 1 | "@nextcloud/prettier-config" 2 | -------------------------------------------------------------------------------- /.tx/backport: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nextcloud/forms/ddc8a45e410efba1aaedaf72e2a109b6a199cf7e/.tx/backport -------------------------------------------------------------------------------- /.tx/config: -------------------------------------------------------------------------------- 1 | [main] 2 | host = https://www.transifex.com 3 | lang_map = nb_NO: nb, sk_SK: sk, th_TH: th, ja_JP: ja, bg_BG: bg, cs_CZ: cs, fi_FI: fi, hu_HU: hu 4 | 5 | [o:nextcloud:p:nextcloud:r:forms] 6 | file_filter = translationfiles//forms.po 7 | source_file = translationfiles/templates/forms.pot 8 | source_lang = en 9 | type = PO 10 | 11 | -------------------------------------------------------------------------------- /AUTHORS.md: -------------------------------------------------------------------------------- 1 | 5 | 6 | # Authors 7 | 8 | - Abdrii Ilkiv 9 | - Affan Hussain 10 | - Ajfar Huq 11 | - Andrii Ilkiv 12 | - Christian Hartmann 13 | - Felix Beichler <35049588+Himmelxd@users.noreply.github.com> 14 | - Ferdinand Thiessen 15 | - Ferdinand Thiessen 16 | - Hamza Mahjoubi 17 | - Inigo Jiron 18 | - Jan C. Borchardt https://jancborchardt.net 19 | - Jan-Christoph Borchardt 20 | - Joas Schilling 21 | - John Molakvoæ (skjnldsv) 22 | - John Molakvoæ 23 | - Jonas Rittershofer 24 | - Julius Härtl 25 | - Kai Schröer 26 | - Kostiantyn Miakshyn 27 | - Marcel Klehr 28 | - Marcel Scherello 29 | - Marco Ambrosini 30 | - Michael Schmidmaier 31 | - Michael Schmidmaier 32 | - Nick Gallo 33 | - René Gieling 34 | - Roeland Jago Douma 35 | - Simon Vieille 36 | - Simon Vieille 37 | - Thomas Müller 38 | - Vinzenz Rosenkranz 39 | - affan98 40 | - ownCloud, Inc. 41 | -------------------------------------------------------------------------------- /CHANGELOG.en.md: -------------------------------------------------------------------------------- 1 | 5 | 6 | # Changelog 7 | 8 | ## v5.1.0 - 2025-04-03 9 | 10 | - **Date: restrictions and ranges** 11 | 12 | The date question type got three new settings: You can ask for a date range and set a minimum/maximum date that can be chosen. 13 | 14 | ## v5.0.0 - 2025-02-25 15 | 16 | - **Re-order options** 17 | 18 | Options of multiple choice questions (radio/checkbox/dropdown) can now be re-ordered using a menu or drag'n'drop. 19 | 20 | - **Unified Search integration** 21 | 22 | You can now use the Unified Search to search forms based on the title and the description. 23 | 24 | - **Clone archived forms** 25 | 26 | You can now clone an archived form. 27 | 28 | - **Clear a form** 29 | 30 | You can now clear a form and also get asked if you want to start new when the form has changed since your last visit and you didn't submit the form yet. 31 | 32 | ## v4.3.0 - 2024-10-04 33 | 34 | - **New question type: Files** 35 | 36 | You can now ask for file uploads in your forms! 37 | 38 | - **Share your forms via QR code** 39 | 40 | Get a QR code representation of your public share link! 41 | 42 | - **Set limits for your checkbox questions** 43 | 44 | Ask for a minimum/maximum number of answers! 45 | 46 | - **Add many options at once** 47 | 48 | It's now way easier to add a lot of options to your checkbox/dropdown/radio questions! 49 | 50 | - **Deprecation of legacy links** 51 | 52 | Legacy share links will be removed in v5.0 of Forms. Forms with such links will show a warning in edit and submit view. 53 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | 5 | 6 | In the Nextcloud community, participants from all over the world come together to create Free Software for a free internet. This is made possible by the support, hard work and enthusiasm of thousands of people, including those who create and use Nextcloud software. 7 | 8 | Our code of conduct offers some guidance to ensure Nextcloud participants can cooperate effectively in a positive and inspiring atmosphere, and to explain how together we can strengthen and support each other. 9 | 10 | The Code of Conduct is shared by all contributors and users who engage with the Nextcloud team and its community services. It presents a summary of the shared values and “common sense” thinking in our community. 11 | 12 | You can find our full code of conduct on our website: https://nextcloud.com/code-of-conduct/ 13 | 14 | Please, keep our CoC in mind when you contribute! That way, everyone can be a part of our community in a productive, positive, creative and fun way. 15 | -------------------------------------------------------------------------------- /LICENSES/MIT.txt: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 6 | 7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 8 | 9 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: 2019 Nextcloud GmbH and Nextcloud contributors 2 | # SPDX-License-Identifier: AGPL-3.0-only 3 | # Makefile for building the project 4 | 5 | app_name=forms 6 | project_dir=$(CURDIR)/../$(app_name) 7 | build_dir=$(CURDIR)/build/artifacts 8 | appstore_package_name=$(build_dir)/$(app_name) 9 | source_dir=$(build_dir)/source 10 | 11 | all: clean install-composer-deps install-npm-deps-dev build-js-production appstore 12 | 13 | clean: 14 | rm -rf $(build_dir) 15 | rm -rf node_modules 16 | rm -rf vendor 17 | rm -rf js 18 | 19 | install-deps: install-composer-deps-dev install-npm-deps-dev 20 | 21 | install-composer-deps: 22 | composer install --no-dev -o 23 | 24 | install-composer-deps-dev: 25 | composer install -o 26 | 27 | install-npm-deps: 28 | npm install --production 29 | 30 | install-npm-deps-dev: 31 | npm install 32 | 33 | optimize-js: install-npm-deps-dev 34 | npm run build 35 | 36 | build-js: 37 | npm run dev 38 | 39 | build-js-production: 40 | npm run build 41 | 42 | watch-js: 43 | npm run watch 44 | 45 | dev-setup: install-composer-deps-dev install-npm-deps-dev build-js 46 | 47 | appstore: 48 | rm -rf $(build_dir) 49 | mkdir -p $(build_dir) 50 | tar cvzf $(appstore_package_name).tar.gz \ 51 | --exclude-vcs \ 52 | $(project_dir)/appinfo \ 53 | $(project_dir)/COPYING \ 54 | $(project_dir)/css \ 55 | $(project_dir)/img \ 56 | $(project_dir)/js \ 57 | $(project_dir)/l10n \ 58 | $(project_dir)/lib \ 59 | $(project_dir)/templates \ 60 | $(project_dir)/vendor \ 61 | $(project_dir)/CHANGELOG.md 62 | -------------------------------------------------------------------------------- /codecov.yml: -------------------------------------------------------------------------------- 1 | # SPDX-FileCopyrightText: 2021 Nextcloud GmbH and Nextcloud contributors 2 | # SPDX-License-Identifier: AGPL-3.0-or-later 3 | comment: 4 | require_changes: true 5 | layout: 'diff' 6 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "nextcloud/forms", 3 | "config": { 4 | "optimize-autoloader": true, 5 | "classmap-authoritative": true, 6 | "sort-packages": true, 7 | "platform": { 8 | "php": "8.1" 9 | }, 10 | "allow-plugins": { 11 | "bamarni/composer-bin-plugin": true 12 | } 13 | }, 14 | "scripts": { 15 | "post-install-cmd": "@composer bin all install --ansi", 16 | "bin": "echo 'bin not installed'", 17 | "cs:fix": "php-cs-fixer fix", 18 | "cs:check": "php-cs-fixer fix --dry-run --diff", 19 | "lint": "find . -name \\*.php -not -path './vendor*/*' -print0 | xargs -0 -n1 php -l", 20 | "test:unit": "phpunit -c tests/phpunit.xml", 21 | "test:integration": "phpunit -c tests/phpunit.integration.xml", 22 | "psalm": "psalm --no-cache", 23 | "openapi": "generate-spec" 24 | }, 25 | "require-dev": { 26 | "bamarni/composer-bin-plugin": "^1.8", 27 | "phpunit/phpunit": "^9" 28 | }, 29 | "require": { 30 | "maennchen/zipstream-php": "^2.4", 31 | "phpoffice/phpspreadsheet": "^4.0" 32 | }, 33 | "extra": { 34 | "bamarni-bin": { 35 | "bin-links": true, 36 | "forward-command": true 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /css/embedded.css: -------------------------------------------------------------------------------- 1 | /** 2 | * SPDX-FileCopyrightText: 2022 Nextcloud GmbH and Nextcloud contributors 3 | * SPDX-License-Identifier: AGPL-3.0-or-later 4 | */ 5 | 6 | /* Remove background for embedded view */ 7 | body { 8 | background-color: var(--color-main-background) !important; 9 | background-image: none !important; 10 | } 11 | -------------------------------------------------------------------------------- /css/forms.css: -------------------------------------------------------------------------------- 1 | /** 2 | * SPDX-FileCopyrightText: 2020 Nextcloud GmbH and Nextcloud contributors 3 | * SPDX-License-Identifier: AGPL-3.0-or-later 4 | */ 5 | 6 | /* Padding for Auto-Scroll if a required question is not filled. 7 | * 60px matches around the height of two lines of question-text 8 | */ 9 | html { 10 | scroll-padding-top: calc(var(--header-height) + 60px); 11 | } 12 | 13 | .icon-forms { 14 | background-image: url(../img/forms-dark.svg); 15 | filter: var(--background-invert-if-dark); 16 | } 17 | 18 | .icon-forms-white, 19 | .icon-forms.icon-white { 20 | background-image: url(../img/forms.svg); 21 | filter: var(--background-invert-if-dark); 22 | } 23 | -------------------------------------------------------------------------------- /css/public.css: -------------------------------------------------------------------------------- 1 | /** 2 | * SPDX-FileCopyrightText: 2020 Nextcloud GmbH and Nextcloud contributors 3 | * SPDX-License-Identifier: AGPL-3.0-or-later 4 | */ 5 | 6 | #content-vue { 7 | /* Full height, shifting the footer(=65px) to the ground. */ 8 | min-height: calc(100vh - 65px); 9 | } 10 | -------------------------------------------------------------------------------- /img/clock_loader_20.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /img/clock_loader_80.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /img/event.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /img/favicon-mask.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /img/favicon-touch.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nextcloud/forms/ddc8a45e410efba1aaedaf72e2a109b6a199cf7e/img/favicon-touch.png -------------------------------------------------------------------------------- /img/favicon-touch.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /img/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nextcloud/forms/ddc8a45e410efba1aaedaf72e2a109b6a199cf7e/img/favicon.ico -------------------------------------------------------------------------------- /img/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nextcloud/forms/ddc8a45e410efba1aaedaf72e2a109b6a199cf7e/img/favicon.png -------------------------------------------------------------------------------- /img/favicon.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /img/forms-dark.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /img/forms.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /img/today.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /l10n/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nextcloud/forms/ddc8a45e410efba1aaedaf72e2a109b6a199cf7e/l10n/.gitkeep -------------------------------------------------------------------------------- /l10n/af.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "forms", 3 | { 4 | "Copy" : "Kopieer", 5 | "Shared with you" : "Met u gedeel", 6 | "Required" : "Vereis", 7 | "Delete" : "Skrap", 8 | "Uploading …" : "Laai tans op …", 9 | "Other" : "Ander", 10 | "Set expiration date" : "Stel vervaldatum", 11 | "Group" : "Groep", 12 | "Share link" : "Deel skakel", 13 | "Add link" : "Voeg skakel toe", 14 | "Internal link" : "Interne skakel", 15 | "View" : "Bekyk", 16 | "Edit" : "Wysig", 17 | "View mode" : "Lysaansig", 18 | "Share" : "Deel", 19 | "Description" : "Beskrywing", 20 | "Summary" : "Opsomming", 21 | "Download" : "Laai af", 22 | "Search" : "Soek", 23 | "Settings" : "Instellings", 24 | "Submit" : "Dien in", 25 | "File" : "Lêer", 26 | "Date" : "Datum", 27 | "Time" : "Tyd", 28 | "Text" : "Teks", 29 | "Phone number" : "Foonnommer", 30 | "Email address" : "E-posadres" 31 | }, 32 | "nplurals=2; plural=(n != 1);"); 33 | -------------------------------------------------------------------------------- /l10n/af.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "Copy" : "Kopieer", 3 | "Shared with you" : "Met u gedeel", 4 | "Required" : "Vereis", 5 | "Delete" : "Skrap", 6 | "Uploading …" : "Laai tans op …", 7 | "Other" : "Ander", 8 | "Set expiration date" : "Stel vervaldatum", 9 | "Group" : "Groep", 10 | "Share link" : "Deel skakel", 11 | "Add link" : "Voeg skakel toe", 12 | "Internal link" : "Interne skakel", 13 | "View" : "Bekyk", 14 | "Edit" : "Wysig", 15 | "View mode" : "Lysaansig", 16 | "Share" : "Deel", 17 | "Description" : "Beskrywing", 18 | "Summary" : "Opsomming", 19 | "Download" : "Laai af", 20 | "Search" : "Soek", 21 | "Settings" : "Instellings", 22 | "Submit" : "Dien in", 23 | "File" : "Lêer", 24 | "Date" : "Datum", 25 | "Time" : "Tyd", 26 | "Text" : "Teks", 27 | "Phone number" : "Foonnommer", 28 | "Email address" : "E-posadres" 29 | },"pluralForm" :"nplurals=2; plural=(n != 1);" 30 | } -------------------------------------------------------------------------------- /l10n/az.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "forms", 3 | { 4 | "No" : "Xeyir", 5 | "Yes" : "Bəli", 6 | "Copy" : "Kopyala", 7 | "Shared with you" : "Shared with you", 8 | "Select groups" : "Qrupları seç", 9 | "Delete" : "Sil", 10 | "Other" : "Digər", 11 | "Group" : "Qrup", 12 | "Share link" : "Linki yayımla", 13 | "Edit" : "Dəyişiklik et", 14 | "Share" : "Paylaş", 15 | "Description" : "Açıqlanma", 16 | "Summary" : "Xülasə", 17 | "Download" : "Yüklə", 18 | "Search" : "Axtarış", 19 | "Sharing" : "Paylaşılır", 20 | "Settings" : "Quraşdırmalar", 21 | "Abort" : "Durdur", 22 | "Date" : "Date", 23 | "Time" : "Vaxt" 24 | }, 25 | "nplurals=2; plural=(n != 1);"); 26 | -------------------------------------------------------------------------------- /l10n/az.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "No" : "Xeyir", 3 | "Yes" : "Bəli", 4 | "Copy" : "Kopyala", 5 | "Shared with you" : "Shared with you", 6 | "Select groups" : "Qrupları seç", 7 | "Delete" : "Sil", 8 | "Other" : "Digər", 9 | "Group" : "Qrup", 10 | "Share link" : "Linki yayımla", 11 | "Edit" : "Dəyişiklik et", 12 | "Share" : "Paylaş", 13 | "Description" : "Açıqlanma", 14 | "Summary" : "Xülasə", 15 | "Download" : "Yüklə", 16 | "Search" : "Axtarış", 17 | "Sharing" : "Paylaşılır", 18 | "Settings" : "Quraşdırmalar", 19 | "Abort" : "Durdur", 20 | "Date" : "Date", 21 | "Time" : "Vaxt" 22 | },"pluralForm" :"nplurals=2; plural=(n != 1);" 23 | } -------------------------------------------------------------------------------- /l10n/bn_BD.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "forms", 3 | { 4 | "No" : "না", 5 | "Yes" : "হ্যাঁ", 6 | "Shared with you" : "Shared with you", 7 | "Select groups" : "গ্রুপ নির্ধারণ", 8 | "Cancel" : "বাতিল করুন", 9 | "Delete" : "মুছে", 10 | "Other" : "অন্যান্য", 11 | "Set expiration date" : "মেয়াদোত্তীর্ণ হওয়ার তারিখ নির্ধারণ করুন", 12 | "Group" : "গোষ্ঠীসমূহ", 13 | "Share link" : "লিংক ভাগাভাগি করেন", 14 | "Edit" : "সম্পাদনা", 15 | "Share" : "ভাগাভাগি কর", 16 | "Description" : "বিবরণ", 17 | "Download" : "ডাউনলোড", 18 | "Search" : "Search", 19 | "Sharing" : "ভাগাভাগিরত", 20 | "Settings" : "সেটিংস", 21 | "Abort" : "বাতিল কর", 22 | "Date" : "Date", 23 | "Time" : "সময়" 24 | }, 25 | "nplurals=2; plural=(n != 1);"); 26 | -------------------------------------------------------------------------------- /l10n/bn_BD.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "No" : "না", 3 | "Yes" : "হ্যাঁ", 4 | "Shared with you" : "Shared with you", 5 | "Select groups" : "গ্রুপ নির্ধারণ", 6 | "Cancel" : "বাতিল করুন", 7 | "Delete" : "মুছে", 8 | "Other" : "অন্যান্য", 9 | "Set expiration date" : "মেয়াদোত্তীর্ণ হওয়ার তারিখ নির্ধারণ করুন", 10 | "Group" : "গোষ্ঠীসমূহ", 11 | "Share link" : "লিংক ভাগাভাগি করেন", 12 | "Edit" : "সম্পাদনা", 13 | "Share" : "ভাগাভাগি কর", 14 | "Description" : "বিবরণ", 15 | "Download" : "ডাউনলোড", 16 | "Search" : "Search", 17 | "Sharing" : "ভাগাভাগিরত", 18 | "Settings" : "সেটিংস", 19 | "Abort" : "বাতিল কর", 20 | "Date" : "Date", 21 | "Time" : "সময়" 22 | },"pluralForm" :"nplurals=2; plural=(n != 1);" 23 | } -------------------------------------------------------------------------------- /l10n/br.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "forms", 3 | { 4 | "No" : "Ket", 5 | "Copy" : "Eilañ", 6 | "Shared with you" : "Rannet ganeoc'h", 7 | "Select groups" : "Choaz ar strolladoù", 8 | "Cancel" : "Nullañ", 9 | "Delete" : "Dilemel", 10 | "Uploading …" : "O pellgas ...", 11 | "Set expiration date" : "Lakaat un deizat termen", 12 | "Group" : "Stollad", 13 | "Share link" : "Lodañ al liamm", 14 | "Add link" : "Ouzhpnna ul liamm", 15 | "Copy embedding code" : "Eilañ ar c'hod enframmañ", 16 | "View" : "Gwell", 17 | "Edit" : "Cheñch", 18 | "Share" : "Rannan", 19 | "Description" : "Diskrivadur", 20 | "Summary" : "Diverrañ", 21 | "Download" : "Pellgargañ", 22 | "Search" : "Klask", 23 | "Sharing" : "Rannan", 24 | "Settings" : "Arventennoù", 25 | "Submit" : "Kinnig", 26 | "Clear" : "Netaat", 27 | "File" : "Restr", 28 | "Date" : "Deiz", 29 | "Presentation" : "Kinnigadenn", 30 | "Text" : "Testenn", 31 | "Phone number" : "Niverenn bellgomz" 32 | }, 33 | "nplurals=5; plural=((n%10 == 1) && (n%100 != 11) && (n%100 !=71) && (n%100 !=91) ? 0 :(n%10 == 2) && (n%100 != 12) && (n%100 !=72) && (n%100 !=92) ? 1 :(n%10 ==3 || n%10==4 || n%10==9) && (n%100 < 10 || n% 100 > 19) && (n%100 < 70 || n%100 > 79) && (n%100 < 90 || n%100 > 99) ? 2 :(n != 0 && n % 1000000 == 0) ? 3 : 4);"); 34 | -------------------------------------------------------------------------------- /l10n/br.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "No" : "Ket", 3 | "Copy" : "Eilañ", 4 | "Shared with you" : "Rannet ganeoc'h", 5 | "Select groups" : "Choaz ar strolladoù", 6 | "Cancel" : "Nullañ", 7 | "Delete" : "Dilemel", 8 | "Uploading …" : "O pellgas ...", 9 | "Set expiration date" : "Lakaat un deizat termen", 10 | "Group" : "Stollad", 11 | "Share link" : "Lodañ al liamm", 12 | "Add link" : "Ouzhpnna ul liamm", 13 | "Copy embedding code" : "Eilañ ar c'hod enframmañ", 14 | "View" : "Gwell", 15 | "Edit" : "Cheñch", 16 | "Share" : "Rannan", 17 | "Description" : "Diskrivadur", 18 | "Summary" : "Diverrañ", 19 | "Download" : "Pellgargañ", 20 | "Search" : "Klask", 21 | "Sharing" : "Rannan", 22 | "Settings" : "Arventennoù", 23 | "Submit" : "Kinnig", 24 | "Clear" : "Netaat", 25 | "File" : "Restr", 26 | "Date" : "Deiz", 27 | "Presentation" : "Kinnigadenn", 28 | "Text" : "Testenn", 29 | "Phone number" : "Niverenn bellgomz" 30 | },"pluralForm" :"nplurals=5; plural=((n%10 == 1) && (n%100 != 11) && (n%100 !=71) && (n%100 !=91) ? 0 :(n%10 == 2) && (n%100 != 12) && (n%100 !=72) && (n%100 !=92) ? 1 :(n%10 ==3 || n%10==4 || n%10==9) && (n%100 < 10 || n% 100 > 19) && (n%100 < 70 || n%100 > 79) && (n%100 < 90 || n%100 > 99) ? 2 :(n != 0 && n % 1000000 == 0) ? 3 : 4);" 31 | } -------------------------------------------------------------------------------- /l10n/bs.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "forms", 3 | { 4 | "No" : "Ne", 5 | "Yes" : "Da", 6 | "Shared with you" : "Shared with you", 7 | "Cancel" : "Odustani", 8 | "Delete" : "Obriši", 9 | "Other" : "Ostali", 10 | "Set expiration date" : "Postavite datum isteka", 11 | "Group" : "Grupa", 12 | "Share link" : "Podijelite vezu", 13 | "Edit" : "Izmjeni", 14 | "Share" : "Podjeli", 15 | "Description" : "Opis", 16 | "Download" : "Preuzmi", 17 | "Search" : "Search", 18 | "Sharing" : "Dijeljenje", 19 | "Settings" : "Podešavanje", 20 | "Date" : "Date" 21 | }, 22 | "nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);"); 23 | -------------------------------------------------------------------------------- /l10n/bs.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "No" : "Ne", 3 | "Yes" : "Da", 4 | "Shared with you" : "Shared with you", 5 | "Cancel" : "Odustani", 6 | "Delete" : "Obriši", 7 | "Other" : "Ostali", 8 | "Set expiration date" : "Postavite datum isteka", 9 | "Group" : "Grupa", 10 | "Share link" : "Podijelite vezu", 11 | "Edit" : "Izmjeni", 12 | "Share" : "Podjeli", 13 | "Description" : "Opis", 14 | "Download" : "Preuzmi", 15 | "Search" : "Search", 16 | "Sharing" : "Dijeljenje", 17 | "Settings" : "Podešavanje", 18 | "Date" : "Date" 19 | },"pluralForm" :"nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);" 20 | } -------------------------------------------------------------------------------- /l10n/cy_GB.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "forms", 3 | { 4 | "No" : "Na", 5 | "Yes" : "Ie", 6 | "Copy" : "Copïo", 7 | "Shared with you" : "Shared with you", 8 | "Required" : "Angen", 9 | "Delete" : "Dileu", 10 | "Other" : "Arall", 11 | "Set expiration date" : "Gosod dyddiad dod i ben", 12 | "Group" : "Grŵp", 13 | "Share link" : "Rhannu dolen", 14 | "Copy embedding code" : "Copïo cod mewnosod", 15 | "View" : "Golwg", 16 | "Edit" : "Golygu", 17 | "Share" : "Rhannu", 18 | "Description" : "Disgrifiad", 19 | "Summary" : "Crynodeb", 20 | "Download" : "Llwytho i lawr", 21 | "Search" : "Chwilio", 22 | "Settings" : "Gosodiadau", 23 | "Date" : "Date", 24 | "Pick a date" : "Dewiswch ddyddiad", 25 | "Time" : "Amser", 26 | "Pick a time" : "Dewiswch amser", 27 | "Presentation" : "Cyflwyniad", 28 | "Email address" : "Cyfeiriad e-bost" 29 | }, 30 | "nplurals=4; plural=(n==1) ? 0 : (n==2) ? 1 : (n != 8 && n != 11) ? 2 : 3;"); 31 | -------------------------------------------------------------------------------- /l10n/cy_GB.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "No" : "Na", 3 | "Yes" : "Ie", 4 | "Copy" : "Copïo", 5 | "Shared with you" : "Shared with you", 6 | "Required" : "Angen", 7 | "Delete" : "Dileu", 8 | "Other" : "Arall", 9 | "Set expiration date" : "Gosod dyddiad dod i ben", 10 | "Group" : "Grŵp", 11 | "Share link" : "Rhannu dolen", 12 | "Copy embedding code" : "Copïo cod mewnosod", 13 | "View" : "Golwg", 14 | "Edit" : "Golygu", 15 | "Share" : "Rhannu", 16 | "Description" : "Disgrifiad", 17 | "Summary" : "Crynodeb", 18 | "Download" : "Llwytho i lawr", 19 | "Search" : "Chwilio", 20 | "Settings" : "Gosodiadau", 21 | "Date" : "Date", 22 | "Pick a date" : "Dewiswch ddyddiad", 23 | "Time" : "Amser", 24 | "Pick a time" : "Dewiswch amser", 25 | "Presentation" : "Cyflwyniad", 26 | "Email address" : "Cyfeiriad e-bost" 27 | },"pluralForm" :"nplurals=4; plural=(n==1) ? 0 : (n==2) ? 1 : (n != 8 && n != 11) ? 2 : 3;" 28 | } -------------------------------------------------------------------------------- /l10n/eo.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "forms", 3 | { 4 | "No" : "Ne", 5 | "Yes" : "Jes", 6 | "Copy" : "Kopii", 7 | "Shared with you" : "Kunhavata kun vi", 8 | "Select groups" : "Elekti grupojn", 9 | "Required" : "Nepra", 10 | "Maximum file size" : "Maksimuma dosiergrando", 11 | "Delete" : "Forigi", 12 | "Uploading …" : "Alŝutado…", 13 | "Other" : "Alia", 14 | "Set expiration date" : "Uzi limdaton", 15 | "Group" : "Grupo", 16 | "Share link" : "Kunhavigi ligilon", 17 | "Add link" : "Aldoni ligilon", 18 | "Copy to clipboard" : "Kopii tondejen", 19 | "Internal link" : "Interna ligilo", 20 | "View" : "Vidi", 21 | "Edit" : "Modifi", 22 | "View mode" : "Vida reĝimo", 23 | "Share" : "Kunhavigi", 24 | "Description" : "Priskribo", 25 | "Summary" : "Resumo", 26 | "Download" : "Elŝuti", 27 | "Search" : "Serĉi", 28 | "Sharing" : "Kunhavigo", 29 | "Settings" : "Agordoj", 30 | "Submit" : "Sendi", 31 | "Clear" : "Viŝi", 32 | "Cannot copy, please copy the link manually" : "Ne eblis kopii la ligilon; kopiu ĝin permane.", 33 | "No recommendations. Start typing." : "Neniu propono. Ektajpu.", 34 | "No elements found." : "Nenio trovita.", 35 | "File" : "Dosiero", 36 | "Date" : "Date", 37 | "Time" : "Dato", 38 | "Text" : "Teksto", 39 | "Phone number" : "Telefonnumero", 40 | "Email address" : "Retpoŝtadreso" 41 | }, 42 | "nplurals=2; plural=(n != 1);"); 43 | -------------------------------------------------------------------------------- /l10n/eo.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "No" : "Ne", 3 | "Yes" : "Jes", 4 | "Copy" : "Kopii", 5 | "Shared with you" : "Kunhavata kun vi", 6 | "Select groups" : "Elekti grupojn", 7 | "Required" : "Nepra", 8 | "Maximum file size" : "Maksimuma dosiergrando", 9 | "Delete" : "Forigi", 10 | "Uploading …" : "Alŝutado…", 11 | "Other" : "Alia", 12 | "Set expiration date" : "Uzi limdaton", 13 | "Group" : "Grupo", 14 | "Share link" : "Kunhavigi ligilon", 15 | "Add link" : "Aldoni ligilon", 16 | "Copy to clipboard" : "Kopii tondejen", 17 | "Internal link" : "Interna ligilo", 18 | "View" : "Vidi", 19 | "Edit" : "Modifi", 20 | "View mode" : "Vida reĝimo", 21 | "Share" : "Kunhavigi", 22 | "Description" : "Priskribo", 23 | "Summary" : "Resumo", 24 | "Download" : "Elŝuti", 25 | "Search" : "Serĉi", 26 | "Sharing" : "Kunhavigo", 27 | "Settings" : "Agordoj", 28 | "Submit" : "Sendi", 29 | "Clear" : "Viŝi", 30 | "Cannot copy, please copy the link manually" : "Ne eblis kopii la ligilon; kopiu ĝin permane.", 31 | "No recommendations. Start typing." : "Neniu propono. Ektajpu.", 32 | "No elements found." : "Nenio trovita.", 33 | "File" : "Dosiero", 34 | "Date" : "Date", 35 | "Time" : "Dato", 36 | "Text" : "Teksto", 37 | "Phone number" : "Telefonnumero", 38 | "Email address" : "Retpoŝtadreso" 39 | },"pluralForm" :"nplurals=2; plural=(n != 1);" 40 | } -------------------------------------------------------------------------------- /l10n/es_419.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "forms", 3 | { 4 | "Yes" : "Si", 5 | "Copy" : "Copiar", 6 | "Shared with you" : "Compartido con usted", 7 | "Select groups" : "Seleccionar grupos", 8 | "Required" : "Requerido", 9 | "Delete" : "Borrar", 10 | "Uploading …" : "Cargando...", 11 | "Set expiration date" : "Establecer fecha de expiración", 12 | "Group" : "Grupo", 13 | "Permissions" : "Permisos", 14 | "Share link" : "Compartir liga", 15 | "Copy to clipboard" : "Copiar al portapapeles", 16 | "Edit" : "Editar", 17 | "Share" : "Compartir", 18 | "Description" : "Descripción", 19 | "Summary" : "Resumen", 20 | "Download" : "Descargar", 21 | "Search" : "Buscar", 22 | "Sharing" : "Compartiendo", 23 | "Settings" : "Configuraciones ", 24 | "Abort" : "Abortar", 25 | "Submit" : "Enviar", 26 | "File" : "Archivo", 27 | "Date" : "Fecha", 28 | "Time" : "Hora", 29 | "Text" : "Texto", 30 | "Phone number" : "Número telefónico" 31 | }, 32 | "nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"); 33 | -------------------------------------------------------------------------------- /l10n/es_419.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "Yes" : "Si", 3 | "Copy" : "Copiar", 4 | "Shared with you" : "Compartido con usted", 5 | "Select groups" : "Seleccionar grupos", 6 | "Required" : "Requerido", 7 | "Delete" : "Borrar", 8 | "Uploading …" : "Cargando...", 9 | "Set expiration date" : "Establecer fecha de expiración", 10 | "Group" : "Grupo", 11 | "Permissions" : "Permisos", 12 | "Share link" : "Compartir liga", 13 | "Copy to clipboard" : "Copiar al portapapeles", 14 | "Edit" : "Editar", 15 | "Share" : "Compartir", 16 | "Description" : "Descripción", 17 | "Summary" : "Resumen", 18 | "Download" : "Descargar", 19 | "Search" : "Buscar", 20 | "Sharing" : "Compartiendo", 21 | "Settings" : "Configuraciones ", 22 | "Abort" : "Abortar", 23 | "Submit" : "Enviar", 24 | "File" : "Archivo", 25 | "Date" : "Fecha", 26 | "Time" : "Hora", 27 | "Text" : "Texto", 28 | "Phone number" : "Número telefónico" 29 | },"pluralForm" :"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;" 30 | } -------------------------------------------------------------------------------- /l10n/es_CL.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "forms", 3 | { 4 | "Yes" : "Si", 5 | "Copy" : "Copiar", 6 | "Shared with you" : "Compartido con usted", 7 | "Select groups" : "Seleccionar grupos", 8 | "Required" : "Requerido", 9 | "Delete" : "Borrar", 10 | "Uploading …" : "Cargando...", 11 | "Other" : "Otro", 12 | "Set expiration date" : "Establecer fecha de expiración", 13 | "Group" : "Grupo", 14 | "Permissions" : "Permisos", 15 | "Share link" : "Compartir liga", 16 | "Copy to clipboard" : "Copiar al portapapeles", 17 | "Edit" : "Editar", 18 | "View mode" : "Modo de visualización", 19 | "Share" : "Compartir", 20 | "Description" : "Descripción", 21 | "Summary" : "Resumen", 22 | "Download" : "Descargar", 23 | "Search" : "Buscar", 24 | "Sharing" : "Compartiendo", 25 | "Settings" : "Configuraciones ", 26 | "Abort" : "Abortar", 27 | "Submit" : "Enviar", 28 | "Clear" : "Limpiar", 29 | "File" : "Archivo", 30 | "Date" : "Fecha", 31 | "Time" : "Hora", 32 | "Text" : "Texto", 33 | "Phone number" : "Número telefónico" 34 | }, 35 | "nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"); 36 | -------------------------------------------------------------------------------- /l10n/es_CL.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "Yes" : "Si", 3 | "Copy" : "Copiar", 4 | "Shared with you" : "Compartido con usted", 5 | "Select groups" : "Seleccionar grupos", 6 | "Required" : "Requerido", 7 | "Delete" : "Borrar", 8 | "Uploading …" : "Cargando...", 9 | "Other" : "Otro", 10 | "Set expiration date" : "Establecer fecha de expiración", 11 | "Group" : "Grupo", 12 | "Permissions" : "Permisos", 13 | "Share link" : "Compartir liga", 14 | "Copy to clipboard" : "Copiar al portapapeles", 15 | "Edit" : "Editar", 16 | "View mode" : "Modo de visualización", 17 | "Share" : "Compartir", 18 | "Description" : "Descripción", 19 | "Summary" : "Resumen", 20 | "Download" : "Descargar", 21 | "Search" : "Buscar", 22 | "Sharing" : "Compartiendo", 23 | "Settings" : "Configuraciones ", 24 | "Abort" : "Abortar", 25 | "Submit" : "Enviar", 26 | "Clear" : "Limpiar", 27 | "File" : "Archivo", 28 | "Date" : "Fecha", 29 | "Time" : "Hora", 30 | "Text" : "Texto", 31 | "Phone number" : "Número telefónico" 32 | },"pluralForm" :"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;" 33 | } -------------------------------------------------------------------------------- /l10n/es_CO.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "forms", 3 | { 4 | "Copy" : "Copiar", 5 | "Shared with you" : "Compartido con usted", 6 | "Select groups" : "Seleccionar grupos", 7 | "Required" : "Requerido", 8 | "Delete" : "Borrar", 9 | "Uploading …" : "Cargando...", 10 | "Set expiration date" : "Establecer fecha de expiración", 11 | "Group" : "Grupo", 12 | "Permissions" : "Permisos", 13 | "Share link" : "Compartir enlace", 14 | "Copy to clipboard" : "Copiar al portapapeles", 15 | "Edit" : "Editar", 16 | "View mode" : "Modo de visualización", 17 | "Share" : "Compartir", 18 | "Description" : "Descripción", 19 | "Summary" : "Resumen", 20 | "Search" : "Buscar", 21 | "Sharing" : "Compartiendo", 22 | "Settings" : "Configuraciones ", 23 | "Abort" : "Abortar", 24 | "Submit" : "Enviar", 25 | "Clear" : "Limpiar", 26 | "File" : "Archivo", 27 | "Date" : "Fecha", 28 | "Time" : "Hora", 29 | "Text" : "Texto", 30 | "Phone number" : "Número de teléfono" 31 | }, 32 | "nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"); 33 | -------------------------------------------------------------------------------- /l10n/es_CO.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "Copy" : "Copiar", 3 | "Shared with you" : "Compartido con usted", 4 | "Select groups" : "Seleccionar grupos", 5 | "Required" : "Requerido", 6 | "Delete" : "Borrar", 7 | "Uploading …" : "Cargando...", 8 | "Set expiration date" : "Establecer fecha de expiración", 9 | "Group" : "Grupo", 10 | "Permissions" : "Permisos", 11 | "Share link" : "Compartir enlace", 12 | "Copy to clipboard" : "Copiar al portapapeles", 13 | "Edit" : "Editar", 14 | "View mode" : "Modo de visualización", 15 | "Share" : "Compartir", 16 | "Description" : "Descripción", 17 | "Summary" : "Resumen", 18 | "Search" : "Buscar", 19 | "Sharing" : "Compartiendo", 20 | "Settings" : "Configuraciones ", 21 | "Abort" : "Abortar", 22 | "Submit" : "Enviar", 23 | "Clear" : "Limpiar", 24 | "File" : "Archivo", 25 | "Date" : "Fecha", 26 | "Time" : "Hora", 27 | "Text" : "Texto", 28 | "Phone number" : "Número de teléfono" 29 | },"pluralForm" :"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;" 30 | } -------------------------------------------------------------------------------- /l10n/es_CR.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "forms", 3 | { 4 | "Copy" : "Copiar", 5 | "Shared with you" : "Compartido con usted", 6 | "Select groups" : "Seleccionar grupos", 7 | "Required" : "Requerido", 8 | "Delete" : "Borrar", 9 | "Uploading …" : "Cargando...", 10 | "Set expiration date" : "Establecer fecha de expiración", 11 | "Group" : "Grupo", 12 | "Permissions" : "Permisos", 13 | "Share link" : "Compartir liga", 14 | "Copy to clipboard" : "Copiar al portapapeles", 15 | "Edit" : "Editar", 16 | "View mode" : "Modo de visualización", 17 | "Share" : "Compartir", 18 | "Description" : "Descripción", 19 | "Summary" : "Resumen", 20 | "Search" : "Buscar", 21 | "Sharing" : "Compartiendo", 22 | "Settings" : "Configuraciones ", 23 | "Abort" : "Abortar", 24 | "Submit" : "Enviar", 25 | "Clear" : "Limpiar", 26 | "File" : "Archivo", 27 | "Date" : "Fecha", 28 | "Time" : "Hora", 29 | "Text" : "Texto", 30 | "Phone number" : "Número de teléfono" 31 | }, 32 | "nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"); 33 | -------------------------------------------------------------------------------- /l10n/es_CR.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "Copy" : "Copiar", 3 | "Shared with you" : "Compartido con usted", 4 | "Select groups" : "Seleccionar grupos", 5 | "Required" : "Requerido", 6 | "Delete" : "Borrar", 7 | "Uploading …" : "Cargando...", 8 | "Set expiration date" : "Establecer fecha de expiración", 9 | "Group" : "Grupo", 10 | "Permissions" : "Permisos", 11 | "Share link" : "Compartir liga", 12 | "Copy to clipboard" : "Copiar al portapapeles", 13 | "Edit" : "Editar", 14 | "View mode" : "Modo de visualización", 15 | "Share" : "Compartir", 16 | "Description" : "Descripción", 17 | "Summary" : "Resumen", 18 | "Search" : "Buscar", 19 | "Sharing" : "Compartiendo", 20 | "Settings" : "Configuraciones ", 21 | "Abort" : "Abortar", 22 | "Submit" : "Enviar", 23 | "Clear" : "Limpiar", 24 | "File" : "Archivo", 25 | "Date" : "Fecha", 26 | "Time" : "Hora", 27 | "Text" : "Texto", 28 | "Phone number" : "Número de teléfono" 29 | },"pluralForm" :"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;" 30 | } -------------------------------------------------------------------------------- /l10n/es_DO.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "forms", 3 | { 4 | "Copy" : "Copiar", 5 | "Shared with you" : "Compartido con usted", 6 | "Select groups" : "Seleccionar grupos", 7 | "Required" : "Requerido", 8 | "Delete" : "Borrar", 9 | "Uploading …" : "Cargando...", 10 | "Set expiration date" : "Establecer fecha de expiración", 11 | "Group" : "Grupo", 12 | "Permissions" : "Permisos", 13 | "Share link" : "Compartir liga", 14 | "Copy to clipboard" : "Copiar al portapapeles", 15 | "Edit" : "Editar", 16 | "View mode" : "Modo de visualización", 17 | "Share" : "Compartir", 18 | "Description" : "Descripción", 19 | "Summary" : "Resumen", 20 | "Download" : "Descargar", 21 | "Search" : "Buscar", 22 | "Sharing" : "Compartiendo", 23 | "Settings" : "Configuraciones ", 24 | "Abort" : "Abortar", 25 | "Submit" : "Enviar", 26 | "Clear" : "Limpiar", 27 | "File" : "Archivo", 28 | "Date" : "Fecha", 29 | "Time" : "Hora", 30 | "Text" : "Texto", 31 | "Phone number" : "Número de teléfono" 32 | }, 33 | "nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"); 34 | -------------------------------------------------------------------------------- /l10n/es_DO.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "Copy" : "Copiar", 3 | "Shared with you" : "Compartido con usted", 4 | "Select groups" : "Seleccionar grupos", 5 | "Required" : "Requerido", 6 | "Delete" : "Borrar", 7 | "Uploading …" : "Cargando...", 8 | "Set expiration date" : "Establecer fecha de expiración", 9 | "Group" : "Grupo", 10 | "Permissions" : "Permisos", 11 | "Share link" : "Compartir liga", 12 | "Copy to clipboard" : "Copiar al portapapeles", 13 | "Edit" : "Editar", 14 | "View mode" : "Modo de visualización", 15 | "Share" : "Compartir", 16 | "Description" : "Descripción", 17 | "Summary" : "Resumen", 18 | "Download" : "Descargar", 19 | "Search" : "Buscar", 20 | "Sharing" : "Compartiendo", 21 | "Settings" : "Configuraciones ", 22 | "Abort" : "Abortar", 23 | "Submit" : "Enviar", 24 | "Clear" : "Limpiar", 25 | "File" : "Archivo", 26 | "Date" : "Fecha", 27 | "Time" : "Hora", 28 | "Text" : "Texto", 29 | "Phone number" : "Número de teléfono" 30 | },"pluralForm" :"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;" 31 | } -------------------------------------------------------------------------------- /l10n/es_GT.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "forms", 3 | { 4 | "Copy" : "Copiar", 5 | "Shared with you" : "Compartido con usted", 6 | "Select groups" : "Seleccionar grupos", 7 | "Required" : "Requerido", 8 | "Delete" : "Borrar", 9 | "Uploading …" : "Cargando...", 10 | "Set expiration date" : "Establecer fecha de expiración", 11 | "Group" : "Grupo", 12 | "Permissions" : "Permisos", 13 | "Share link" : "Compartir liga", 14 | "Copy to clipboard" : "Copiar al portapapeles", 15 | "Edit" : "Editar", 16 | "View mode" : "Modo de visualización", 17 | "Share" : "Compartir", 18 | "Description" : "Descripción", 19 | "Summary" : "Resumen", 20 | "Download" : "Descargar", 21 | "Search" : "Buscar", 22 | "Sharing" : "Compartiendo", 23 | "Settings" : "Configuraciones ", 24 | "Abort" : "Abortar", 25 | "Submit" : "Enviar", 26 | "Clear" : "Limpiar", 27 | "File" : "Archivo", 28 | "Date" : "Fecha", 29 | "Time" : "Hora", 30 | "Text" : "Texto", 31 | "Phone number" : "Número telefónico", 32 | "Email address" : "Dirección de correo electrónico" 33 | }, 34 | "nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"); 35 | -------------------------------------------------------------------------------- /l10n/es_GT.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "Copy" : "Copiar", 3 | "Shared with you" : "Compartido con usted", 4 | "Select groups" : "Seleccionar grupos", 5 | "Required" : "Requerido", 6 | "Delete" : "Borrar", 7 | "Uploading …" : "Cargando...", 8 | "Set expiration date" : "Establecer fecha de expiración", 9 | "Group" : "Grupo", 10 | "Permissions" : "Permisos", 11 | "Share link" : "Compartir liga", 12 | "Copy to clipboard" : "Copiar al portapapeles", 13 | "Edit" : "Editar", 14 | "View mode" : "Modo de visualización", 15 | "Share" : "Compartir", 16 | "Description" : "Descripción", 17 | "Summary" : "Resumen", 18 | "Download" : "Descargar", 19 | "Search" : "Buscar", 20 | "Sharing" : "Compartiendo", 21 | "Settings" : "Configuraciones ", 22 | "Abort" : "Abortar", 23 | "Submit" : "Enviar", 24 | "Clear" : "Limpiar", 25 | "File" : "Archivo", 26 | "Date" : "Fecha", 27 | "Time" : "Hora", 28 | "Text" : "Texto", 29 | "Phone number" : "Número telefónico", 30 | "Email address" : "Dirección de correo electrónico" 31 | },"pluralForm" :"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;" 32 | } -------------------------------------------------------------------------------- /l10n/es_HN.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "forms", 3 | { 4 | "Copy" : "Copiar", 5 | "Shared with you" : "Compartido con usted", 6 | "Select groups" : "Seleccionar grupos", 7 | "Required" : "Requerido", 8 | "Delete" : "Borrar", 9 | "Uploading …" : "Cargando...", 10 | "Other" : "Otro", 11 | "Set expiration date" : "Establecer fecha de expiración", 12 | "Group" : "Grupo", 13 | "Permissions" : "Permisos", 14 | "Share link" : "Compartir liga", 15 | "Copy to clipboard" : "Copiar al portapapeles", 16 | "Edit" : "Editar", 17 | "Share" : "Compartir", 18 | "Description" : "Descripción", 19 | "Summary" : "Resumen", 20 | "Download" : "Descargar", 21 | "Search" : "Buscar", 22 | "Sharing" : "Compartiendo", 23 | "Settings" : "Configuraciones ", 24 | "Abort" : "Abortar", 25 | "Submit" : "Enviar", 26 | "Clear" : "Limpiar", 27 | "File" : "Archivo", 28 | "Date" : "Fecha", 29 | "Time" : "Hora", 30 | "Text" : "Texto", 31 | "Phone number" : "Número telefónico" 32 | }, 33 | "nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"); 34 | -------------------------------------------------------------------------------- /l10n/es_HN.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "Copy" : "Copiar", 3 | "Shared with you" : "Compartido con usted", 4 | "Select groups" : "Seleccionar grupos", 5 | "Required" : "Requerido", 6 | "Delete" : "Borrar", 7 | "Uploading …" : "Cargando...", 8 | "Other" : "Otro", 9 | "Set expiration date" : "Establecer fecha de expiración", 10 | "Group" : "Grupo", 11 | "Permissions" : "Permisos", 12 | "Share link" : "Compartir liga", 13 | "Copy to clipboard" : "Copiar al portapapeles", 14 | "Edit" : "Editar", 15 | "Share" : "Compartir", 16 | "Description" : "Descripción", 17 | "Summary" : "Resumen", 18 | "Download" : "Descargar", 19 | "Search" : "Buscar", 20 | "Sharing" : "Compartiendo", 21 | "Settings" : "Configuraciones ", 22 | "Abort" : "Abortar", 23 | "Submit" : "Enviar", 24 | "Clear" : "Limpiar", 25 | "File" : "Archivo", 26 | "Date" : "Fecha", 27 | "Time" : "Hora", 28 | "Text" : "Texto", 29 | "Phone number" : "Número telefónico" 30 | },"pluralForm" :"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;" 31 | } -------------------------------------------------------------------------------- /l10n/es_NI.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "forms", 3 | { 4 | "Copy" : "Copiar", 5 | "Shared with you" : "Compartido con usted", 6 | "Select groups" : "Seleccionar grupos", 7 | "Required" : "Requerido", 8 | "Delete" : "Borrar", 9 | "Uploading …" : "Cargando...", 10 | "Set expiration date" : "Establecer fecha de expiración", 11 | "Group" : "Grupo", 12 | "Permissions" : "Permisos", 13 | "Share link" : "Compartir liga", 14 | "Copy to clipboard" : "Copiar al portapapeles", 15 | "Edit" : "Editar", 16 | "Share" : "Compartir", 17 | "Description" : "Descripción", 18 | "Summary" : "Resumen", 19 | "Download" : "Descargar", 20 | "Search" : "Buscar", 21 | "Sharing" : "Compartiendo", 22 | "Settings" : "Configuraciones ", 23 | "Abort" : "Abortar", 24 | "Submit" : "Enviar", 25 | "File" : "Archivo", 26 | "Date" : "Fecha", 27 | "Time" : "Hora", 28 | "Text" : "Texto", 29 | "Phone number" : "Número de teléfono" 30 | }, 31 | "nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"); 32 | -------------------------------------------------------------------------------- /l10n/es_NI.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "Copy" : "Copiar", 3 | "Shared with you" : "Compartido con usted", 4 | "Select groups" : "Seleccionar grupos", 5 | "Required" : "Requerido", 6 | "Delete" : "Borrar", 7 | "Uploading …" : "Cargando...", 8 | "Set expiration date" : "Establecer fecha de expiración", 9 | "Group" : "Grupo", 10 | "Permissions" : "Permisos", 11 | "Share link" : "Compartir liga", 12 | "Copy to clipboard" : "Copiar al portapapeles", 13 | "Edit" : "Editar", 14 | "Share" : "Compartir", 15 | "Description" : "Descripción", 16 | "Summary" : "Resumen", 17 | "Download" : "Descargar", 18 | "Search" : "Buscar", 19 | "Sharing" : "Compartiendo", 20 | "Settings" : "Configuraciones ", 21 | "Abort" : "Abortar", 22 | "Submit" : "Enviar", 23 | "File" : "Archivo", 24 | "Date" : "Fecha", 25 | "Time" : "Hora", 26 | "Text" : "Texto", 27 | "Phone number" : "Número de teléfono" 28 | },"pluralForm" :"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;" 29 | } -------------------------------------------------------------------------------- /l10n/es_PA.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "forms", 3 | { 4 | "Copy" : "Copiar", 5 | "Shared with you" : "Compartido con usted", 6 | "Select groups" : "Seleccionar grupos", 7 | "Required" : "Requerido", 8 | "Delete" : "Borrar", 9 | "Uploading …" : "Cargando...", 10 | "Set expiration date" : "Establecer fecha de expiración", 11 | "Group" : "Grupo", 12 | "Permissions" : "Permisos", 13 | "Share link" : "Compartir liga", 14 | "Copy to clipboard" : "Copiar al portapapeles", 15 | "Edit" : "Editar", 16 | "Share" : "Compartir", 17 | "Description" : "Descripción", 18 | "Summary" : "Resumen", 19 | "Download" : "Descargar", 20 | "Search" : "Buscar", 21 | "Sharing" : "Compartiendo", 22 | "Settings" : "Configuraciones ", 23 | "Abort" : "Abortar", 24 | "Submit" : "Enviar", 25 | "File" : "Archivo", 26 | "Date" : "Fecha", 27 | "Time" : "Hora", 28 | "Text" : "Texto", 29 | "Phone number" : "Número telefónico" 30 | }, 31 | "nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"); 32 | -------------------------------------------------------------------------------- /l10n/es_PA.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "Copy" : "Copiar", 3 | "Shared with you" : "Compartido con usted", 4 | "Select groups" : "Seleccionar grupos", 5 | "Required" : "Requerido", 6 | "Delete" : "Borrar", 7 | "Uploading …" : "Cargando...", 8 | "Set expiration date" : "Establecer fecha de expiración", 9 | "Group" : "Grupo", 10 | "Permissions" : "Permisos", 11 | "Share link" : "Compartir liga", 12 | "Copy to clipboard" : "Copiar al portapapeles", 13 | "Edit" : "Editar", 14 | "Share" : "Compartir", 15 | "Description" : "Descripción", 16 | "Summary" : "Resumen", 17 | "Download" : "Descargar", 18 | "Search" : "Buscar", 19 | "Sharing" : "Compartiendo", 20 | "Settings" : "Configuraciones ", 21 | "Abort" : "Abortar", 22 | "Submit" : "Enviar", 23 | "File" : "Archivo", 24 | "Date" : "Fecha", 25 | "Time" : "Hora", 26 | "Text" : "Texto", 27 | "Phone number" : "Número telefónico" 28 | },"pluralForm" :"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;" 29 | } -------------------------------------------------------------------------------- /l10n/es_PE.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "forms", 3 | { 4 | "Copy" : "Copiar", 5 | "Shared with you" : "Compartido con usted", 6 | "Select groups" : "Seleccionar grupos", 7 | "Required" : "Requerido", 8 | "Delete" : "Borrar", 9 | "Uploading …" : "Cargando...", 10 | "Other" : "Otro", 11 | "Set expiration date" : "Establecer fecha de expiración", 12 | "Group" : "Grupo", 13 | "Permissions" : "Permisos", 14 | "Share link" : "Compartir liga", 15 | "Copy to clipboard" : "Copiar al portapapeles", 16 | "Edit" : "Editar", 17 | "Share" : "Compartir", 18 | "Description" : "Descripción", 19 | "Summary" : "Resumen", 20 | "Download" : "Descargar", 21 | "Search" : "Buscar", 22 | "Sharing" : "Compartiendo", 23 | "Settings" : "Configuraciones ", 24 | "Abort" : "Abortar", 25 | "Submit" : "Enviar", 26 | "File" : "Archivo", 27 | "Date" : "Fecha", 28 | "Time" : "Hora", 29 | "Text" : "Texto", 30 | "Phone number" : "Número telefónico" 31 | }, 32 | "nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"); 33 | -------------------------------------------------------------------------------- /l10n/es_PE.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "Copy" : "Copiar", 3 | "Shared with you" : "Compartido con usted", 4 | "Select groups" : "Seleccionar grupos", 5 | "Required" : "Requerido", 6 | "Delete" : "Borrar", 7 | "Uploading …" : "Cargando...", 8 | "Other" : "Otro", 9 | "Set expiration date" : "Establecer fecha de expiración", 10 | "Group" : "Grupo", 11 | "Permissions" : "Permisos", 12 | "Share link" : "Compartir liga", 13 | "Copy to clipboard" : "Copiar al portapapeles", 14 | "Edit" : "Editar", 15 | "Share" : "Compartir", 16 | "Description" : "Descripción", 17 | "Summary" : "Resumen", 18 | "Download" : "Descargar", 19 | "Search" : "Buscar", 20 | "Sharing" : "Compartiendo", 21 | "Settings" : "Configuraciones ", 22 | "Abort" : "Abortar", 23 | "Submit" : "Enviar", 24 | "File" : "Archivo", 25 | "Date" : "Fecha", 26 | "Time" : "Hora", 27 | "Text" : "Texto", 28 | "Phone number" : "Número telefónico" 29 | },"pluralForm" :"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;" 30 | } -------------------------------------------------------------------------------- /l10n/es_PR.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "forms", 3 | { 4 | "Copy" : "Copiar", 5 | "Shared with you" : "Compartido con usted", 6 | "Select groups" : "Seleccionar grupos", 7 | "Required" : "Requerido", 8 | "Delete" : "Borrar", 9 | "Uploading …" : "Cargando...", 10 | "Set expiration date" : "Establecer fecha de expiración", 11 | "Group" : "Grupo", 12 | "Permissions" : "Permisos", 13 | "Share link" : "Compartir liga", 14 | "Copy to clipboard" : "Copiar al portapapeles", 15 | "Edit" : "Editar", 16 | "Share" : "Compartir", 17 | "Description" : "Descripción", 18 | "Summary" : "Resumen", 19 | "Download" : "Descargar", 20 | "Search" : "Buscar", 21 | "Sharing" : "Compartiendo", 22 | "Settings" : "Configuraciones ", 23 | "Abort" : "Abortar", 24 | "Submit" : "Enviar", 25 | "File" : "Archivo", 26 | "Date" : "Fecha", 27 | "Time" : "Hora", 28 | "Text" : "Texto", 29 | "Phone number" : "Número telefónico" 30 | }, 31 | "nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"); 32 | -------------------------------------------------------------------------------- /l10n/es_PR.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "Copy" : "Copiar", 3 | "Shared with you" : "Compartido con usted", 4 | "Select groups" : "Seleccionar grupos", 5 | "Required" : "Requerido", 6 | "Delete" : "Borrar", 7 | "Uploading …" : "Cargando...", 8 | "Set expiration date" : "Establecer fecha de expiración", 9 | "Group" : "Grupo", 10 | "Permissions" : "Permisos", 11 | "Share link" : "Compartir liga", 12 | "Copy to clipboard" : "Copiar al portapapeles", 13 | "Edit" : "Editar", 14 | "Share" : "Compartir", 15 | "Description" : "Descripción", 16 | "Summary" : "Resumen", 17 | "Download" : "Descargar", 18 | "Search" : "Buscar", 19 | "Sharing" : "Compartiendo", 20 | "Settings" : "Configuraciones ", 21 | "Abort" : "Abortar", 22 | "Submit" : "Enviar", 23 | "File" : "Archivo", 24 | "Date" : "Fecha", 25 | "Time" : "Hora", 26 | "Text" : "Texto", 27 | "Phone number" : "Número telefónico" 28 | },"pluralForm" :"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;" 29 | } -------------------------------------------------------------------------------- /l10n/es_PY.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "forms", 3 | { 4 | "Copy" : "Copiar", 5 | "Shared with you" : "Compartido con usted", 6 | "Select groups" : "Seleccionar grupos", 7 | "Required" : "Requerido", 8 | "Delete" : "Borrar", 9 | "Uploading …" : "Cargando...", 10 | "Set expiration date" : "Establecer fecha de expiración", 11 | "Group" : "Grupo", 12 | "Permissions" : "Permisos", 13 | "Share link" : "Compartir liga", 14 | "Copy to clipboard" : "Copiar al portapapeles", 15 | "Edit" : "Editar", 16 | "Share" : "Compartir", 17 | "Description" : "Descripción", 18 | "Summary" : "Resumen", 19 | "Download" : "Descargar", 20 | "Search" : "Buscar", 21 | "Sharing" : "Compartiendo", 22 | "Settings" : "Configuraciones ", 23 | "Abort" : "Abortar", 24 | "Submit" : "Enviar", 25 | "File" : "Archivo", 26 | "Date" : "Fecha", 27 | "Time" : "Hora", 28 | "Text" : "Texto", 29 | "Phone number" : "Número telefónico" 30 | }, 31 | "nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"); 32 | -------------------------------------------------------------------------------- /l10n/es_PY.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "Copy" : "Copiar", 3 | "Shared with you" : "Compartido con usted", 4 | "Select groups" : "Seleccionar grupos", 5 | "Required" : "Requerido", 6 | "Delete" : "Borrar", 7 | "Uploading …" : "Cargando...", 8 | "Set expiration date" : "Establecer fecha de expiración", 9 | "Group" : "Grupo", 10 | "Permissions" : "Permisos", 11 | "Share link" : "Compartir liga", 12 | "Copy to clipboard" : "Copiar al portapapeles", 13 | "Edit" : "Editar", 14 | "Share" : "Compartir", 15 | "Description" : "Descripción", 16 | "Summary" : "Resumen", 17 | "Download" : "Descargar", 18 | "Search" : "Buscar", 19 | "Sharing" : "Compartiendo", 20 | "Settings" : "Configuraciones ", 21 | "Abort" : "Abortar", 22 | "Submit" : "Enviar", 23 | "File" : "Archivo", 24 | "Date" : "Fecha", 25 | "Time" : "Hora", 26 | "Text" : "Texto", 27 | "Phone number" : "Número telefónico" 28 | },"pluralForm" :"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;" 29 | } -------------------------------------------------------------------------------- /l10n/es_SV.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "forms", 3 | { 4 | "Copy" : "Copiar", 5 | "Shared with you" : "Compartido con usted", 6 | "Select groups" : "Seleccionar grupos", 7 | "Required" : "Requerido", 8 | "Delete" : "Borrar", 9 | "Uploading …" : "Cargando...", 10 | "Set expiration date" : "Establecer fecha de expiración", 11 | "Group" : "Grupo", 12 | "Permissions" : "Permisos", 13 | "Share link" : "Compartir liga", 14 | "Copy to clipboard" : "Copiar al portapapeles", 15 | "Edit" : "Editar", 16 | "View mode" : "Modo de visualización", 17 | "Share" : "Compartir", 18 | "Description" : "Descripción", 19 | "Summary" : "Resumen", 20 | "Download" : "Descargar", 21 | "Search" : "Buscar", 22 | "Sharing" : "Compartiendo", 23 | "Settings" : "Configuraciones ", 24 | "Abort" : "Abortar", 25 | "Submit" : "Enviar", 26 | "Clear" : "Limpiar", 27 | "File" : "Archivo", 28 | "Date" : "Fecha", 29 | "Time" : "Hora", 30 | "Text" : "Texto", 31 | "Phone number" : "Número telefónico" 32 | }, 33 | "nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"); 34 | -------------------------------------------------------------------------------- /l10n/es_SV.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "Copy" : "Copiar", 3 | "Shared with you" : "Compartido con usted", 4 | "Select groups" : "Seleccionar grupos", 5 | "Required" : "Requerido", 6 | "Delete" : "Borrar", 7 | "Uploading …" : "Cargando...", 8 | "Set expiration date" : "Establecer fecha de expiración", 9 | "Group" : "Grupo", 10 | "Permissions" : "Permisos", 11 | "Share link" : "Compartir liga", 12 | "Copy to clipboard" : "Copiar al portapapeles", 13 | "Edit" : "Editar", 14 | "View mode" : "Modo de visualización", 15 | "Share" : "Compartir", 16 | "Description" : "Descripción", 17 | "Summary" : "Resumen", 18 | "Download" : "Descargar", 19 | "Search" : "Buscar", 20 | "Sharing" : "Compartiendo", 21 | "Settings" : "Configuraciones ", 22 | "Abort" : "Abortar", 23 | "Submit" : "Enviar", 24 | "Clear" : "Limpiar", 25 | "File" : "Archivo", 26 | "Date" : "Fecha", 27 | "Time" : "Hora", 28 | "Text" : "Texto", 29 | "Phone number" : "Número telefónico" 30 | },"pluralForm" :"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;" 31 | } -------------------------------------------------------------------------------- /l10n/es_UY.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "forms", 3 | { 4 | "Copy" : "Copiar", 5 | "Shared with you" : "Compartido con usted", 6 | "Select groups" : "Seleccionar grupos", 7 | "Required" : "Requerido", 8 | "Delete" : "Borrar", 9 | "Uploading …" : "Cargando...", 10 | "Set expiration date" : "Establecer fecha de expiración", 11 | "Group" : "Grupo", 12 | "Permissions" : "Permisos", 13 | "Share link" : "Compartir liga", 14 | "Copy to clipboard" : "Copiar al portapapeles", 15 | "Edit" : "Editar", 16 | "Share" : "Compartir", 17 | "Description" : "Descripción", 18 | "Summary" : "Resumen", 19 | "Download" : "Descargar", 20 | "Search" : "Buscar", 21 | "Sharing" : "Compartiendo", 22 | "Settings" : "Configuraciones ", 23 | "Abort" : "Abortar", 24 | "Submit" : "Enviar", 25 | "File" : "Archivo", 26 | "Date" : "Fecha", 27 | "Time" : "Hora", 28 | "Text" : "Texto", 29 | "Phone number" : "Número telefónico" 30 | }, 31 | "nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;"); 32 | -------------------------------------------------------------------------------- /l10n/es_UY.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "Copy" : "Copiar", 3 | "Shared with you" : "Compartido con usted", 4 | "Select groups" : "Seleccionar grupos", 5 | "Required" : "Requerido", 6 | "Delete" : "Borrar", 7 | "Uploading …" : "Cargando...", 8 | "Set expiration date" : "Establecer fecha de expiración", 9 | "Group" : "Grupo", 10 | "Permissions" : "Permisos", 11 | "Share link" : "Compartir liga", 12 | "Copy to clipboard" : "Copiar al portapapeles", 13 | "Edit" : "Editar", 14 | "Share" : "Compartir", 15 | "Description" : "Descripción", 16 | "Summary" : "Resumen", 17 | "Download" : "Descargar", 18 | "Search" : "Buscar", 19 | "Sharing" : "Compartiendo", 20 | "Settings" : "Configuraciones ", 21 | "Abort" : "Abortar", 22 | "Submit" : "Enviar", 23 | "File" : "Archivo", 24 | "Date" : "Fecha", 25 | "Time" : "Hora", 26 | "Text" : "Texto", 27 | "Phone number" : "Número telefónico" 28 | },"pluralForm" :"nplurals=3; plural=n == 1 ? 0 : n != 0 && n % 1000000 == 0 ? 1 : 2;" 29 | } -------------------------------------------------------------------------------- /l10n/hy.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "forms", 3 | { 4 | "No" : "Ոչ", 5 | "Yes" : "Այո", 6 | "Copy" : "պատճենահանել", 7 | "Shared with you" : "Shared with you", 8 | "Cancel" : "չեղարկել", 9 | "Delete" : "հեռացնել", 10 | "Other" : "Այլ", 11 | "Set expiration date" : "Սահմանել վավերականության ժամկետ", 12 | "Group" : "Խումբ", 13 | "Share link" : "Կիսվել հղմամբ", 14 | "Edit" : "մշակել", 15 | "Share" : "Կիսվել", 16 | "Description" : "Նկարագրություն", 17 | "Download" : "Ներբեռնել", 18 | "Search" : "Search", 19 | "Settings" : "կարգավորումներ", 20 | "Date" : "Date", 21 | "Time" : "Ժամ" 22 | }, 23 | "nplurals=2; plural=(n != 1);"); 24 | -------------------------------------------------------------------------------- /l10n/hy.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "No" : "Ոչ", 3 | "Yes" : "Այո", 4 | "Copy" : "պատճենահանել", 5 | "Shared with you" : "Shared with you", 6 | "Cancel" : "չեղարկել", 7 | "Delete" : "հեռացնել", 8 | "Other" : "Այլ", 9 | "Set expiration date" : "Սահմանել վավերականության ժամկետ", 10 | "Group" : "Խումբ", 11 | "Share link" : "Կիսվել հղմամբ", 12 | "Edit" : "մշակել", 13 | "Share" : "Կիսվել", 14 | "Description" : "Նկարագրություն", 15 | "Download" : "Ներբեռնել", 16 | "Search" : "Search", 17 | "Settings" : "կարգավորումներ", 18 | "Date" : "Date", 19 | "Time" : "Ժամ" 20 | },"pluralForm" :"nplurals=2; plural=(n != 1);" 21 | } -------------------------------------------------------------------------------- /l10n/ia.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "forms", 3 | { 4 | "Copy" : "Copiar", 5 | "Shared with you" : "Compartite con te", 6 | "Required" : "Requirite", 7 | "Delete" : "Deler", 8 | "Set expiration date" : "Assignar data de expiration", 9 | "Group" : "Gruppo", 10 | "Share link" : "Compartir ligamine", 11 | "View" : "Vider", 12 | "Edit" : "Modificar", 13 | "Share" : "Compartir", 14 | "Description" : "Description", 15 | "Summary" : "Summario", 16 | "Download" : "Discargar", 17 | "Search" : "Cercar", 18 | "Sharing" : "Compartente", 19 | "Settings" : "Configurationes", 20 | "Date" : "Date", 21 | "Time" : "Tempore", 22 | "Document" : "Documento", 23 | "Presentation" : "Presentation", 24 | "Spreadsheet" : "Folios de labor", 25 | "Phone number" : "Numero de telephono" 26 | }, 27 | "nplurals=2; plural=(n != 1);"); 28 | -------------------------------------------------------------------------------- /l10n/ia.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "Copy" : "Copiar", 3 | "Shared with you" : "Compartite con te", 4 | "Required" : "Requirite", 5 | "Delete" : "Deler", 6 | "Set expiration date" : "Assignar data de expiration", 7 | "Group" : "Gruppo", 8 | "Share link" : "Compartir ligamine", 9 | "View" : "Vider", 10 | "Edit" : "Modificar", 11 | "Share" : "Compartir", 12 | "Description" : "Description", 13 | "Summary" : "Summario", 14 | "Download" : "Discargar", 15 | "Search" : "Cercar", 16 | "Sharing" : "Compartente", 17 | "Settings" : "Configurationes", 18 | "Date" : "Date", 19 | "Time" : "Tempore", 20 | "Document" : "Documento", 21 | "Presentation" : "Presentation", 22 | "Spreadsheet" : "Folios de labor", 23 | "Phone number" : "Numero de telephono" 24 | },"pluralForm" :"nplurals=2; plural=(n != 1);" 25 | } -------------------------------------------------------------------------------- /l10n/id.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "forms", 3 | { 4 | "Copy" : "Salin", 5 | "Shared with you" : "Shared with you", 6 | "Select groups" : "Pilih grup", 7 | "Cancel" : "Batal", 8 | "Options" : "Pilihan", 9 | "Delete" : "Hapus", 10 | "Uploading …" : "Mengunggah …", 11 | "Other" : "Lainnya", 12 | "Set expiration date" : "Atur tanggal kedaluwarsa", 13 | "Group" : "Grup", 14 | "Share link" : "Bagikan tautan", 15 | "Add link" : "Tambah tautan", 16 | "Copy to clipboard" : "Salin ke papan klip", 17 | "Copy embedding code" : "Salin kode penyemat", 18 | "View" : "Tampilan", 19 | "Edit" : "Sunting", 20 | "Share" : "Bagikan", 21 | "Description" : "Deskrisi", 22 | "Summary" : "Kesimpulan", 23 | "Download" : "Unduh", 24 | "Search" : "Cari", 25 | "Sharing" : "Berbagi", 26 | "Settings" : "Setelan", 27 | "Abort" : "Batal", 28 | "Clear" : "Bersihkan", 29 | "No recommendations. Start typing." : "Tidak ada saran. Mulai mengetik.", 30 | "Checkboxes" : "Kotak centang", 31 | "Date" : "Date", 32 | "Pick a date" : "Pilih tanggal", 33 | "Time" : "Waktu", 34 | "Pick a time" : "Pilih waktu", 35 | "Image" : "Gambar", 36 | "Text" : "Teks", 37 | "Phone number" : "Nomor telefon", 38 | "Email address" : "Alamat surel" 39 | }, 40 | "nplurals=1; plural=0;"); 41 | -------------------------------------------------------------------------------- /l10n/id.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "Copy" : "Salin", 3 | "Shared with you" : "Shared with you", 4 | "Select groups" : "Pilih grup", 5 | "Cancel" : "Batal", 6 | "Options" : "Pilihan", 7 | "Delete" : "Hapus", 8 | "Uploading …" : "Mengunggah …", 9 | "Other" : "Lainnya", 10 | "Set expiration date" : "Atur tanggal kedaluwarsa", 11 | "Group" : "Grup", 12 | "Share link" : "Bagikan tautan", 13 | "Add link" : "Tambah tautan", 14 | "Copy to clipboard" : "Salin ke papan klip", 15 | "Copy embedding code" : "Salin kode penyemat", 16 | "View" : "Tampilan", 17 | "Edit" : "Sunting", 18 | "Share" : "Bagikan", 19 | "Description" : "Deskrisi", 20 | "Summary" : "Kesimpulan", 21 | "Download" : "Unduh", 22 | "Search" : "Cari", 23 | "Sharing" : "Berbagi", 24 | "Settings" : "Setelan", 25 | "Abort" : "Batal", 26 | "Clear" : "Bersihkan", 27 | "No recommendations. Start typing." : "Tidak ada saran. Mulai mengetik.", 28 | "Checkboxes" : "Kotak centang", 29 | "Date" : "Date", 30 | "Pick a date" : "Pilih tanggal", 31 | "Time" : "Waktu", 32 | "Pick a time" : "Pilih waktu", 33 | "Image" : "Gambar", 34 | "Text" : "Teks", 35 | "Phone number" : "Nomor telefon", 36 | "Email address" : "Alamat surel" 37 | },"pluralForm" :"nplurals=1; plural=0;" 38 | } -------------------------------------------------------------------------------- /l10n/ka.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "No" : "No", 3 | "Yes" : "Yes", 4 | "Question" : "Question", 5 | "Copy" : "Copy", 6 | "Shared with you" : "Shared with you", 7 | "Select groups" : "Select groups", 8 | "Results" : "შედეგი", 9 | "Cancel" : "Cancel", 10 | "Go to previous page" : "Go to previous page", 11 | "Delete" : "Delete", 12 | "Uploading …" : "Uploading …", 13 | "Other" : "Other", 14 | "Set expiration date" : "Set expiration date", 15 | "Group" : "Group", 16 | "Permissions" : "Permissions", 17 | "Share link" : "Share link", 18 | "Copy to clipboard" : "Copy to clipboard", 19 | "Copy embedding code" : "Copy embedding code", 20 | "Internal link" : "Internal link", 21 | "View" : "View", 22 | "Edit" : "Edit", 23 | "Share" : "Share", 24 | "Description" : "Description", 25 | "Summary" : "Summary", 26 | "Download" : "Download", 27 | "Search" : "ძიება", 28 | "No results found" : "No results found", 29 | "Sharing" : "Sharing", 30 | "Settings" : "Settings", 31 | "Abort" : "Abort", 32 | "Submit" : "Submit", 33 | "Clear" : "Clear", 34 | "Cannot copy, please copy the link manually" : "Cannot copy, please copy the link manually", 35 | "No recommendations. Start typing." : "No recommendations. Start typing.", 36 | "No elements found." : "No elements found.", 37 | "Checkboxes" : "Checkboxes", 38 | "File" : "File", 39 | "Date" : "Date", 40 | "Pick a date" : "Pick a date", 41 | "Time" : "Time", 42 | "Pick a time" : "Pick a time", 43 | "Image" : "Image", 44 | "Presentation" : "Presentation", 45 | "Text" : "Text", 46 | "Phone number" : "Phone number", 47 | "Email address" : "Email address" 48 | },"pluralForm" :"nplurals=2; plural=(n!=1);" 49 | } -------------------------------------------------------------------------------- /l10n/ka_GE.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "forms", 3 | { 4 | "Yes" : "დიახ", 5 | "Copy" : "კოპირება", 6 | "Shared with you" : "გაზიარებული თქვენთან", 7 | "Select groups" : "ჯგუფების არჩევა", 8 | "Cancel" : "გაუქმება", 9 | "Required" : "სავალდებულო", 10 | "Delete" : "წაშლა", 11 | "Uploading …" : "იტვირთება ...", 12 | "Other" : "სხვა", 13 | "Set expiration date" : "მიუთითეთ ვადის გასვლის დრო", 14 | "Group" : "ჯგუფი", 15 | "Permissions" : "უფლებები", 16 | "Share link" : "ბმულის გაზიარება", 17 | "Copy to clipboard" : "კოპირება ბუფერში", 18 | "Edit" : "შეცვლა", 19 | "Share" : "გაზიარება", 20 | "Description" : "აღწერილობა", 21 | "Summary" : "შეჯამება", 22 | "Download" : "ჩამოტვირთვა", 23 | "Search" : "ძიება", 24 | "Sharing" : "გაზიარება", 25 | "Settings" : "პარამეტრები", 26 | "Abort" : "შეჩერება", 27 | "Submit" : "გაგზავნა", 28 | "Clear" : "გასუფთავება", 29 | "File" : "ფაილი", 30 | "Date" : "თარიღი", 31 | "Time" : "დრო", 32 | "Text" : "ტექსტი", 33 | "Phone number" : "ტელეფონის ნომერი" 34 | }, 35 | "nplurals=2; plural=(n!=1);"); 36 | -------------------------------------------------------------------------------- /l10n/ka_GE.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "Yes" : "დიახ", 3 | "Copy" : "კოპირება", 4 | "Shared with you" : "გაზიარებული თქვენთან", 5 | "Select groups" : "ჯგუფების არჩევა", 6 | "Cancel" : "გაუქმება", 7 | "Required" : "სავალდებულო", 8 | "Delete" : "წაშლა", 9 | "Uploading …" : "იტვირთება ...", 10 | "Other" : "სხვა", 11 | "Set expiration date" : "მიუთითეთ ვადის გასვლის დრო", 12 | "Group" : "ჯგუფი", 13 | "Permissions" : "უფლებები", 14 | "Share link" : "ბმულის გაზიარება", 15 | "Copy to clipboard" : "კოპირება ბუფერში", 16 | "Edit" : "შეცვლა", 17 | "Share" : "გაზიარება", 18 | "Description" : "აღწერილობა", 19 | "Summary" : "შეჯამება", 20 | "Download" : "ჩამოტვირთვა", 21 | "Search" : "ძიება", 22 | "Sharing" : "გაზიარება", 23 | "Settings" : "პარამეტრები", 24 | "Abort" : "შეჩერება", 25 | "Submit" : "გაგზავნა", 26 | "Clear" : "გასუფთავება", 27 | "File" : "ფაილი", 28 | "Date" : "თარიღი", 29 | "Time" : "დრო", 30 | "Text" : "ტექსტი", 31 | "Phone number" : "ტელეფონის ნომერი" 32 | },"pluralForm" :"nplurals=2; plural=(n!=1);" 33 | } -------------------------------------------------------------------------------- /l10n/kab.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "forms", 3 | { 4 | "No" : "Uhu", 5 | "Yes" : "Oui", 6 | "Question" : "Asteqsi", 7 | "Copy" : "Nɣel", 8 | "Results" : "Igmaḍ", 9 | "Options" : "Iɣewwaṛen", 10 | "Delete" : "Kkes", 11 | "Other" : "Wayeḍ", 12 | "Group" : "Agraw", 13 | "Share link" : "Fren aseɣwen", 14 | "Copy to clipboard" : "Copier dans le presse-papiers", 15 | "Edit" : "Ẓreg", 16 | "Share" : "Bḍu", 17 | "Download" : "Sider", 18 | "Search" : "Nadi", 19 | "Sharing" : "Beṭṭu", 20 | "Settings" : "Iɣewwaṛen", 21 | "File" : "Afaylu", 22 | "Phone number" : "Uṭṭun n tiliɣri", 23 | "Email address" : "Tansa imayl" 24 | }, 25 | "nplurals=2; plural=(n != 1);"); 26 | -------------------------------------------------------------------------------- /l10n/kab.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "No" : "Uhu", 3 | "Yes" : "Oui", 4 | "Question" : "Asteqsi", 5 | "Copy" : "Nɣel", 6 | "Results" : "Igmaḍ", 7 | "Options" : "Iɣewwaṛen", 8 | "Delete" : "Kkes", 9 | "Other" : "Wayeḍ", 10 | "Group" : "Agraw", 11 | "Share link" : "Fren aseɣwen", 12 | "Copy to clipboard" : "Copier dans le presse-papiers", 13 | "Edit" : "Ẓreg", 14 | "Share" : "Bḍu", 15 | "Download" : "Sider", 16 | "Search" : "Nadi", 17 | "Sharing" : "Beṭṭu", 18 | "Settings" : "Iɣewwaṛen", 19 | "File" : "Afaylu", 20 | "Phone number" : "Uṭṭun n tiliɣri", 21 | "Email address" : "Tansa imayl" 22 | },"pluralForm" :"nplurals=2; plural=(n != 1);" 23 | } -------------------------------------------------------------------------------- /l10n/km.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "forms", 3 | { 4 | "No" : "ទេ", 5 | "Yes" : "បាទ ឬចាស", 6 | "Shared with you" : "Shared with you", 7 | "Cancel" : "លើកលែង", 8 | "Options" : "ជម្រើស", 9 | "Delete" : "លុប", 10 | "Other" : "ផ្សេងៗ", 11 | "Set expiration date" : "កំណត់​ពេល​ផុត​កំណត់", 12 | "Group" : "Group", 13 | "Share link" : "Share link", 14 | "Edit" : "កែប្រែ", 15 | "Share" : "ចែក​រំលែក", 16 | "Description" : "ការ​អធិប្បាយ", 17 | "Download" : "ទាញយក", 18 | "Search" : "ស្វែងរក", 19 | "Sharing" : "ការ​ចែក​រំលែក", 20 | "Settings" : "ការកំណត់", 21 | "Abort" : "អំពី", 22 | "File" : "ឯកសារ", 23 | "Date" : "Date", 24 | "Time" : "ម៉ោង" 25 | }, 26 | "nplurals=1; plural=0;"); 27 | -------------------------------------------------------------------------------- /l10n/km.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "No" : "ទេ", 3 | "Yes" : "បាទ ឬចាស", 4 | "Shared with you" : "Shared with you", 5 | "Cancel" : "លើកលែង", 6 | "Options" : "ជម្រើស", 7 | "Delete" : "លុប", 8 | "Other" : "ផ្សេងៗ", 9 | "Set expiration date" : "កំណត់​ពេល​ផុត​កំណត់", 10 | "Group" : "Group", 11 | "Share link" : "Share link", 12 | "Edit" : "កែប្រែ", 13 | "Share" : "ចែក​រំលែក", 14 | "Description" : "ការ​អធិប្បាយ", 15 | "Download" : "ទាញយក", 16 | "Search" : "ស្វែងរក", 17 | "Sharing" : "ការ​ចែក​រំលែក", 18 | "Settings" : "ការកំណត់", 19 | "Abort" : "អំពី", 20 | "File" : "ឯកសារ", 21 | "Date" : "Date", 22 | "Time" : "ម៉ោង" 23 | },"pluralForm" :"nplurals=1; plural=0;" 24 | } -------------------------------------------------------------------------------- /l10n/kn.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "forms", 3 | { 4 | "No" : "ಇಲ್ಲ", 5 | "Yes" : "ಹೌದು", 6 | "Copy" : "ನಕಲಿಸಿ", 7 | "Shared with you" : "Shared with you", 8 | "Delete" : "ಅಳಿಸಿ", 9 | "Other" : "ಇತರೆ", 10 | "Set expiration date" : "ಮುಕ್ತಾಯ ದಿನಾಂಕವನ್ನು ನಿರ್ದರಿಸಿ", 11 | "Group" : "ಗುಂಪು", 12 | "Share link" : "ಸಂಪರ್ಕ ಕೊಂಡಿಯನ್ನು ಹಂಚಿಕೊಳ್ಳಬಹುದು", 13 | "Edit" : "ಸಂಪಾದಿಸು", 14 | "Share" : "ಹಂಚಿಕೊಳ್ಳಿ", 15 | "Download" : "ಪ್ರತಿಯನ್ನು ಸ್ಥಳೀಯವಾಗಿ ಉಳಿಸಿಕೊಳ್ಳಿ", 16 | "Search" : "Search", 17 | "Sharing" : "ಹಂಚಿಕೆ", 18 | "Settings" : "ಆಯ್ಕೆ", 19 | "Date" : "Date", 20 | "Time" : "ಸಮಯ" 21 | }, 22 | "nplurals=2; plural=(n > 1);"); 23 | -------------------------------------------------------------------------------- /l10n/kn.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "No" : "ಇಲ್ಲ", 3 | "Yes" : "ಹೌದು", 4 | "Copy" : "ನಕಲಿಸಿ", 5 | "Shared with you" : "Shared with you", 6 | "Delete" : "ಅಳಿಸಿ", 7 | "Other" : "ಇತರೆ", 8 | "Set expiration date" : "ಮುಕ್ತಾಯ ದಿನಾಂಕವನ್ನು ನಿರ್ದರಿಸಿ", 9 | "Group" : "ಗುಂಪು", 10 | "Share link" : "ಸಂಪರ್ಕ ಕೊಂಡಿಯನ್ನು ಹಂಚಿಕೊಳ್ಳಬಹುದು", 11 | "Edit" : "ಸಂಪಾದಿಸು", 12 | "Share" : "ಹಂಚಿಕೊಳ್ಳಿ", 13 | "Download" : "ಪ್ರತಿಯನ್ನು ಸ್ಥಳೀಯವಾಗಿ ಉಳಿಸಿಕೊಳ್ಳಿ", 14 | "Search" : "Search", 15 | "Sharing" : "ಹಂಚಿಕೆ", 16 | "Settings" : "ಆಯ್ಕೆ", 17 | "Date" : "Date", 18 | "Time" : "ಸಮಯ" 19 | },"pluralForm" :"nplurals=2; plural=(n > 1);" 20 | } -------------------------------------------------------------------------------- /l10n/lb.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "forms", 3 | { 4 | "No" : "Nee", 5 | "Yes" : "Jo", 6 | "Copy" : "Kopie", 7 | "Shared with you" : "Mat dir gedeelt", 8 | "Select groups" : "Wiel Gruppen äus", 9 | "Required" : "Noutwendeg", 10 | "Delete" : "Läschen", 11 | "Other" : "Aner", 12 | "Set expiration date" : "Verfallsdatum setzen", 13 | "Group" : "Grupp", 14 | "Share link" : "Link deelen", 15 | "Edit" : "Änneren", 16 | "Share" : "Deelen", 17 | "Description" : "Beschreiwung", 18 | "Download" : "Eroflueden", 19 | "Search" : "Sichen", 20 | "Sharing" : "Gedeelt", 21 | "Settings" : "Astellungen", 22 | "Date" : "Date", 23 | "Time" : "Zäit" 24 | }, 25 | "nplurals=2; plural=(n != 1);"); 26 | -------------------------------------------------------------------------------- /l10n/lb.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "No" : "Nee", 3 | "Yes" : "Jo", 4 | "Copy" : "Kopie", 5 | "Shared with you" : "Mat dir gedeelt", 6 | "Select groups" : "Wiel Gruppen äus", 7 | "Required" : "Noutwendeg", 8 | "Delete" : "Läschen", 9 | "Other" : "Aner", 10 | "Set expiration date" : "Verfallsdatum setzen", 11 | "Group" : "Grupp", 12 | "Share link" : "Link deelen", 13 | "Edit" : "Änneren", 14 | "Share" : "Deelen", 15 | "Description" : "Beschreiwung", 16 | "Download" : "Eroflueden", 17 | "Search" : "Sichen", 18 | "Sharing" : "Gedeelt", 19 | "Settings" : "Astellungen", 20 | "Date" : "Date", 21 | "Time" : "Zäit" 22 | },"pluralForm" :"nplurals=2; plural=(n != 1);" 23 | } -------------------------------------------------------------------------------- /l10n/lo.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "forms", 3 | { 4 | "No" : "ບໍ່", 5 | "Copy" : "ສຳເນົາ", 6 | "Shared with you" : "ແບ່ງປັບກັບທ່ານ", 7 | "Cancel" : "ຍົກເລີກ", 8 | "Delete" : "ລຶບ", 9 | "Set expiration date" : "ກໍານົດວັນໝົດອາຍຸ", 10 | "Group" : "ກຸ່ມ", 11 | "Share link" : "ແບ່ງປັນລິງ", 12 | "Internal link" : "ລີງພາຍໃນ", 13 | "Edit" : "ແກ້ໄຂ", 14 | "Share" : "ແບ່ງປັນ", 15 | "Download" : "ດາວໂຫລດ", 16 | "Search" : "ຄົ້ນຫາ", 17 | "Sharing" : "ການແບ່ງປັນ", 18 | "Settings" : "ການຕັ້ງຄ່າ", 19 | "File" : "ຟາຍ", 20 | "Date" : "ວັນທີ", 21 | "Phone number" : "ເບີໂທລະສັບ" 22 | }, 23 | "nplurals=1; plural=0;"); 24 | -------------------------------------------------------------------------------- /l10n/lo.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "No" : "ບໍ່", 3 | "Copy" : "ສຳເນົາ", 4 | "Shared with you" : "ແບ່ງປັບກັບທ່ານ", 5 | "Cancel" : "ຍົກເລີກ", 6 | "Delete" : "ລຶບ", 7 | "Set expiration date" : "ກໍານົດວັນໝົດອາຍຸ", 8 | "Group" : "ກຸ່ມ", 9 | "Share link" : "ແບ່ງປັນລິງ", 10 | "Internal link" : "ລີງພາຍໃນ", 11 | "Edit" : "ແກ້ໄຂ", 12 | "Share" : "ແບ່ງປັນ", 13 | "Download" : "ດາວໂຫລດ", 14 | "Search" : "ຄົ້ນຫາ", 15 | "Sharing" : "ການແບ່ງປັນ", 16 | "Settings" : "ການຕັ້ງຄ່າ", 17 | "File" : "ຟາຍ", 18 | "Date" : "ວັນທີ", 19 | "Phone number" : "ເບີໂທລະສັບ" 20 | },"pluralForm" :"nplurals=1; plural=0;" 21 | } -------------------------------------------------------------------------------- /l10n/mn.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "forms", 3 | { 4 | "Copy" : "Хуулах", 5 | "Shared with you" : "тантай хуваалцсан", 6 | "Select groups" : "бүлэг сонгох", 7 | "Cancel" : "Цуцлах", 8 | "Required" : "Шаардлагатай", 9 | "Delete" : "Устгах", 10 | "Uploading …" : "Байршуулж байна...", 11 | "Set expiration date" : "Дуусах хугацааг тохируулах", 12 | "Group" : "Бүлэг", 13 | "Share link" : "Холбоос хуваалцах", 14 | "Edit" : "засварлах", 15 | "Share" : "Түгээх", 16 | "Description" : "Тодорхойлолт", 17 | "Summary" : "Хураангуй", 18 | "Download" : "Татах", 19 | "Search" : "Хайх", 20 | "Sharing" : "Түгээх", 21 | "Settings" : "Тохиргоо", 22 | "Submit" : "мэдэгдэх", 23 | "Date" : "Он сар өдөр", 24 | "Time" : "Цаг", 25 | "Phone number" : "Утасны дугаар" 26 | }, 27 | "nplurals=2; plural=(n != 1);"); 28 | -------------------------------------------------------------------------------- /l10n/mn.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "Copy" : "Хуулах", 3 | "Shared with you" : "тантай хуваалцсан", 4 | "Select groups" : "бүлэг сонгох", 5 | "Cancel" : "Цуцлах", 6 | "Required" : "Шаардлагатай", 7 | "Delete" : "Устгах", 8 | "Uploading …" : "Байршуулж байна...", 9 | "Set expiration date" : "Дуусах хугацааг тохируулах", 10 | "Group" : "Бүлэг", 11 | "Share link" : "Холбоос хуваалцах", 12 | "Edit" : "засварлах", 13 | "Share" : "Түгээх", 14 | "Description" : "Тодорхойлолт", 15 | "Summary" : "Хураангуй", 16 | "Download" : "Татах", 17 | "Search" : "Хайх", 18 | "Sharing" : "Түгээх", 19 | "Settings" : "Тохиргоо", 20 | "Submit" : "мэдэгдэх", 21 | "Date" : "Он сар өдөр", 22 | "Time" : "Цаг", 23 | "Phone number" : "Утасны дугаар" 24 | },"pluralForm" :"nplurals=2; plural=(n != 1);" 25 | } -------------------------------------------------------------------------------- /l10n/nn_NO.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "forms", 3 | { 4 | "Copy" : "Kopier", 5 | "Shared with you" : "Shared with you", 6 | "Select groups" : "Vel grupper", 7 | "Required" : "Nødvendig", 8 | "Delete" : "Slett", 9 | "Uploading …" : "Lastar opp...", 10 | "Other" : "Anna", 11 | "Set expiration date" : "Set utløpsdato", 12 | "Group" : "Gruppe", 13 | "Share link" : "Del lenkje", 14 | "Edit" : "Rediger", 15 | "Share" : "Del", 16 | "Description" : "Skildring", 17 | "Summary" : "Oppsumering", 18 | "Download" : "Last ned", 19 | "Search" : "Søk", 20 | "Sharing" : "Deling", 21 | "Settings" : "Instillingar", 22 | "Abort" : "Avbryt", 23 | "File" : "Fil", 24 | "Date" : "Dato", 25 | "Time" : "Tid" 26 | }, 27 | "nplurals=2; plural=(n != 1);"); 28 | -------------------------------------------------------------------------------- /l10n/nn_NO.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "Copy" : "Kopier", 3 | "Shared with you" : "Shared with you", 4 | "Select groups" : "Vel grupper", 5 | "Required" : "Nødvendig", 6 | "Delete" : "Slett", 7 | "Uploading …" : "Lastar opp...", 8 | "Other" : "Anna", 9 | "Set expiration date" : "Set utløpsdato", 10 | "Group" : "Gruppe", 11 | "Share link" : "Del lenkje", 12 | "Edit" : "Rediger", 13 | "Share" : "Del", 14 | "Description" : "Skildring", 15 | "Summary" : "Oppsumering", 16 | "Download" : "Last ned", 17 | "Search" : "Søk", 18 | "Sharing" : "Deling", 19 | "Settings" : "Instillingar", 20 | "Abort" : "Avbryt", 21 | "File" : "Fil", 22 | "Date" : "Dato", 23 | "Time" : "Tid" 24 | },"pluralForm" :"nplurals=2; plural=(n != 1);" 25 | } -------------------------------------------------------------------------------- /l10n/oc.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "forms", 3 | { 4 | "Forms" : "Formularis", 5 | "No" : "Non", 6 | "Yes" : "Òc", 7 | "Question" : "Question", 8 | "Copy" : "Copiar", 9 | "Shared with you" : "Partejat amb vos", 10 | "Loading forms …" : "Cargament del formulari...", 11 | "No forms created yet" : "Cap de formulari pas encara creat", 12 | "Cancel" : "Anullar", 13 | "Options" : "Opcions", 14 | "Delete" : "Suprimir", 15 | "Uploading …" : "Mandadís…", 16 | "Set expiration date" : "Especificar una data d'expiracion", 17 | "Group" : "Grop", 18 | "Permissions" : "Autorizacions", 19 | "Share link" : "Partejar lo ligam", 20 | "Add link" : "Apondre un ligam", 21 | "Copy to clipboard" : "Copiar dins lo quichapapièrs", 22 | "View" : "Veire", 23 | "Edit" : "Modificar", 24 | "Share" : "Partejar", 25 | "Description" : "Descripcion", 26 | "Download" : "Teledescargar", 27 | "Search" : "Recercar", 28 | "Sharing" : "Partiment", 29 | "Settings" : "Paramètres", 30 | "Abort" : "Anullar", 31 | "Submit" : "Transmetre", 32 | "Clear" : "Escafar", 33 | "File" : "Fichier", 34 | "Date" : "Data", 35 | "Pick a date" : "Causir una data", 36 | "Time" : "Ora", 37 | "Pick a time" : "Causir una ora", 38 | "Document" : "Document", 39 | "Presentation" : "Presentacion", 40 | "Text" : "Tèxt", 41 | "Phone number" : "Numèro de telefòn", 42 | "Email address" : "Adreça mail" 43 | }, 44 | "nplurals=2; plural=(n > 1);"); 45 | -------------------------------------------------------------------------------- /l10n/oc.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "Forms" : "Formularis", 3 | "No" : "Non", 4 | "Yes" : "Òc", 5 | "Question" : "Question", 6 | "Copy" : "Copiar", 7 | "Shared with you" : "Partejat amb vos", 8 | "Loading forms …" : "Cargament del formulari...", 9 | "No forms created yet" : "Cap de formulari pas encara creat", 10 | "Cancel" : "Anullar", 11 | "Options" : "Opcions", 12 | "Delete" : "Suprimir", 13 | "Uploading …" : "Mandadís…", 14 | "Set expiration date" : "Especificar una data d'expiracion", 15 | "Group" : "Grop", 16 | "Permissions" : "Autorizacions", 17 | "Share link" : "Partejar lo ligam", 18 | "Add link" : "Apondre un ligam", 19 | "Copy to clipboard" : "Copiar dins lo quichapapièrs", 20 | "View" : "Veire", 21 | "Edit" : "Modificar", 22 | "Share" : "Partejar", 23 | "Description" : "Descripcion", 24 | "Download" : "Teledescargar", 25 | "Search" : "Recercar", 26 | "Sharing" : "Partiment", 27 | "Settings" : "Paramètres", 28 | "Abort" : "Anullar", 29 | "Submit" : "Transmetre", 30 | "Clear" : "Escafar", 31 | "File" : "Fichier", 32 | "Date" : "Data", 33 | "Pick a date" : "Causir una data", 34 | "Time" : "Ora", 35 | "Pick a time" : "Causir una ora", 36 | "Document" : "Document", 37 | "Presentation" : "Presentacion", 38 | "Text" : "Tèxt", 39 | "Phone number" : "Numèro de telefòn", 40 | "Email address" : "Adreça mail" 41 | },"pluralForm" :"nplurals=2; plural=(n > 1);" 42 | } -------------------------------------------------------------------------------- /l10n/si.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "forms", 3 | { 4 | "No" : "නැහැ", 5 | "Copy" : "පිටපත්", 6 | "Anonymous response" : "නිර්නාමික ප්‍රතිචාරය", 7 | "responses" : "ප්‍රතිචාර", 8 | "Cancel" : "අවලංගු", 9 | "Uploading …" : "උඩුගත වෙමින්…", 10 | "Other" : "වෙනත්", 11 | "Group" : "සමූහය", 12 | "Edit" : "සංස්කරණය", 13 | "Share" : "බෙදාගන්න", 14 | "Description" : "විස්තරය", 15 | "Summary" : "සාරාංශය", 16 | "Responses" : "ප්‍රතිචාර", 17 | "Download" : "බාගන්න", 18 | "Search" : "සොයන්න", 19 | "Settings" : "සැකසුම්", 20 | "Abort" : "රෝධනය", 21 | "File" : "ගොනුව", 22 | "Date" : "දිනය", 23 | "Time" : "වේලාව", 24 | "Phone number" : "දුරකථන අංකය" 25 | }, 26 | "nplurals=2; plural=(n != 1);"); 27 | -------------------------------------------------------------------------------- /l10n/si.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "No" : "නැහැ", 3 | "Copy" : "පිටපත්", 4 | "Anonymous response" : "නිර්නාමික ප්‍රතිචාරය", 5 | "responses" : "ප්‍රතිචාර", 6 | "Cancel" : "අවලංගු", 7 | "Uploading …" : "උඩුගත වෙමින්…", 8 | "Other" : "වෙනත්", 9 | "Group" : "සමූහය", 10 | "Edit" : "සංස්කරණය", 11 | "Share" : "බෙදාගන්න", 12 | "Description" : "විස්තරය", 13 | "Summary" : "සාරාංශය", 14 | "Responses" : "ප්‍රතිචාර", 15 | "Download" : "බාගන්න", 16 | "Search" : "සොයන්න", 17 | "Settings" : "සැකසුම්", 18 | "Abort" : "රෝධනය", 19 | "File" : "ගොනුව", 20 | "Date" : "දිනය", 21 | "Time" : "වේලාව", 22 | "Phone number" : "දුරකථන අංකය" 23 | },"pluralForm" :"nplurals=2; plural=(n != 1);" 24 | } -------------------------------------------------------------------------------- /l10n/sq.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "forms", 3 | { 4 | "Yes" : "Po", 5 | "Copy" : "Kopjo", 6 | "Shared with you" : "E ndarë me ju", 7 | "Select groups" : "Përzgjidhni grupe", 8 | "Cancel" : "Anuloje", 9 | "Required" : "E domosdoshme", 10 | "Delete" : "Fshij", 11 | "Other" : "Tjetër", 12 | "Set expiration date" : "Caktoni datë skadimi", 13 | "Group" : "Grup", 14 | "Permissions" : "Lejet", 15 | "Share link" : "Lidhje ndarjeje", 16 | "Add link" : "Shto link", 17 | "Copy to clipboard" : "Kopjo në dërrasë ", 18 | "View" : "Shiko", 19 | "Edit" : "Përpuno", 20 | "Share" : "Shpërndaje", 21 | "Description" : "Përshkrim", 22 | "Summary" : "Përmbledhje", 23 | "Download" : "Shkarko", 24 | "Search" : "Kërko", 25 | "Sharing" : "Ndarje", 26 | "Settings" : "Rregullimet", 27 | "Abort" : "Ndërprite", 28 | "Submit" : "Dërgo", 29 | "Clear" : "Pastro", 30 | "File" : "Skedar ", 31 | "Date" : "Data", 32 | "Time" : "Kohë", 33 | "Document" : "Dokument", 34 | "Presentation" : "Paraqitje", 35 | "Spreadsheet" : "Fletëllogaritje", 36 | "Text" : "Tekst", 37 | "Phone number" : "Numri i telefonit" 38 | }, 39 | "nplurals=2; plural=(n != 1);"); 40 | -------------------------------------------------------------------------------- /l10n/sq.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "Yes" : "Po", 3 | "Copy" : "Kopjo", 4 | "Shared with you" : "E ndarë me ju", 5 | "Select groups" : "Përzgjidhni grupe", 6 | "Cancel" : "Anuloje", 7 | "Required" : "E domosdoshme", 8 | "Delete" : "Fshij", 9 | "Other" : "Tjetër", 10 | "Set expiration date" : "Caktoni datë skadimi", 11 | "Group" : "Grup", 12 | "Permissions" : "Lejet", 13 | "Share link" : "Lidhje ndarjeje", 14 | "Add link" : "Shto link", 15 | "Copy to clipboard" : "Kopjo në dërrasë ", 16 | "View" : "Shiko", 17 | "Edit" : "Përpuno", 18 | "Share" : "Shpërndaje", 19 | "Description" : "Përshkrim", 20 | "Summary" : "Përmbledhje", 21 | "Download" : "Shkarko", 22 | "Search" : "Kërko", 23 | "Sharing" : "Ndarje", 24 | "Settings" : "Rregullimet", 25 | "Abort" : "Ndërprite", 26 | "Submit" : "Dërgo", 27 | "Clear" : "Pastro", 28 | "File" : "Skedar ", 29 | "Date" : "Data", 30 | "Time" : "Kohë", 31 | "Document" : "Dokument", 32 | "Presentation" : "Paraqitje", 33 | "Spreadsheet" : "Fletëllogaritje", 34 | "Text" : "Tekst", 35 | "Phone number" : "Numri i telefonit" 36 | },"pluralForm" :"nplurals=2; plural=(n != 1);" 37 | } -------------------------------------------------------------------------------- /l10n/sr@latin.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "forms", 3 | { 4 | "No" : "Ne", 5 | "Yes" : "Da", 6 | "Copy" : "Kopija", 7 | "Shared with you" : "Shared with you", 8 | "Cancel" : "Poništi", 9 | "Delete" : "Obriši", 10 | "Other" : "Ostali", 11 | "Set expiration date" : "Postavi datum isteka", 12 | "Group" : "Group", 13 | "Share link" : "Podeli vezu", 14 | "Edit" : "Izmeni", 15 | "Share" : "Podeli", 16 | "Description" : "Opis", 17 | "Search" : "Traži", 18 | "Sharing" : "Deljenje", 19 | "Settings" : "Поставке", 20 | "Abort" : "Prekini", 21 | "File" : "Fajl", 22 | "Date" : "Date" 23 | }, 24 | "nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);"); 25 | -------------------------------------------------------------------------------- /l10n/sr@latin.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "No" : "Ne", 3 | "Yes" : "Da", 4 | "Copy" : "Kopija", 5 | "Shared with you" : "Shared with you", 6 | "Cancel" : "Poništi", 7 | "Delete" : "Obriši", 8 | "Other" : "Ostali", 9 | "Set expiration date" : "Postavi datum isteka", 10 | "Group" : "Group", 11 | "Share link" : "Podeli vezu", 12 | "Edit" : "Izmeni", 13 | "Share" : "Podeli", 14 | "Description" : "Opis", 15 | "Search" : "Traži", 16 | "Sharing" : "Deljenje", 17 | "Settings" : "Поставке", 18 | "Abort" : "Prekini", 19 | "File" : "Fajl", 20 | "Date" : "Date" 21 | },"pluralForm" :"nplurals=3; plural=(n%10==1 && n%100!=11 ? 0 : n%10>=2 && n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2);" 22 | } -------------------------------------------------------------------------------- /l10n/ta.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "forms", 3 | { 4 | "No" : "இல்லை", 5 | "Yes" : "ஆம்", 6 | "Copy" : "Copy", 7 | "Shared with you" : "Shared with you", 8 | "Cancel" : "ரத்து செய்", 9 | "Delete" : "நீக்குக", 10 | "Other" : "மற்றவை", 11 | "Set expiration date" : "காலாவதி தேதியை குறிப்பிடுக", 12 | "Group" : "Group", 13 | "Share link" : "Share link", 14 | "Edit" : "தொகுக்க", 15 | "Share" : "பகிர்வு", 16 | "Description" : "விவரிப்பு", 17 | "Download" : "பதிவிறக்குக", 18 | "Search" : "தேடுதல்", 19 | "Settings" : "அமைப்புகள்", 20 | "File" : "File", 21 | "Date" : "Date" 22 | }, 23 | "nplurals=2; plural=(n != 1);"); 24 | -------------------------------------------------------------------------------- /l10n/ta.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "No" : "இல்லை", 3 | "Yes" : "ஆம்", 4 | "Copy" : "Copy", 5 | "Shared with you" : "Shared with you", 6 | "Cancel" : "ரத்து செய்", 7 | "Delete" : "நீக்குக", 8 | "Other" : "மற்றவை", 9 | "Set expiration date" : "காலாவதி தேதியை குறிப்பிடுக", 10 | "Group" : "Group", 11 | "Share link" : "Share link", 12 | "Edit" : "தொகுக்க", 13 | "Share" : "பகிர்வு", 14 | "Description" : "விவரிப்பு", 15 | "Download" : "பதிவிறக்குக", 16 | "Search" : "தேடுதல்", 17 | "Settings" : "அமைப்புகள்", 18 | "File" : "File", 19 | "Date" : "Date" 20 | },"pluralForm" :"nplurals=2; plural=(n != 1);" 21 | } -------------------------------------------------------------------------------- /l10n/uz.js: -------------------------------------------------------------------------------- 1 | OC.L10N.register( 2 | "forms", 3 | { 4 | "Timestamp of data load" : "Ma'lumotlarni yuklash vaqt belgisi", 5 | "No" : "No", 6 | "Yes" : "Yes", 7 | "Count" : "Hisoblash", 8 | "Copy" : "Copy", 9 | "Shared with you" : "Shared with you", 10 | "Results" : "Natijalar", 11 | "Cancel" : "Cancel", 12 | "Options" : "Variantlar", 13 | "Delete" : "Delete", 14 | "Uploading …" : "Yuklanmoqda...", 15 | "Other" : "Boshqa", 16 | "Set expiration date" : "Set expiration date", 17 | "Share link" : "Share link", 18 | "Copy embedding code" : "O'rnatish kodini nusxalash", 19 | "Internal link" : "Ichki havola", 20 | "Edit" : "Tahrirlash", 21 | "Share" : "Ulashish", 22 | "Description" : "Tavsif", 23 | "Download" : "Download", 24 | "Search" : "Qidiruv", 25 | "No results found" : "Hech qanday natija topilmadi", 26 | "Sharing" : "Ulashish", 27 | "Settings" : "Settings", 28 | "Checkboxes" : "Belgilash katakchalari", 29 | "File" : "File", 30 | "Date" : "Sana", 31 | "Pick a date" : "Sana tanlang", 32 | "Time" : "Vaqt", 33 | "Pick a time" : "Vaqtni tanlang", 34 | "Text" : "Matn", 35 | "Email address" : "E-pochta manzili" 36 | }, 37 | "nplurals=1; plural=0;"); 38 | -------------------------------------------------------------------------------- /l10n/uz.json: -------------------------------------------------------------------------------- 1 | { "translations": { 2 | "Timestamp of data load" : "Ma'lumotlarni yuklash vaqt belgisi", 3 | "No" : "No", 4 | "Yes" : "Yes", 5 | "Count" : "Hisoblash", 6 | "Copy" : "Copy", 7 | "Shared with you" : "Shared with you", 8 | "Results" : "Natijalar", 9 | "Cancel" : "Cancel", 10 | "Options" : "Variantlar", 11 | "Delete" : "Delete", 12 | "Uploading …" : "Yuklanmoqda...", 13 | "Other" : "Boshqa", 14 | "Set expiration date" : "Set expiration date", 15 | "Share link" : "Share link", 16 | "Copy embedding code" : "O'rnatish kodini nusxalash", 17 | "Internal link" : "Ichki havola", 18 | "Edit" : "Tahrirlash", 19 | "Share" : "Ulashish", 20 | "Description" : "Tavsif", 21 | "Download" : "Download", 22 | "Search" : "Qidiruv", 23 | "No results found" : "Hech qanday natija topilmadi", 24 | "Sharing" : "Ulashish", 25 | "Settings" : "Settings", 26 | "Checkboxes" : "Belgilash katakchalari", 27 | "File" : "File", 28 | "Date" : "Sana", 29 | "Pick a date" : "Sana tanlang", 30 | "Time" : "Vaqt", 31 | "Pick a time" : "Vaqtni tanlang", 32 | "Text" : "Matn", 33 | "Email address" : "E-pochta manzili" 34 | },"pluralForm" :"nplurals=1; plural=0;" 35 | } -------------------------------------------------------------------------------- /lib/Activity/Filter.php: -------------------------------------------------------------------------------- 1 | appName; 28 | } 29 | 30 | /** 31 | * Translated, readable Filter-Name 32 | * @return string 33 | */ 34 | public function getName(): string { 35 | return $this->l10n->t('Forms'); 36 | } 37 | 38 | /** 39 | * Icon to use 40 | * @return string Full Icon-URL 41 | */ 42 | public function getIcon(): string { 43 | return $this->urlGenerator->getAbsoluteURL($this->urlGenerator->imagePath($this->appName, 'forms-dark.svg')); 44 | } 45 | 46 | /** 47 | * Filter Priority within Activity App 48 | * @return int 49 | */ 50 | public function getPriority(): int { 51 | return 60; 52 | } 53 | 54 | /** 55 | * Only show Activities by Forms-App. 56 | * @return string[] Array of allowed Apps 57 | */ 58 | public function allowedApps(): array { 59 | return [$this->appName]; 60 | } 61 | 62 | /** 63 | * No Sub-Filter within forms. 64 | * @param string[] $types 65 | * @return string[] An array of allowed Event-Types. Return param $types to allow all. 66 | */ 67 | public function filterTypes(array $types): array { 68 | return $types; 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /lib/Activity/Settings/FormsActivitySettings.php: -------------------------------------------------------------------------------- 1 | appName; 26 | } 27 | 28 | /** 29 | * Human Readable Group Title 30 | * @return string 31 | */ 32 | public function getGroupName(): string { 33 | return $this->l10n->t('Forms'); 34 | } 35 | 36 | /** 37 | * Priority of the Setting (0-100) 38 | * Using this as Forms-Basepriority 39 | * @return int 40 | */ 41 | public function getPriority(): int { 42 | return 60; 43 | } 44 | 45 | /** 46 | * User can change Notification 47 | * @return bool 48 | */ 49 | public function canChangeNotification(): bool { 50 | return true; 51 | } 52 | 53 | /** 54 | * Notification enabled by default 55 | */ 56 | public function isDefaultEnabledNotification(): bool { 57 | return true; 58 | } 59 | 60 | /** 61 | * User can change Mail 62 | * @return bool 63 | */ 64 | public function canChangeMail(): bool { 65 | return true; 66 | } 67 | 68 | /** 69 | * Mail disabled by default 70 | * @return bool 71 | */ 72 | public function isDefaultEnabledMail(): bool { 73 | return false; 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /lib/Activity/Settings/NewShare.php: -------------------------------------------------------------------------------- 1 | l10n->t('A form has been shared with you'); 28 | } 29 | 30 | /** 31 | * Priority of the Setting 32 | * Using Forms Base-Priority (parent) 33 | * @return int 34 | */ 35 | public function getPriority(): int { 36 | return parent::getPriority() + 0; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /lib/Activity/Settings/NewSharedSubmission.php: -------------------------------------------------------------------------------- 1 | l10n->t('Someone answered a shared form'); 28 | } 29 | 30 | /** 31 | * Priority of the Setting 32 | * Using Forms Base-Priority (parent) 33 | * @return int 34 | */ 35 | public function getPriority(): int { 36 | return parent::getPriority() + 2; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /lib/Activity/Settings/NewSubmission.php: -------------------------------------------------------------------------------- 1 | l10n->t('Someone answered a form'); 28 | } 29 | 30 | /** 31 | * Priority of the Setting 32 | * Using Forms Base-Priority (parent) 33 | * @return int 34 | */ 35 | public function getPriority(): int { 36 | return parent::getPriority() + 1; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /lib/BackgroundJob/UserDeletedJob.php: -------------------------------------------------------------------------------- 1 | logger->info('Deleting forms for deleted user {user}', [ 32 | 'user' => $ownerId 33 | ]); 34 | 35 | $forms = $this->formMapper->findAllByOwnerId($ownerId); 36 | foreach ($forms as $form) { 37 | $this->formMapper->deleteForm($form); 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /lib/Capabilities.php: -------------------------------------------------------------------------------- 1 | }} 23 | */ 24 | public function getCapabilities() { 25 | return [ 26 | 'forms' => [ 27 | 'version' => $this->appManager->getAppVersion('forms'), 28 | 'apiVersions' => ['v3'] 29 | ] 30 | ]; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /lib/Db/Answer.php: -------------------------------------------------------------------------------- 1 | addType('submissionId', 'integer'); 37 | $this->addType('questionId', 'integer'); 38 | $this->addType('fileId', 'integer'); 39 | } 40 | 41 | /** 42 | * @return FormsAnswer 43 | */ 44 | public function read(): array { 45 | return [ 46 | 'id' => $this->getId(), 47 | 'submissionId' => $this->getSubmissionId(), 48 | 'fileId' => $this->getFileId(), 49 | 'questionId' => $this->getQuestionId(), 50 | 'text' => (string)$this->getText(), 51 | ]; 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /lib/Db/AnswerMapper.php: -------------------------------------------------------------------------------- 1 | 16 | */ 17 | class AnswerMapper extends QBMapper { 18 | 19 | /** 20 | * AnswerMapper constructor. 21 | * @param IDBConnection $db 22 | */ 23 | public function __construct(IDBConnection $db) { 24 | parent::__construct($db, 'forms_v2_answers', Answer::class); 25 | } 26 | 27 | /** 28 | * @param int $submissionId 29 | * @throws \OCP\AppFramework\Db\DoesNotExistException if not found 30 | * @return Answer[] 31 | */ 32 | public function findBySubmission(int $submissionId): array { 33 | $qb = $this->db->getQueryBuilder(); 34 | 35 | $qb->select('*') 36 | ->from($this->getTableName()) 37 | ->where( 38 | $qb->expr()->eq('submission_id', $qb->createNamedParameter($submissionId, IQueryBuilder::PARAM_INT)) 39 | ); 40 | 41 | return $this->findEntities($qb); 42 | } 43 | 44 | /** 45 | * @param int $submissionId 46 | */ 47 | public function deleteBySubmission(int $submissionId): void { 48 | $qb = $this->db->getQueryBuilder(); 49 | 50 | $qb->delete($this->getTableName()) 51 | ->where( 52 | $qb->expr()->eq('submission_id', $qb->createNamedParameter($submissionId, IQueryBuilder::PARAM_INT)) 53 | ); 54 | 55 | $qb->executeStatement(); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /lib/Db/Option.php: -------------------------------------------------------------------------------- 1 | questionId = null; 36 | $this->text = null; 37 | $this->order = null; 38 | $this->addType('questionId', 'integer'); 39 | $this->addType('order', 'integer'); 40 | $this->addType('text', 'string'); 41 | } 42 | 43 | /** 44 | * @return FormsOption 45 | */ 46 | public function read(): array { 47 | return [ 48 | 'id' => $this->getId(), 49 | 'questionId' => $this->getQuestionId(), 50 | 'order' => $this->getOrder(), 51 | 'text' => (string)$this->getText(), 52 | ]; 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /lib/Db/Submission.php: -------------------------------------------------------------------------------- 1 | addType('formId', 'integer'); 32 | $this->addType('timestamp', 'integer'); 33 | } 34 | 35 | /** 36 | * @return array{ 37 | * id: int, 38 | * formId: int, 39 | * userId: string, 40 | * timestamp: int, 41 | * } 42 | */ 43 | public function read(): array { 44 | return [ 45 | 'id' => $this->getId(), 46 | 'formId' => $this->getFormId(), 47 | 'userId' => $this->getUserId(), 48 | 'timestamp' => $this->getTimestamp(), 49 | ]; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /lib/Db/UploadedFile.php: -------------------------------------------------------------------------------- 1 | addType('formId', 'integer'); 35 | $this->addType('originalFileName', 'string'); 36 | $this->addType('fileId', 'integer'); 37 | $this->addType('created', 'integer'); 38 | } 39 | 40 | public function read(): array { 41 | return [ 42 | 'id' => $this->getId(), 43 | 'formId' => $this->getFormId(), 44 | 'originalFileName' => $this->getOriginalFileName(), 45 | 'fileId' => $this->getFileId(), 46 | 'created' => $this->getCreated(), 47 | ]; 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /lib/Events/AbstractFormEvent.php: -------------------------------------------------------------------------------- 1 | form; 24 | } 25 | 26 | /** 27 | * @inheritDoc 28 | */ 29 | public function getWebhookSerializable(): array { 30 | return $this->form->read(); 31 | } 32 | } 33 | 34 | } else { 35 | // need this block as long as NC < 30 is supported 36 | abstract class AbstractFormEvent extends Event { 37 | public function __construct( 38 | protected Form $form, 39 | ) { 40 | parent::__construct(); 41 | } 42 | 43 | public function getForm(): Form { 44 | return $this->form; 45 | } 46 | 47 | public function getWebhookSerializable(): array { 48 | return $this->form->read(); 49 | } 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /lib/Events/FormSubmittedEvent.php: -------------------------------------------------------------------------------- 1 | $this->form->read(), 24 | 'submission' => $this->submission->read(), 25 | ]; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /lib/Exception/NoSuchFormException.php: -------------------------------------------------------------------------------- 1 | 18 | */ 19 | class AnalyticsDatasourceListener implements IEventListener { 20 | public function handle(Event $event): void { 21 | if (!($event instanceof DatasourceEvent)) { 22 | // Unrelated 23 | return; 24 | } 25 | $event->registerDatasource(AnalyticsDatasource::class); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /lib/Listener/UserDeletedListener.php: -------------------------------------------------------------------------------- 1 | 18 | */ 19 | class UserDeletedListener implements IEventListener { 20 | public function __construct( 21 | private IJobList $jobList, 22 | ) { 23 | } 24 | 25 | public function handle(Event $event): void { 26 | if (!($event instanceof UserDeletedEvent)) { 27 | return; 28 | } 29 | 30 | // Set a Cron-Job to delete the Users Forms. 31 | $this->jobList->add(UserDeletedJob::class, ['owner_id' => $event->getUser()->getUID()]); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /lib/Middleware/ThrottleFormAccessMiddleware.php: -------------------------------------------------------------------------------- 1 | getMessage(), 29 | $exception->getCode(), 30 | ); 31 | $response->throttle(['action' => 'form']); 32 | return $response; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /lib/Migration/Version0010Date20190000000007.php: -------------------------------------------------------------------------------- 1 | connection = $connection; 34 | $this->config = $config; 35 | } 36 | 37 | /** 38 | * @param IOutput $output 39 | * @param \Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper` 40 | * @param array $options 41 | * @return null|ISchemaWrapper 42 | * @since 13.0.0 43 | */ 44 | public function changeSchema(IOutput $output, \Closure $schemaClosure, array $options) { 45 | /** @var ISchemaWrapper $schema */ 46 | $schema = $schemaClosure(); 47 | 48 | if ($schema->hasTable('forms_events')) { 49 | $schema->getTable('forms_events')->addColumn('unique', 'integer', [ 50 | 'notnull' => false, 51 | 'default' => 0, 52 | ]); 53 | } else { 54 | } 55 | return $schema; 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /lib/Migration/Version010102Date20200323120846.php: -------------------------------------------------------------------------------- 1 | hasTable('forms_notif')) { 31 | $schema->dropTable('forms_notif'); 32 | } 33 | 34 | return $schema; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /lib/Migration/Version020002Date20200729205932.php: -------------------------------------------------------------------------------- 1 | hasTable('forms_v2_forms')) { 29 | $schema->getTable('forms_v2_forms') 30 | ->changeColumn('description', [ 31 | 'length' => 8192, 32 | ]); 33 | } 34 | 35 | if ($schema->hasTable('forms_v2_answers')) { 36 | $schema->getTable('forms_v2_answers') 37 | ->changeColumn('text', [ 38 | 'length' => 4096, 39 | ]); 40 | } 41 | 42 | return $schema; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /lib/Migration/Version020300Date20210403214012.php: -------------------------------------------------------------------------------- 1 | ensureColumnIsNullable($schema, 'forms_v2_forms', 'is_anonymous'); 29 | $result |= $this->ensureColumnIsNullable($schema, 'forms_v2_forms', 'submit_once'); 30 | $result |= $this->ensureColumnIsNullable($schema, 'forms_v2_questions', 'mandatory'); 31 | 32 | return $result ? $schema : null; 33 | } 34 | 35 | protected function ensureColumnIsNullable(ISchemaWrapper $schema, string $tableName, string $columnName): bool { 36 | $table = $schema->getTable($tableName); 37 | $column = $table->getColumn($columnName); 38 | 39 | if ($column->getNotnull()) { 40 | $column->setNotnull(false); 41 | return true; 42 | } 43 | 44 | return false; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /lib/Migration/Version020300Date20210406114130.php: -------------------------------------------------------------------------------- 1 | connection = $connection; 27 | } 28 | 29 | /** 30 | * @param IOutput $output 31 | * @param Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper` 32 | * @param array $options 33 | * @return null|ISchemaWrapper 34 | */ 35 | public function changeSchema(IOutput $output, Closure $schemaClosure, array $options): ?ISchemaWrapper { 36 | /** @var ISchemaWrapper $schema */ 37 | $schema = $schemaClosure(); 38 | 39 | $table = $schema->getTable('forms_v2_questions'); 40 | 41 | if (!$table->hasColumn('is_required')) { 42 | $table->addColumn('is_required', Types::BOOLEAN, [ 43 | 'notnull' => false, 44 | 'default' => 0, 45 | ]); 46 | 47 | return $schema; 48 | } 49 | 50 | return null; 51 | } 52 | 53 | /** 54 | * @return void 55 | */ 56 | public function postSchemaChange(IOutput $output, \Closure $schemaClosure, array $options) { 57 | $qb_update = $this->connection->getQueryBuilder(); 58 | 59 | $qb_update->update('forms_v2_questions') 60 | ->set('is_required', 'mandatory'); 61 | $qb_update->executeStatement(); 62 | } 63 | } 64 | -------------------------------------------------------------------------------- /lib/Migration/Version020300Date20210406133704.php: -------------------------------------------------------------------------------- 1 | getTable('forms_v2_questions'); 29 | 30 | if ($table->hasColumn('mandatory') && $table->hasColumn('is_required')) { 31 | $table->dropColumn('mandatory'); 32 | 33 | return $schema; 34 | } 35 | 36 | return null; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /lib/Migration/Version030000Date20220402100057.php: -------------------------------------------------------------------------------- 1 | getTable('forms_v2_forms')->getColumn('description'); 34 | if ($column->getType() === Type::getType(Types::STRING)) { 35 | $column->setType(Type::getType(Types::TEXT)); 36 | $update_necesssary = true; 37 | } 38 | 39 | // Change Type of Answer-Text from string to text. Necessary due to length restrictions. 40 | $column = $schema->getTable('forms_v2_answers')->getColumn('text'); 41 | if ($column->getType() === Type::getType(Types::STRING)) { 42 | $column->setType(Type::getType(Types::TEXT)); 43 | $update_necesssary = true; 44 | } 45 | 46 | return $update_necesssary ? $schema : null; 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /lib/Migration/Version030000Date20220402151229.php: -------------------------------------------------------------------------------- 1 | hasTable('forms_events')) { 31 | $schema->dropTable('forms_events'); 32 | $update_necessary = true; 33 | } 34 | if ($schema->hasTable('forms_questions')) { 35 | $schema->dropTable('forms_questions'); 36 | $update_necessary = true; 37 | } 38 | if ($schema->hasTable('forms_answers')) { 39 | $schema->dropTable('forms_answers'); 40 | $update_necessary = true; 41 | } 42 | if ($schema->hasTable('forms_votes')) { 43 | $schema->dropTable('forms_votes'); 44 | $update_necessary = true; 45 | } 46 | 47 | return $update_necessary ? $schema : null; 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /lib/Migration/Version030000Date20220414203511.php: -------------------------------------------------------------------------------- 1 | getTable('forms_v2_questions'); 27 | 28 | if (!$table->hasColumn('description')) { 29 | $table->addColumn('description', Types::TEXT, [ 30 | 'notnull' => false, 31 | 'length' => 4096, 32 | 'default' => '', 33 | ]); 34 | 35 | return $schema; 36 | } 37 | 38 | return null; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /lib/Migration/Version030000Date20220707130109.php: -------------------------------------------------------------------------------- 1 | getTable('forms_v2_forms'); 28 | 29 | if ($table->hasColumn('submit_once') && $table->hasColumn('submit_multiple')) { 30 | $table->dropColumn('submit_once'); 31 | return $schema; 32 | } 33 | 34 | return null; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /lib/Migration/Version030000Date20220831195000.php: -------------------------------------------------------------------------------- 1 | getTable('forms_v2_questions'); 27 | 28 | if (!$table->hasColumn('extra_settings_json')) { 29 | $table->addColumn('extra_settings_json', Types::JSON, [ 30 | 'notnull' => false, 31 | ]); 32 | 33 | return $schema; 34 | } 35 | 36 | return null; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /lib/Migration/Version030000Date20220926200602.php: -------------------------------------------------------------------------------- 1 | connection = $connection; 27 | } 28 | 29 | /** 30 | * @param IOutput $output 31 | * @param Closure $schemaClosure The `\Closure` returns a `ISchemaWrapper` 32 | * @param array $options 33 | */ 34 | public function postSchemaChange(IOutput $output, Closure $schemaClosure, array $options): void { 35 | $qb = $this->connection->getQueryBuilder(); 36 | 37 | // Set old questions with empty description. 38 | $qb->update('forms_v2_questions') 39 | ->set('description', $qb->expr()->literal('')) 40 | ->where($qb->expr()->isNull('description')) 41 | ->executeStatement(); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /lib/Migration/Version030100Date20221231100426.php: -------------------------------------------------------------------------------- 1 | getTable('forms_v2_forms'); 32 | 33 | if (!$table->hasColumn('show_expiration')) { 34 | $table->addColumn('show_expiration', Types::BOOLEAN, [ 35 | 'notnull' => false, 36 | 'default' => 0, 37 | ]); 38 | 39 | return $schema; 40 | } 41 | 42 | return null; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /lib/Migration/Version030100Date20230115214242.php: -------------------------------------------------------------------------------- 1 | ensureColumnIsNullable($schema, 'forms_v2_answers', 'text'); 29 | $result |= $this->ensureColumnIsNullable($schema, 'forms_v2_forms', 'title'); 30 | $result |= $this->ensureColumnIsNullable($schema, 'forms_v2_options', 'text'); 31 | $result |= $this->ensureColumnIsNullable($schema, 'forms_v2_questions', 'order'); 32 | $result |= $this->ensureColumnIsNullable($schema, 'forms_v2_questions', 'text'); 33 | $result |= $this->ensureColumnIsNullable($schema, 'forms_v2_shares', 'share_type'); 34 | 35 | return $result ? $schema : null; 36 | } 37 | 38 | protected function ensureColumnIsNullable(ISchemaWrapper $schema, string $tableName, string $columnName): bool { 39 | $table = $schema->getTable($tableName); 40 | $column = $table->getColumn($columnName); 41 | 42 | if ($column->getNotnull()) { 43 | $column->setNotnull(false); 44 | return true; 45 | } 46 | 47 | return false; 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /lib/Migration/Version030100Date20230123182700.php: -------------------------------------------------------------------------------- 1 | getTable('forms_v2_shares'); 29 | 30 | if (!$table->hasColumn('permissions_json')) { 31 | $table->addColumn('permissions_json', Types::JSON, [ 32 | 'notnull' => false, 33 | ]); 34 | 35 | return $schema; 36 | } 37 | 38 | return null; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /lib/Migration/Version030100Date20230202175747.php: -------------------------------------------------------------------------------- 1 | getTable('forms_v2_forms'); 30 | 31 | if (!$table->hasColumn('last_updated')) { 32 | $table->addColumn('last_updated', Types::INTEGER, [ 33 | 'notnull' => false, 34 | 'default' => 0, 35 | 'comment' => 'unix-timestamp', 36 | ]); 37 | 38 | return $schema; 39 | } 40 | 41 | return null; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /lib/Migration/Version030200Date20230307141800.php: -------------------------------------------------------------------------------- 1 | getTable('forms_v2_questions'); 30 | 31 | if (!$table->hasColumn('name')) { 32 | $table->addColumn('name', Types::STRING, [ 33 | 'notnull' => false, 34 | 'default' => '', 35 | 'comment' => 'technical-identifier', 36 | ]); 37 | 38 | return $schema; 39 | } 40 | 41 | return null; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /lib/Migration/Version030400Date20230628011500.php: -------------------------------------------------------------------------------- 1 | getTable('forms_v2_forms'); 30 | 31 | if (!$table->hasColumn('submission_message')) { 32 | $table->addColumn('submission_message', Types::STRING, [ 33 | 'notnull' => false, 34 | 'default' => null, 35 | 'length' => 2048, 36 | 'comment' => 'custom thank you message', 37 | ]); 38 | 39 | return $schema; 40 | } 41 | 42 | return null; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /lib/Migration/Version040010Date20240122133700.php: -------------------------------------------------------------------------------- 1 | getTable('forms_v2_forms'); 30 | $table->addColumn('file_id', Types::BIGINT, [ 31 | 'notnull' => false, 32 | 'default' => null, 33 | 'length' => 11, 34 | 'unsigned' => true, 35 | ]); 36 | 37 | $table->addColumn('file_format', Types::STRING, [ 38 | 'notnull' => false, 39 | 'default' => null, 40 | 'length' => 5, 41 | ]); 42 | 43 | return $schema; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /lib/Migration/Version040200Date20240402224725.php: -------------------------------------------------------------------------------- 1 | getTable('forms_v2_forms'); 33 | 34 | if ($table->hasColumn('access_json') && $table->hasColumn('access_enum')) { 35 | $table->dropColumn('access_json'); 36 | return $schema; 37 | } 38 | 39 | return null; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /lib/Migration/Version040300Date20240420155356.php: -------------------------------------------------------------------------------- 1 | getTable('forms_v2_options'); 33 | 34 | // Abort if already existing. 35 | if ($table->hasColumn('order')) { 36 | return null; 37 | } 38 | 39 | // Create new column 40 | $table->addColumn('order', Types::INTEGER, [ 41 | 'notnull' => false, 42 | 'default' => null, 43 | 'unsigned' => true, 44 | ]); 45 | 46 | // Add index for better performance 47 | $table->addIndex(['question_id', 'order'], 'forms_options_question_order'); 48 | 49 | return $schema; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /lib/Migration/Version040300Date20240708163401.php: -------------------------------------------------------------------------------- 1 | getTable('forms_v2_submissions'); 29 | if (!$table->hasIndex('forms_submissions_form_user')) { 30 | $table->addIndex(['form_id', 'user_id'], 'forms_submissions_form_user'); 31 | } 32 | 33 | return $schema; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /lib/Migration/Version050000Date20241005173955.php: -------------------------------------------------------------------------------- 1 | db->getQueryBuilder(); 33 | 34 | $qbUpdate->update('forms_v2_forms') 35 | ->set('access_enum', $qbUpdate->func()->subtract( 36 | 'access_enum', 37 | $qbUpdate->createNamedParameter(3, IQueryBuilder::PARAM_INT) 38 | )) 39 | ->where($qbUpdate->expr()->gte('access_enum', $qbUpdate->createNamedParameter(3, IQueryBuilder::PARAM_INT))) 40 | ->executeStatement(); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /lib/Migration/Version050004Date20250319180638.php: -------------------------------------------------------------------------------- 1 | hasTable('forms_v2_uploaded_files')) { 33 | $table = $schema->getTable('forms_v2_uploaded_files'); 34 | $table->dropPrimaryKey(); 35 | $table->setPrimaryKey(['id'], 'forms_upload_files_id'); 36 | } 37 | 38 | return $schema; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /lib/Migration/Version050200Date20250109201500.php: -------------------------------------------------------------------------------- 1 | getTable('forms_v2_forms'); 30 | 31 | if (!$table->hasColumn('allow_edit_submissions')) { 32 | $table->addColumn('allow_edit_submissions', Types::BOOLEAN, [ 33 | 'notnull' => false, 34 | 'default' => 0, 35 | ]); 36 | 37 | return $schema; 38 | } 39 | 40 | return null; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /lib/Search/FormsSearchResultEntry.php: -------------------------------------------------------------------------------- 1 | linkToRoute('forms.page.views', ['hash' => $form->getHash(), 'view' => 'submit']); 19 | $iconURL = $urlGenerator->getAbsoluteURL(($urlGenerator->imagePath(Application::APP_ID, 'forms-dark.svg'))); 20 | parent::__construct($iconURL, $form->getTitle(), $form->getDescription(), $formURL, 'icon-forms'); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /lib/Search/SearchProvider.php: -------------------------------------------------------------------------------- 1 | l10n->t('Forms'); 38 | } 39 | 40 | public function search(IUser $user, ISearchQuery $query): SearchResult { 41 | $forms = $this->formsService->search($query); 42 | 43 | $results = array_map(function (Form $form) { 44 | return [ 45 | 'object' => $form, 46 | 'entry' => new FormsSearchResultEntry($form, $this->urlGenerator) 47 | ]; 48 | }, $forms); 49 | 50 | $resultEntries = array_map(function (array $result) { 51 | return $result['entry']; 52 | }, $results); 53 | 54 | return SearchResult::complete( 55 | $this->l10n->t('Forms'), 56 | $resultEntries 57 | ); 58 | } 59 | 60 | public function getOrder(string $route, array $routeParameters): int { 61 | if (str_contains($route, Application::APP_ID)) { 62 | // Active app, prefer my results 63 | return -1; 64 | } 65 | return 77; 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /lib/Settings/Settings.php: -------------------------------------------------------------------------------- 1 | groupManager->search(''); 35 | foreach ($groups as $group) { 36 | $formattedGroups[] = [ 37 | 'groupId' => $group->getGID(), 38 | 'displayName' => $group->getDisplayName() 39 | ]; 40 | } 41 | return $formattedGroups; 42 | } 43 | 44 | public function getForm(): TemplateResponse { 45 | Util::addStyle($this->appName, 'forms-style'); 46 | Util::addScript($this->appName, 'forms-settings'); 47 | $this->initialState->provideInitialState('availableGroups', $this->getAvailableGroups()); 48 | $this->initialState->provideInitialState('appConfig', $this->configService->getAppConfig()); 49 | 50 | return new TemplateResponse($this->appName, 'settings'); 51 | } 52 | 53 | public function getSection(): string { 54 | return 'forms'; 55 | } 56 | 57 | public function getPriority(): int { 58 | return 50; 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /lib/Settings/SettingsSection.php: -------------------------------------------------------------------------------- 1 | l10n->t('Forms'); 38 | } 39 | 40 | /** 41 | * Priority of the Section. Using Priority here as on Navigationorder. 42 | * 43 | * @return int between 0-99 44 | */ 45 | public function getPriority(): int { 46 | return 77; 47 | } 48 | 49 | /** 50 | * Section Icon 51 | * 52 | * @return string Relative Path to the icon 53 | */ 54 | public function getIcon(): string { 55 | return $this->urlGenerator->imagePath('forms', 'forms-dark.svg'); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /playwright/start-nextcloud-server.mjs: -------------------------------------------------------------------------------- 1 | /** 2 | * SPDX-FileCopyrightText: 2024 Ferdinand Thiessen 3 | * SPDX-License-Identifier: AGPL-3.0-or-later 4 | */ 5 | 6 | import { startNextcloud, stopNextcloud } from '@nextcloud/e2e-test-server/docker' 7 | import { readFileSync } from 'fs' 8 | 9 | const start = async () => { 10 | const appinfo = readFileSync('appinfo/info.xml').toString() 11 | const maxVersion = appinfo.match( 12 | //, 13 | )?.[1] 14 | const branch = maxVersion ? `stable${maxVersion}` : undefined 15 | 16 | return await startNextcloud(branch, true, { 17 | exposePort: 8089, 18 | }) 19 | } 20 | 21 | // Start the Nextcloud docker container 22 | await start() 23 | // Listen for process to exit (tests done) and shut down the docker container 24 | process.on('beforeExit', (code) => { 25 | stopNextcloud() 26 | }) 27 | 28 | // Idle to wait for shutdown 29 | while (true) { 30 | await new Promise((resolve) => setTimeout(resolve, 5000)) 31 | } 32 | -------------------------------------------------------------------------------- /playwright/support/fixtures/form.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * SPDX-FileCopyrightText: 2024 Ferdinand Thiessen 3 | * SPDX-License-Identifier: AGPL-3.0-or-later 4 | */ 5 | 6 | import { test as baseTest } from '@playwright/test' 7 | import { FormSection } from '../sections/FormSection' 8 | 9 | interface FormFixture { 10 | form: FormSection 11 | } 12 | 13 | export const test = baseTest.extend({ 14 | form: async ({ page }, use) => { 15 | const form = new FormSection(page) 16 | await use(form) 17 | }, 18 | }) 19 | -------------------------------------------------------------------------------- /playwright/support/fixtures/navigation.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * SPDX-FileCopyrightText: 2024 Ferdinand Thiessen 3 | * SPDX-License-Identifier: AGPL-3.0-or-later 4 | */ 5 | 6 | import { test as baseTest } from '@playwright/test' 7 | import { AppNavigationSection } from '../sections/AppNavigationSection' 8 | 9 | interface AppNavigationFixture { 10 | appNavigation: AppNavigationSection 11 | } 12 | 13 | export const test = baseTest.extend({ 14 | appNavigation: async ({ page }, use) => { 15 | const appNavigation = new AppNavigationSection(page) 16 | await use(appNavigation) 17 | }, 18 | }) 19 | -------------------------------------------------------------------------------- /playwright/support/fixtures/random-user.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * SPDX-FileCopyrightText: 2024 Ferdinand Thiessen 3 | * SPDX-License-Identifier: AGPL-3.0-or-later 4 | */ 5 | 6 | import { test as base } from '@playwright/test' 7 | import { createRandomUser, login } from '@nextcloud/e2e-test-server/playwright' 8 | 9 | /** 10 | * This test fixture ensures a new random user is created and used for the test (current page) 11 | */ 12 | export const test = base.extend({ 13 | page: async ({ browser, baseURL }, use) => { 14 | // Important: make sure we authenticate in a clean environment by unsetting storage state. 15 | const page = await browser.newPage({ 16 | storageState: undefined, 17 | baseURL, 18 | }) 19 | 20 | const user = await createRandomUser() 21 | await login(page.request, user) 22 | 23 | await use(page) 24 | await page.close() 25 | }, 26 | }) 27 | -------------------------------------------------------------------------------- /playwright/support/fixtures/topBar.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * SPDX-FileCopyrightText: 2024 Ferdinand Thiessen 3 | * SPDX-License-Identifier: AGPL-3.0-or-later 4 | */ 5 | 6 | import { test as baseTest } from '@playwright/test' 7 | import { TopBarSection } from '../sections/TopBarSection' 8 | 9 | interface TopBarFixture { 10 | topBar: TopBarSection 11 | } 12 | 13 | export const test = baseTest.extend({ 14 | topBar: async ({ page }, use) => { 15 | const form = new TopBarSection(page) 16 | await use(form) 17 | }, 18 | }) 19 | -------------------------------------------------------------------------------- /playwright/support/sections/AppNavigationSection.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * SPDX-FileCopyrightText: 2024 Ferdinand Thiessen 3 | * SPDX-License-Identifier: AGPL-3.0-or-later 4 | */ 5 | 6 | import type { Locator, Page } from '@playwright/test' 7 | 8 | export class AppNavigationSection { 9 | public readonly navigationLocator: Locator 10 | public readonly newFormLocator: Locator 11 | public readonly ownFormsLocator: Locator 12 | public readonly sharedFormsLocator: Locator 13 | 14 | // eslint-disable-next-line no-useless-constructor 15 | constructor(public readonly page: Page) { 16 | this.navigationLocator = this.page.getByRole('navigation', { 17 | name: 'Forms navigation', 18 | }) 19 | this.newFormLocator = this.navigationLocator.getByRole('button', { 20 | name: 'New form', 21 | }) 22 | this.ownFormsLocator = this.navigationLocator 23 | .getByRole('list', { name: 'Your forms' }) 24 | .getByRole('listitem') 25 | this.sharedFormsLocator = this.navigationLocator 26 | .getByRole('button', { name: 'Shared forms' }) 27 | .getByRole('listitem') 28 | } 29 | 30 | public async clickNewForm(): Promise { 31 | await this.newFormLocator.click() 32 | await this.page.waitForURL(/apps\/forms\/.+/) 33 | } 34 | 35 | public async openArchivedForms(): Promise { 36 | await this.navigationLocator 37 | .getByRole('button', { name: 'Archived forms' }) 38 | .click() 39 | } 40 | 41 | public getOwnForm(name: string | RegExp): Locator { 42 | return this.ownFormsLocator.getByRole('link', { name }) 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /playwright/support/sections/QuestionSection.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * SPDX-FileCopyrightText: 2024 Ferdinand Thiessen 3 | * SPDX-License-Identifier: AGPL-3.0-or-later 4 | */ 5 | 6 | import type { Locator, Page } from '@playwright/test' 7 | 8 | export class QuestionSection { 9 | public readonly titleInput: Locator 10 | public readonly newAnswerInput: Locator 11 | public readonly answerInputs: Locator 12 | 13 | // eslint-disable-next-line no-useless-constructor 14 | constructor( 15 | public readonly page: Page, 16 | public readonly section: Locator, 17 | ) { 18 | this.titleInput = this.section.getByRole('textbox', { 19 | name: /title of/i, 20 | }) 21 | this.newAnswerInput = this.section.getByRole('textbox', { 22 | name: 'Add a new answer option', 23 | }) 24 | this.answerInputs = this.section.getByRole('textbox', { 25 | name: /The text of option \d+/i, 26 | }) 27 | } 28 | 29 | async fillTitle(title: string): Promise { 30 | await this.titleInput.fill(title) 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /playwright/support/sections/QuestionType.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * SPDX-FileCopyrightText: 2024 Ferdinand Thiessen 3 | * SPDX-License-Identifier: AGPL-3.0-or-later 4 | */ 5 | 6 | export enum QuestionType { 7 | Checkboxes = 'Checkboxes', 8 | Dropdown = 'Dropdown', 9 | } 10 | -------------------------------------------------------------------------------- /playwright/support/sections/TopBarSection.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * SPDX-FileCopyrightText: 2024 Ferdinand Thiessen 3 | * SPDX-License-Identifier: AGPL-3.0-or-later 4 | */ 5 | 6 | import type { Locator, Page } from '@playwright/test' 7 | 8 | export enum FormsView { 9 | View = 'View', 10 | Edit = 'Edit', 11 | Results = 'Results', 12 | } 13 | 14 | export class TopBarSection { 15 | public readonly toolbar: Locator 16 | 17 | // eslint-disable-next-line no-useless-constructor 18 | constructor(public readonly page: Page) { 19 | this.toolbar = this.page.getByRole('toolbar', { name: 'View mode' }) 20 | } 21 | 22 | public async getActiveView(): Promise { 23 | return this.toolbar.getByRole('radio', { checked: true }) 24 | } 25 | 26 | public async getAllViews(): Promise { 27 | return this.toolbar.getByRole('radio') 28 | } 29 | 30 | public async toggleView(view: FormsView): Promise { 31 | const radio = this.toolbar.getByRole('radio', { name: view }) 32 | if (await radio.isChecked()) { 33 | return 34 | } 35 | await radio.check({ force: true }) // force is needed as the input element is hidden behind the icon 36 | await this.page.waitForURL(/\/submit$/) 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /playwright/support/setup.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * SPDX-FileCopyrightText: 2024 Ferdinand Thiessen 3 | * SPDX-License-Identifier: AGPL-3.0-or-later 4 | */ 5 | 6 | import { test as setup } from '@playwright/test' 7 | import { configureNextcloud } from '@nextcloud/e2e-test-server/docker' 8 | 9 | /** 10 | * We use this to ensure Nextcloud is configured correctly before running our tests 11 | * 12 | * This can not be done in the webserver startup process, 13 | * as that only checks for the URL to be accessible which happens already before everything is configured. 14 | */ 15 | setup('Configure Nextcloud', async () => { 16 | await configureNextcloud(['forms']) 17 | }) 18 | -------------------------------------------------------------------------------- /screenshots/forms1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nextcloud/forms/ddc8a45e410efba1aaedaf72e2a109b6a199cf7e/screenshots/forms1.png -------------------------------------------------------------------------------- /screenshots/forms2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nextcloud/forms/ddc8a45e410efba1aaedaf72e2a109b6a199cf7e/screenshots/forms2.png -------------------------------------------------------------------------------- /screenshots/forms3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/nextcloud/forms/ddc8a45e410efba1aaedaf72e2a109b6a199cf7e/screenshots/forms3.png -------------------------------------------------------------------------------- /src/components/Icons/FormsIcon.vue: -------------------------------------------------------------------------------- 1 | 5 | 6 | 26 | 27 | 46 | -------------------------------------------------------------------------------- /src/components/Icons/IconCopyAll.vue: -------------------------------------------------------------------------------- 1 | 5 | 6 | 26 | 27 | 46 | -------------------------------------------------------------------------------- /src/components/Icons/IconDragIndicator.vue: -------------------------------------------------------------------------------- 1 | 5 | 6 | 26 | 27 | 46 | -------------------------------------------------------------------------------- /src/components/Icons/IconLinearScale.vue: -------------------------------------------------------------------------------- 1 | 5 | 6 | 26 | 27 | 46 | -------------------------------------------------------------------------------- /src/components/Icons/IconOverlay.vue: -------------------------------------------------------------------------------- 1 | 5 | 6 | 14 | 15 | 16 | 17 | 30 | -------------------------------------------------------------------------------- /src/emptyContent.js: -------------------------------------------------------------------------------- 1 | /** 2 | * SPDX-FileCopyrightText: 2022 Nextcloud GmbH and Nextcloud contributors 3 | * SPDX-License-Identifier: AGPL-3.0-or-later 4 | */ 5 | import { translate, translatePlural } from '@nextcloud/l10n' 6 | import Vue from 'vue' 7 | 8 | import FormsEmptyContent from './FormsEmptyContent.vue' 9 | 10 | // eslint-disable-next-line import/no-unresolved, n/no-missing-import 11 | import 'vite/modulepreload-polyfill' 12 | 13 | Vue.prototype.t = translate 14 | Vue.prototype.n = translatePlural 15 | 16 | export default new Vue({ 17 | el: '#content', 18 | // eslint-disable-next-line vue/match-component-file-name 19 | name: 'FormsEmptyContent', 20 | render: (h) => h(FormsEmptyContent), 21 | }) 22 | -------------------------------------------------------------------------------- /src/main.js: -------------------------------------------------------------------------------- 1 | /** 2 | * SPDX-FileCopyrightText: 2018 Nextcloud GmbH and Nextcloud contributors 3 | * SPDX-License-Identifier: AGPL-3.0-or-later 4 | */ 5 | 6 | import { translate, translatePlural } from '@nextcloud/l10n' 7 | 8 | import Tooltip from '@nextcloud/vue/dist/Directives/Tooltip.js' 9 | import Vue from 'vue' 10 | 11 | import router from './router.js' 12 | import Forms from './Forms.vue' 13 | 14 | // eslint-disable-next-line import/no-unresolved, n/no-missing-import 15 | import 'vite/modulepreload-polyfill' 16 | import '@nextcloud/dialogs/style.css' 17 | 18 | Vue.directive('tooltip', Tooltip) 19 | 20 | Vue.prototype.t = translate 21 | Vue.prototype.n = translatePlural 22 | 23 | export default new Vue({ 24 | el: '#content', 25 | // eslint-disable-next-line vue/match-component-file-name 26 | name: 'FormsRoot', 27 | router, 28 | render: (h) => h(Forms), 29 | }) 30 | -------------------------------------------------------------------------------- /src/mixins/PermissionTypes.js: -------------------------------------------------------------------------------- 1 | /** 2 | * SPDX-FileCopyrightText: 2021 Nextcloud GmbH and Nextcloud contributors 3 | * SPDX-License-Identifier: AGPL-3.0-or-later 4 | */ 5 | 6 | export default { 7 | data() { 8 | return { 9 | /** 10 | * !!! Keep in Sync with lib/Constants.php !! 11 | */ 12 | PERMISSION_TYPES: { 13 | PERMISSION_EDIT: 'edit', 14 | PERMISSION_RESULTS: 'results', 15 | PERMISSION_RESULTS_DELETE: 'results_delete', 16 | PERMISSION_SUBMIT: 'submit', 17 | /** Internal permission to mark public link shares as embeddable */ 18 | PERMISSION_EMBED: 'embed', 19 | PERMISSION_ALL: [ 20 | this.PERMISSION_EDIT, 21 | this.PERMISSION_RESULTS, 22 | this.PERMISSION_RESULTS_DELETE, 23 | this.PERMISSION_SUBMIT, 24 | ], 25 | }, 26 | } 27 | }, 28 | } 29 | -------------------------------------------------------------------------------- /src/models/Constants.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors 3 | * SPDX-License-Identifier: AGPL-3.0-or-later 4 | */ 5 | 6 | /** 7 | * Represents the state of a form. 8 | * 9 | * Possible values: 10 | * - `FormActive` (0): The form is currently active and can be interacted with. 11 | * - `FormClosed` (1): The form is closed and no longer accepting input. 12 | * - `FormArchived` (2): The form is archived and stored for reference. 13 | * 14 | * Keep in sync with Constants.php 15 | */ 16 | export enum FormState { 17 | FormActive = 0, 18 | FormClosed = 1, 19 | FormArchived = 2, 20 | } 21 | 22 | /** 23 | * The debounce time in milliseconds for input events. 24 | * 25 | * This constant is used to limit the rate at which input-related 26 | * operations are triggered, improving performance and user experience. 27 | */ 28 | export const INPUT_DEBOUNCE_MS = 400 29 | 30 | /** 31 | * A constant representing the prefix used for identifying "other" answers 32 | */ 33 | export const QUESTION_EXTRASETTINGS_OTHER_PREFIX = 'system-other-answer:' 34 | -------------------------------------------------------------------------------- /src/models/Entities.d.ts: -------------------------------------------------------------------------------- 1 | /** 2 | * SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors 3 | * SPDX-License-Identifier: AGPL-3.0-or-later 4 | */ 5 | export interface FormsOption { 6 | local?: boolean 7 | id: number 8 | text: string 9 | order?: number 10 | questionId: number 11 | } 12 | -------------------------------------------------------------------------------- /src/models/FileTypes.js: -------------------------------------------------------------------------------- 1 | /** 2 | * SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors 3 | * SPDX-License-Identifier: AGPL-3.0-or-later 4 | */ 5 | 6 | import { translate as t } from '@nextcloud/l10n' 7 | // !! Keep in SYNC with lib/Constants.php for supported file types \OCA\Forms\Constants::EXTRA_SETTINGS_ALLOWED_FILE_TYPES !! 8 | export default { 9 | image: { 10 | label: t('forms', 'Image'), 11 | }, 12 | 'x-office/document': { 13 | label: t('forms', 'Document'), 14 | }, 15 | 'x-office/presentation': { 16 | label: t('forms', 'Presentation'), 17 | }, 18 | 'x-office/spreadsheet': { 19 | label: t('forms', 'Spreadsheet'), 20 | }, 21 | } 22 | -------------------------------------------------------------------------------- /src/router.js: -------------------------------------------------------------------------------- 1 | /** 2 | * SPDX-FileCopyrightText: 2018 Nextcloud GmbH and Nextcloud contributors 3 | * SPDX-License-Identifier: AGPL-3.0-or-later 4 | */ 5 | 6 | import Vue from 'vue' 7 | import Router from 'vue-router' 8 | import { generateUrl } from '@nextcloud/router' 9 | 10 | import Create from './views/Create.vue' 11 | import Results from './views/Results.vue' 12 | import Submit from './views/Submit.vue' 13 | 14 | Vue.use(Router) 15 | 16 | export default new Router({ 17 | mode: 'history', 18 | 19 | // if index.php is in the url AND we got this far, then it's working: 20 | // let's keep using index.php in the url 21 | base: generateUrl('/apps/forms', ''), 22 | linkActiveClass: 'active', 23 | 24 | routes: [ 25 | { 26 | path: '/', 27 | name: 'root', 28 | }, 29 | { 30 | path: '/:hash', 31 | redirect: { name: 'submit' }, 32 | name: 'formRoot', 33 | props: true, 34 | }, 35 | { 36 | path: '/:hash/edit', 37 | components: { 38 | default: Create, 39 | }, 40 | name: 'edit', 41 | props: { default: true }, 42 | }, 43 | { 44 | path: '/:hash/results', 45 | components: { 46 | default: Results, 47 | }, 48 | name: 'results', 49 | props: { default: true }, 50 | }, 51 | { 52 | path: '/:hash/submit/:submissionId?', 53 | components: { 54 | default: Submit, 55 | }, 56 | name: 'submit', 57 | props: { default: true }, 58 | }, 59 | ], 60 | }) 61 | -------------------------------------------------------------------------------- /src/scssmixins/markdownOutput.scss: -------------------------------------------------------------------------------- 1 | /** 2 | * SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors 3 | * SPDX-License-Identifier: AGPL-3.0-or-later 4 | */ 5 | 6 | @mixin markdown-output { 7 | & { 8 | overflow-wrap: break-word; 9 | } 10 | 11 | :deep() { 12 | > :not(:first-child) { 13 | margin-block-start: 1.5em; 14 | } 15 | 16 | h1 { 17 | font-size: 28px; 18 | font-weight: bold; 19 | line-height: 34px; 20 | margin-bottom: 12px; 21 | color: var(--color-main-text); 22 | } 23 | 24 | a { 25 | color: var(--color-primary-element); 26 | text-decoration: underline; 27 | } 28 | 29 | blockquote { 30 | padding-inline-start: 1em; 31 | border-inline-start: 4px solid var(--color-primary-element); 32 | color: var(--color-text-maxcontrast); 33 | } 34 | 35 | pre { 36 | white-space: pre-wrap; 37 | background-color: var(--color-background-dark); 38 | border-radius: var(--border-radius); 39 | padding-block: 1em; 40 | padding-inline: 1.3em; 41 | } 42 | 43 | p code { 44 | background-color: var(--color-background-dark); 45 | border-radius: var(--border-radius); 46 | padding-block: 0.1em; 47 | padding-inline: 0.3em; 48 | } 49 | 50 | ul, 51 | ol { 52 | padding-inline-start: 10px; 53 | margin-inline-start: 10px; 54 | } 55 | 56 | ul { 57 | > li { 58 | list-style-type: disc; 59 | } 60 | 61 | // Second-level list entries 62 | li ul > li { 63 | list-style-type: circle; 64 | } 65 | 66 | // Third+-level list entries 67 | li li ul > li { 68 | list-style-type: square; 69 | } 70 | } 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /src/settings.js: -------------------------------------------------------------------------------- 1 | /** 2 | * SPDX-FileCopyrightText: 2022 Nextcloud GmbH and Nextcloud contributors 3 | * SPDX-License-Identifier: AGPL-3.0-or-later 4 | */ 5 | 6 | import { translate, translatePlural } from '@nextcloud/l10n' 7 | import Vue from 'vue' 8 | 9 | import FormsSettings from './FormsSettings.vue' 10 | 11 | // eslint-disable-next-line import/no-unresolved, n/no-missing-import 12 | import 'vite/modulepreload-polyfill' 13 | 14 | Vue.prototype.t = translate 15 | Vue.prototype.n = translatePlural 16 | 17 | export default new Vue({ 18 | el: '#forms-settings', 19 | // eslint-disable-next-line vue/match-component-file-name 20 | name: 'FormsSettings', 21 | render: (h) => h(FormsSettings), 22 | }) 23 | -------------------------------------------------------------------------------- /src/submit.js: -------------------------------------------------------------------------------- 1 | /** 2 | * SPDX-FileCopyrightText: 2020 Nextcloud GmbH and Nextcloud contributors 3 | * SPDX-License-Identifier: AGPL-3.0-or-later 4 | */ 5 | 6 | import { translate, translatePlural } from '@nextcloud/l10n' 7 | import Vue from 'vue' 8 | 9 | import FormsSubmitRoot from './FormsSubmit.vue' 10 | 11 | // eslint-disable-next-line import/no-unresolved, n/no-missing-import 12 | import 'vite/modulepreload-polyfill' 13 | 14 | Vue.prototype.t = translate 15 | Vue.prototype.n = translatePlural 16 | 17 | export default new Vue({ 18 | el: '#content', 19 | // eslint-disable-next-line vue/match-component-file-name 20 | name: 'FormsSubmitRoot', 21 | render: (h) => h(FormsSubmitRoot), 22 | }) 23 | -------------------------------------------------------------------------------- /src/utils/CancelableRequest.js: -------------------------------------------------------------------------------- 1 | /** 2 | * SPDX-FileCopyrightText: 2019 Nextcloud GmbH and Nextcloud contributors 3 | * SPDX-License-Identifier: AGPL-3.0-or-later 4 | */ 5 | 6 | import axios from '@nextcloud/axios' 7 | 8 | /** 9 | * Creates a cancelable axios 'request object'. 10 | * 11 | * @param {Function} request the axios promise request 12 | * @return {object} 13 | */ 14 | const CancelableRequest = function (request) { 15 | /** 16 | * Generate an axios cancel token 17 | */ 18 | const CancelToken = axios.CancelToken 19 | const source = CancelToken.source() 20 | 21 | /** 22 | * Execute the request 23 | * 24 | * @param {string} url the url to send the request to 25 | * @param {object} [options] optional config for the request 26 | */ 27 | const fetch = async function (url, options) { 28 | return request( 29 | url, 30 | Object.assign({ cancelToken: source.token }, { ...options }), 31 | ) 32 | } 33 | return { 34 | request: fetch, 35 | cancel: source.cancel, 36 | } 37 | } 38 | 39 | export default CancelableRequest 40 | -------------------------------------------------------------------------------- /src/utils/Logger.js: -------------------------------------------------------------------------------- 1 | /** 2 | * SPDX-FileCopyrightText: 2022 Nextcloud GmbH and Nextcloud contributors 3 | * SPDX-License-Identifier: AGPL-3.0-or-later 4 | */ 5 | 6 | import { getLoggerBuilder } from '@nextcloud/logger' 7 | 8 | const logger = getLoggerBuilder().setApp('forms').detectUser().build() 9 | 10 | export default logger 11 | -------------------------------------------------------------------------------- /src/utils/OcsResponse2Data.js: -------------------------------------------------------------------------------- 1 | /** 2 | * SPDX-FileCopyrightText: 2021 Nextcloud GmbH and Nextcloud contributors 3 | * SPDX-License-Identifier: AGPL-3.0-or-later 4 | */ 5 | 6 | /** 7 | * Extract actual data from Axios OCS response 8 | * Just a small wrapper for nice code. 9 | * 10 | * @param {object} response response returned by axios 11 | * @return {object} The actual data out of the ocs response 12 | */ 13 | const OcsResponse2Data = function (response) { 14 | return response.data.ocs.data 15 | } 16 | 17 | export default OcsResponse2Data 18 | -------------------------------------------------------------------------------- /src/utils/RegularExpression.js: -------------------------------------------------------------------------------- 1 | /** 2 | * SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors 3 | * SPDX-License-Identifier: AGPL-3.0-or-later 4 | */ 5 | 6 | /** 7 | * Validate a regex, ensures enclosed with delimiters and only supported modifiers by PHP *and* JS 8 | */ 9 | const REGEX_WITH_DELIMITERS = /^\/(.+)\/([smi]{0,3})$/ 10 | /** 11 | * Find unescaped slashes within a string 12 | */ 13 | const REGEX_UNESCAPED_SLASH = /(?:^|[^\\])(?:\\\\)*\// 14 | 15 | /** 16 | * Check if a regex is valid and enclosed with delimiters 17 | * 18 | * @param {string} input regular expression 19 | * @return {boolean} 20 | */ 21 | export function validateExpression(input) { 22 | // empty regex passes 23 | if (input.length === 0) { 24 | return true 25 | } 26 | 27 | // Validate regex has delimters 28 | if (!REGEX_WITH_DELIMITERS.test(input)) { 29 | return false 30 | } 31 | 32 | // Check pattern is escaped 33 | const { pattern, modifiers } = splitRegex(input) 34 | if (REGEX_UNESCAPED_SLASH.test(pattern)) { 35 | return false 36 | } 37 | 38 | // Check if regular expression can be compiled 39 | try { 40 | ;(() => new RegExp(pattern, modifiers))() 41 | return true 42 | } catch (e) { 43 | return false 44 | } 45 | } 46 | 47 | /** 48 | * Split an enclosed regular expression into pattern and modifiers 49 | * 50 | * @param {string} regex regular expression with delimiters 51 | * @return {{pattern: string, modifiers: string}} pattern and modifiers 52 | */ 53 | export function splitRegex(regex) { 54 | const [, pattern, modifiers] = regex.match(REGEX_WITH_DELIMITERS) || ['', '', ''] 55 | return { pattern, modifiers } 56 | } 57 | -------------------------------------------------------------------------------- /src/utils/SetWindowTitle.js: -------------------------------------------------------------------------------- 1 | /** 2 | * SPDX-FileCopyrightText: 2020 Nextcloud GmbH and Nextcloud contributors 3 | * SPDX-License-Identifier: AGPL-3.0-or-later 4 | */ 5 | 6 | /** 7 | * Set the Window-Title to current FormTitle including suffix. 8 | * 9 | * @param {string} formTitle Title of current form to set on window. 10 | */ 11 | const SetWindowTitle = function (formTitle) { 12 | if (formTitle === '') { 13 | window.document.title = t('forms', 'Forms') + ' - ' + OC.theme.title 14 | } else { 15 | window.document.title = 16 | formTitle + ' - ' + t('forms', 'Forms') + ' - ' + OC.theme.title 17 | } 18 | } 19 | 20 | export default SetWindowTitle 21 | -------------------------------------------------------------------------------- /stylelint.config.cjs: -------------------------------------------------------------------------------- 1 | /** 2 | * SPDX-FileCopyrightText: 2021 Nextcloud GmbH and Nextcloud contributors 3 | * SPDX-License-Identifier: AGPL-3.0-or-later 4 | */ 5 | 6 | const stylelintConfig = require('@nextcloud/stylelint-config') 7 | 8 | module.exports = stylelintConfig 9 | -------------------------------------------------------------------------------- /templates/main.php: -------------------------------------------------------------------------------- 1 | 7 | 8 |
9 | -------------------------------------------------------------------------------- /templates/settings.php: -------------------------------------------------------------------------------- 1 | 7 | 8 |
9 | -------------------------------------------------------------------------------- /tests/Unit/Activity/Settings/NewShareTest.php: -------------------------------------------------------------------------------- 1 | l10n = $this->createMock(IL10N::class); 26 | $this->newShare = new NewShare('forms', $this->l10n); 27 | } 28 | 29 | public function testGetGroupIdentifier() { 30 | $this->assertEquals('forms', $this->newShare->getGroupIdentifier()); 31 | } 32 | 33 | public function testGetGroupName() { 34 | $this->l10n->expects($this->once()) 35 | ->method('t') 36 | ->will($this->returnCallback(function ($identity) { 37 | return $identity; 38 | })); 39 | $this->assertEquals('Forms', $this->newShare->getGroupName()); 40 | } 41 | 42 | public function testGetIdentifier() { 43 | $this->assertEquals('forms_newshare', $this->newShare->getIdentifier()); 44 | } 45 | 46 | public function testGetName() { 47 | $this->l10n->expects($this->once()) 48 | ->method('t') 49 | ->will($this->returnCallback(function ($identity) { 50 | return $identity; 51 | })); 52 | $this->assertEquals('A form has been shared with you', $this->newShare->getName()); 53 | } 54 | 55 | public function testGetPriority() { 56 | $this->assertEquals(60, $this->newShare->getPriority()); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /tests/Unit/Activity/Settings/NewSubmissionTest.php: -------------------------------------------------------------------------------- 1 | l10n = $this->createMock(IL10N::class); 26 | $this->newShare = new NewSubmission('forms', $this->l10n); 27 | } 28 | 29 | public function testGetGroupIdentifier() { 30 | $this->assertEquals('forms', $this->newShare->getGroupIdentifier()); 31 | } 32 | 33 | public function testGetGroupName() { 34 | $this->l10n->expects($this->once()) 35 | ->method('t') 36 | ->will($this->returnCallback(function ($identity) { 37 | return $identity; 38 | })); 39 | $this->assertEquals('Forms', $this->newShare->getGroupName()); 40 | } 41 | 42 | public function testGetIdentifier() { 43 | $this->assertEquals('forms_newsubmission', $this->newShare->getIdentifier()); 44 | } 45 | 46 | public function testGetName() { 47 | $this->l10n->expects($this->once()) 48 | ->method('t') 49 | ->will($this->returnCallback(function ($identity) { 50 | return $identity; 51 | })); 52 | $this->assertEquals('Someone answered a form', $this->newShare->getName()); 53 | } 54 | 55 | public function testGetPriority() { 56 | $this->assertEquals(61, $this->newShare->getPriority()); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /tests/Unit/BackgroundJob/UserDeletedJobTest.php: -------------------------------------------------------------------------------- 1 | formMapper = $this->createMock(FormMapper::class); 33 | $time = $this->createMock(ITimeFactory::class); 34 | $this->logger = $this->getMockBuilder('Psr\Log\LoggerInterface')->getMock(); 35 | $this->userDeletedJob = new UserDeletedJob($this->formMapper, $time, $this->logger); 36 | } 37 | 38 | public function testHandle() { 39 | $form = $this->createMock(Form::class); 40 | $this->formMapper->expects($this->once()) 41 | ->method('findAllByOwnerId') 42 | ->willReturn([$form, $form, $form]); 43 | $this->formMapper->expects($this->exactly(3)) 44 | ->method('deleteForm') 45 | ->with($form); 46 | 47 | $this->userDeletedJob->run(['owner_id' => 'someUser']); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /tests/Unit/MockedMapperException.php: -------------------------------------------------------------------------------- 1 | 5 | * SPDX-License-Identifier: AGPL-3.0-or-later 6 | */ 7 | 8 | namespace OCA\Forms\Tests\Unit; 9 | 10 | use OCP\AppFramework\Db\IMapperException; 11 | 12 | /** 13 | * Simple wrapper over IMapperException to implement Throwable, needed for throwing a mocked exception 14 | */ 15 | interface MockedMapperException extends IMapperException, \Throwable { 16 | } 17 | -------------------------------------------------------------------------------- /tests/bootstrap.php: -------------------------------------------------------------------------------- 1 | loadApp('forms'); 22 | -------------------------------------------------------------------------------- /tests/phpunit.integration.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | ./Integration 8 | 9 | 10 | 11 | 12 | ../lib 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /tests/phpunit.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | ./Unit 11 | 12 | 13 | 14 | 15 | ../lib 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /tests/stubs/oc_hooks_emitter.php: -------------------------------------------------------------------------------- 1 |