Compare commits

..

1 Commits

Author SHA1 Message Date
bf92374c1e fix(deps): update dependency @kyvg/vue3-notification to v3
Some checks failed
continuous-integration/drone/pr Build is failing
2023-09-15 16:08:47 +00:00
113 changed files with 4802 additions and 10784 deletions

View File

@ -42,7 +42,7 @@ steps:
# - .cache
- name: dependencies
image: node:20.10-alpine
image: node:20.5-alpine
pull: always
environment:
PNPM_CACHE_FOLDER: .cache/pnpm
@ -55,7 +55,7 @@ steps:
# - restore-cache
- name: lint
image: node:20.10-alpine
image: node:20.5-alpine
pull: always
environment:
PNPM_CACHE_FOLDER: .cache/pnpm
@ -66,7 +66,7 @@ steps:
- dependencies
- name: build-prod
image: node:20.10-alpine
image: node:20.5-alpine
pull: always
environment:
PNPM_CACHE_FOLDER: .cache/pnpm
@ -77,7 +77,7 @@ steps:
- dependencies
- name: test-unit
image: node:20.10-alpine
image: node:20.5-alpine
pull: always
commands:
- corepack enable && pnpm config set store-dir .cache/pnpm
@ -87,7 +87,7 @@ steps:
- name: typecheck
failure: ignore
image: node:20.10-alpine
image: node:20.5-alpine
pull: always
environment:
PNPM_CACHE_FOLDER: .cache/pnpm
@ -202,7 +202,7 @@ steps:
# - .cache
- name: build
image: node:20.10-alpine
image: node:20.5-alpine
pull: always
environment:
PNPM_CACHE_FOLDER: .cache/pnpm
@ -285,7 +285,7 @@ steps:
# - .cache
- name: build
image: node:20.10-alpine
image: node:20.5-alpine
pull: always
environment:
PNPM_CACHE_FOLDER: .cache/pnpm
@ -532,6 +532,6 @@ steps:
src/i18n/lang/en.json: en.json
---
kind: signature
hmac: 3380c4283256eea047e6228817161991d23457d09abe9d99f06e018b1eb047f4
hmac: 8df53c07dc07c8a22c4aca9effd0ef8335cbed6ed55c00caeb335e6bc15458a6
...

View File

@ -1,23 +0,0 @@
name: 'Repo Lockdown'
on:
pull_request_target:
types: opened
permissions:
issues: write
pull-requests: write
jobs:
action:
runs-on: ubuntu-latest
steps:
- uses: dessant/repo-lockdown@v4
with:
pr-comment: 'Hi! Thank you for your contribution.
This repo is only a mirror and unfortunately we can''t accept PRs made here. Please re-submit your changes to [our Gitea instance](https://kolaente.dev/vikunja/frontend/pulls).
Also check out the [contribution guidelines](https://vikunja.io/docs/development/#pull-requests).
Thank you for your understanding.'

2
.nvmrc
View File

@ -1 +1 @@
20.10.0
18.17.1

View File

@ -3,7 +3,7 @@
# │─││ │││ │ │
# ┘─┘┘─┘┘┘─┘┘─┘
FROM --platform=$BUILDPLATFORM node:20.10-alpine AS builder
FROM --platform=$BUILDPLATFORM node:20.5-alpine AS builder
WORKDIR /build

View File

@ -0,0 +1,40 @@
import {createFakeUserAndLogin} from '../../support/authenticateUser'
import {TaskFactory} from '../../factories/task'
import {ProjectFactory} from '../../factories/project'
import {UserProjectFactory} from '../../factories/users_project'
import {BucketFactory} from '../../factories/bucket'
describe('Editor', () => {
createFakeUserAndLogin()
beforeEach(() => {
ProjectFactory.create(1)
BucketFactory.create(1)
TaskFactory.truncate()
UserProjectFactory.truncate()
})
it('Has a preview with checkable checkboxes', () => {
const tasks = TaskFactory.create(1, {
description: `# Test Heading
* Bullet 1
* Bullet 2
* [ ] Checklist
* [x] Checklist checked
`,
bucket_id: 1,
})
cy.visit(`/tasks/${tasks[0].id}`)
cy.get('input[type=checkbox][data-checkbox-num=0]')
.click()
cy.get('.task-view .details.content.description h3 span.is-small.has-text-success')
.contains('Saved!')
.should('exist')
cy.get('.preview.content')
.should('contain', 'Test Heading')
})
})

View File

@ -24,7 +24,7 @@ function addLabelToTaskAndVerify(labelTitle: string) {
.first()
.click()
cy.get('.global-notification', {timeout: 4000})
cy.get('.global-notification', { timeout: 4000 })
.should('contain', 'Success')
cy.get('.task-view .details.labels-list .multiselect .input-wrapper span.tag')
.should('exist')
@ -122,7 +122,7 @@ describe('Task', () => {
const tasks = TaskFactory.create(1, {
id: 1,
index: 1,
description: 'Lorem ipsum dolor sit amet.',
description: 'Lorem ipsum dolor sit amet.'
})
cy.visit(`/tasks/${tasks[0].id}`)
@ -143,7 +143,7 @@ describe('Task', () => {
id: 1,
index: 1,
done: true,
done_at: new Date().toISOString(),
done_at: new Date().toISOString()
})
cy.visit(`/tasks/${tasks[0].id}`)
@ -196,13 +196,13 @@ describe('Task', () => {
it('Can edit the description', () => {
const tasks = TaskFactory.create(1, {
id: 1,
description: 'Lorem ipsum dolor sit amet.',
description: 'Lorem ipsum dolor sit amet.'
})
cy.visit(`/tasks/${tasks[0].id}`)
cy.get('.task-view .details.content.description .tiptap button.done-edit')
cy.get('.task-view .details.content.description .editor button')
.click()
cy.get('.task-view .details.content.description .tiptap__editor .tiptap.ProseMirror')
cy.get('.task-view .details.content.description .editor .vue-easymde .EasyMDEContainer .CodeMirror-scroll')
.type('{selectall}New Description')
cy.get('[data-cy="saveEditor"]')
.contains('Save')
@ -219,7 +219,7 @@ describe('Task', () => {
})
cy.visit(`/tasks/${tasks[0].id}`)
cy.get('.task-view .comments .media.comment .tiptap__editor .tiptap.ProseMirror')
cy.get('.task-view .comments .media.comment .editor .vue-easymde .EasyMDEContainer .CodeMirror-scroll')
.should('be.visible')
.type('{selectall}New Comment')
cy.get('.task-view .comments .media.comment .button:not([disabled])')
@ -227,7 +227,7 @@ describe('Task', () => {
.should('be.visible')
.click()
cy.get('.task-view .comments .media.comment .tiptap__editor')
cy.get('.task-view .comments .media.comment .editor')
.should('contain', 'New Comment')
cy.get('.global-notification')
.should('contain', 'Success')
@ -236,7 +236,7 @@ describe('Task', () => {
it('Can move a task to another project', () => {
const projects = ProjectFactory.create(2)
BucketFactory.create(2, {
project_id: '{increment}',
project_id: '{increment}'
})
const tasks = TaskFactory.create(1, {
id: 1,
@ -380,7 +380,7 @@ describe('Task', () => {
addLabelToTaskAndVerify(labels[0].title)
})
it('Can add a label to a task and it shows up on the kanban board afterwards', () => {
const tasks = TaskFactory.create(1, {
id: 1,
@ -389,18 +389,18 @@ describe('Task', () => {
})
const labels = LabelFactory.create(1)
LabelTaskFactory.truncate()
cy.visit(`/projects/${projects[0].id}/kanban`)
cy.get('.bucket .task')
.contains(tasks[0].title)
.click()
addLabelToTaskAndVerify(labels[0].title)
cy.get('.modal-content .close')
.click()
cy.get('.bucket .task')
.should('contain.text', labels[0].title)
})
@ -461,7 +461,7 @@ describe('Task', () => {
cy.get('.global-notification')
.should('contain', 'Success')
})
it('Can set a reminder', () => {
TaskReminderFactory.truncate()
const tasks = TaskFactory.create(1, {
@ -543,7 +543,7 @@ describe('Task', () => {
cy.get('.global-notification')
.should('contain', 'Success')
})
it('Allows to set a custom relative reminder when the task already has a due date', () => {
TaskReminderFactory.truncate()
const tasks = TaskFactory.create(1, {
@ -579,7 +579,7 @@ describe('Task', () => {
cy.get('.global-notification')
.should('contain', 'Success')
})
it('Allows to set a fixed reminder when the task already has a due date', () => {
TaskReminderFactory.truncate()
const tasks = TaskFactory.create(1, {
@ -609,7 +609,7 @@ describe('Task', () => {
cy.get('.global-notification')
.should('contain', 'Success')
})
it('Can set a priority for a task', () => {
const tasks = TaskFactory.create(1, {
id: 1,
@ -647,7 +647,7 @@ describe('Task', () => {
.select('50%')
cy.get('.global-notification')
.should('contain', 'Success')
cy.wait(200)
cy.get('.task-view .columns.details .column')
@ -656,7 +656,7 @@ describe('Task', () => {
.should('be.visible')
.should('have.value', '0.5')
})
it('Can add an attachment to a task', () => {
TaskAttachmentFactory.truncate()
const tasks = TaskFactory.create(1, {
@ -691,119 +691,35 @@ describe('Task', () => {
cy.get('.bucket .task .footer .icon svg.fa-paperclip')
.should('exist')
})
it('Can check items off a checklist', () => {
const tasks = TaskFactory.create(1, {
id: 1,
description: `
<ul data-type="taskList">
<li data-checked="false" data-type="taskItem"><label><input type="checkbox"><span></span></label>
<div><p>First Item</p></div>
</li>
<li data-checked="false" data-type="taskItem"><label><input type="checkbox"><span></span></label>
<div><p>Second Item</p></div>
</li>
<li data-checked="false" data-type="taskItem"><label><input type="checkbox"><span></span></label>
<div><p>Third Item</p></div>
</li>
<li data-checked="false" data-type="taskItem"><label><input type="checkbox"><span></span></label>
<div><p>Fourth Item</p></div>
</li>
<li data-checked="true" data-type="taskItem"><label><input type="checkbox"><span></span></label>
<div><p>Fifth Item</p></div>
</li>
</ul>`,
This is a checklist:
* [ ] one item
* [ ] another item
* [ ] third item
* [ ] fourth item
* [x] and this one is already done
`,
})
cy.visit(`/tasks/${tasks[0].id}`)
cy.get('.task-view .checklist-summary')
.should('contain.text', '1 of 5 tasks')
cy.get('.tiptap__editor ul > li input[type=checkbox]')
cy.get('.editor .content ul > li input[type=checkbox]')
.eq(2)
.click()
cy.get('.task-view .details.content.description h3 span.is-small.has-text-success')
.contains('Saved!')
.should('exist')
cy.get('.tiptap__editor ul > li input[type=checkbox]')
cy.get('.editor .content ul > li input[type=checkbox]')
.eq(2)
.should('be.checked')
cy.get('.tiptap__editor input[type=checkbox]')
cy.get('.editor .content input[type=checkbox]')
.should('have.length', 5)
cy.get('.task-view .checklist-summary')
.should('contain.text', '2 of 5 tasks')
})
it('Should use the editor to render description', () => {
const tasks = TaskFactory.create(1, {
id: 1,
description: `
<h1>Lorem Ipsum</h1>
<p>Dolor sit amet</p>
<ul data-type="taskList">
<li data-checked="false" data-type="taskItem"><label><input type="checkbox"><span></span></label>
<div><p>First Item</p></div>
</li>
<li data-checked="false" data-type="taskItem"><label><input type="checkbox"><span></span></label>
<div><p>Second Item</p></div>
</li>
</ul>`,
})
cy.visit(`/tasks/${tasks[0].id}`)
cy.get('.tiptap__editor ul > li input[type=checkbox]')
.should('exist')
cy.get('.tiptap__editor h1')
.contains('Lorem Ipsum')
.should('exist')
cy.get('.tiptap__editor p')
.contains('Dolor sit amet')
.should('exist')
})
it.only('Should render an image from attachment', async () => {
TaskAttachmentFactory.truncate()
const tasks = TaskFactory.create(1, {
id: 1,
description: '',
})
cy.readFile('cypress/fixtures/image.jpg', null).then(file => {
const formData = new FormData()
formData.append('files', new Blob([file]), 'image.jpg')
cy.request({
method: 'PUT',
url: `${Cypress.env('API_URL')}/tasks/${tasks[0].id}/attachments`,
headers: {
'Authorization': `Bearer ${window.localStorage.getItem('token')}`,
'Content-Type': 'multipart/form-data',
},
body: formData,
})
.then(({body}) => {
const dec = new TextDecoder('utf-8')
const {success} = JSON.parse(dec.decode(body))
TaskFactory.create(1, {
id: 1,
description: `<img src="${Cypress.env('API_URL')}/tasks/${tasks[0].id}/attachments/${success[0].id}" alt="test image">`,
})
cy.visit(`/tasks/${tasks[0].id}`)
cy.get('.tiptap__editor img')
.should('be.visible')
.and(($img) => {
// "naturalWidth" and "naturalHeight" are set when the image loads
expect($img[0].naturalWidth).to.be.greaterThan(0)
})
})
})
})
})
})

View File

@ -2,11 +2,11 @@
"nodes": {
"nixpkgs": {
"locked": {
"lastModified": 1701336116,
"narHash": "sha256-kEmpezCR/FpITc6yMbAh4WrOCiT2zg5pSjnKrq51h5Y=",
"lastModified": 1692494774,
"narHash": "sha256-noGVoOTyZ2Kr5OFglzKYOX48cx3hggdCPbXrYMG2FDw=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "f5c27c6136db4d76c30e533c20517df6864c46ee",
"rev": "3476a10478587dec90acb14ec6bde0966c545cc0",
"type": "github"
},
"original": {

View File

@ -13,7 +13,7 @@
},
"homepage": "https://vikunja.io/",
"funding": "https://opencollective.com/vikunja",
"packageManager": "pnpm@8.11.0",
"packageManager": "pnpm@8.7.4",
"keywords": [
"todo",
"productivity",
@ -45,136 +45,103 @@
"story:preview": "histoire preview"
},
"dependencies": {
"@fortawesome/fontawesome-svg-core": "6.5.1",
"@fortawesome/free-regular-svg-icons": "6.5.1",
"@fortawesome/free-solid-svg-icons": "6.5.1",
"@fortawesome/vue-fontawesome": "3.0.5",
"@github/hotkey": "2.3.1",
"@infectoone/vue-ganttastic": "2.2.0",
"@intlify/unplugin-vue-i18n": "1.5.0",
"@kyvg/vue3-notification": "3.1.0",
"@sentry/tracing": "7.85.0",
"@sentry/vue": "7.85.0",
"@tiptap/core": "2.1.13",
"@tiptap/extension-blockquote": "2.1.13",
"@tiptap/extension-bold": "2.1.13",
"@tiptap/extension-bullet-list": "2.1.13",
"@tiptap/extension-code": "2.1.13",
"@tiptap/extension-code-block-lowlight": "2.1.13",
"@tiptap/extension-document": "2.1.13",
"@tiptap/extension-dropcursor": "2.1.13",
"@tiptap/extension-gapcursor": "2.1.13",
"@tiptap/extension-hard-break": "2.1.13",
"@tiptap/extension-heading": "2.1.13",
"@tiptap/extension-history": "2.1.13",
"@tiptap/extension-horizontal-rule": "2.1.13",
"@tiptap/extension-image": "2.1.13",
"@tiptap/extension-italic": "2.1.13",
"@tiptap/extension-link": "2.1.13",
"@tiptap/extension-list-item": "2.1.13",
"@tiptap/extension-ordered-list": "2.1.13",
"@tiptap/extension-paragraph": "2.1.13",
"@tiptap/extension-placeholder": "2.1.13",
"@tiptap/extension-strike": "2.1.13",
"@tiptap/extension-table": "2.1.13",
"@tiptap/extension-table-cell": "2.1.13",
"@tiptap/extension-table-header": "2.1.13",
"@tiptap/extension-table-row": "2.1.13",
"@tiptap/extension-task-item": "2.1.13",
"@tiptap/extension-task-list": "2.1.13",
"@tiptap/extension-text": "2.1.13",
"@tiptap/extension-typography": "2.1.13",
"@tiptap/extension-underline": "2.1.13",
"@tiptap/pm": "2.1.13",
"@tiptap/suggestion": "2.1.13",
"@tiptap/vue-3": "2.1.13",
"@types/is-touch-device": "1.0.2",
"@types/lodash.clonedeep": "4.5.9",
"@vueuse/core": "10.7.0",
"@vueuse/router": "10.7.0",
"axios": "1.6.2",
"@fortawesome/fontawesome-svg-core": "6.4.2",
"@fortawesome/free-regular-svg-icons": "6.4.2",
"@fortawesome/free-solid-svg-icons": "6.4.2",
"@fortawesome/vue-fontawesome": "3.0.3",
"@github/hotkey": "2.0.1",
"@infectoone/vue-ganttastic": "2.1.4",
"@intlify/unplugin-vue-i18n": "0.13.0",
"@kyvg/vue3-notification": "3.0.2",
"@sentry/tracing": "7.68.0",
"@sentry/vue": "7.68.0",
"@vueuse/core": "10.4.1",
"@vueuse/router": "10.4.1",
"axios": "1.5.0",
"blurhash": "2.0.5",
"bulma-css-variables": "0.9.33",
"camel-case": "4.1.2",
"codemirror": "5.65.15",
"date-fns": "2.30.0",
"dayjs": "1.11.10",
"dompurify": "3.0.6",
"dayjs": "1.11.9",
"dompurify": "3.0.5",
"easymde": "2.18.0",
"fast-deep-equal": "3.1.3",
"flatpickr": "4.6.13",
"flexsearch": "0.7.31",
"floating-vue": "2.0.0-beta.24",
"highlight.js": "11.8.0",
"is-touch-device": "1.0.1",
"klona": "2.0.6",
"lodash.debounce": "4.0.8",
"lowlight": "2.9.0",
"pinia": "2.1.7",
"marked": "5.1.2",
"pinia": "2.1.6",
"register-service-worker": "1.7.2",
"snake-case": "3.0.4",
"sortablejs": "1.15.1",
"tippy.js": "6.3.7",
"ufo": "1.3.2",
"vue": "3.3.10",
"sortablejs": "1.15.0",
"ufo": "1.3.0",
"vue": "3.3.4",
"vue-advanced-cropper": "2.8.8",
"vue-flatpickr-component": "11.0.3",
"vue-i18n": "9.8.0",
"vue-router": "4.2.5",
"vue-i18n": "9.2.2",
"vue-router": "4.2.4",
"workbox-precaching": "7.0.0",
"zhyswan-vuedraggable": "4.1.3"
},
"devDependencies": {
"@4tw/cypress-drag-drop": "2.2.5",
"@cypress/vite-dev-server": "5.0.6",
"@cypress/vue": "6.0.0",
"@faker-js/faker": "8.3.1",
"@histoire/plugin-screenshot": "0.17.6",
"@histoire/plugin-vue": "0.17.6",
"@rushstack/eslint-patch": "1.6.0",
"@cypress/vue": "5.0.5",
"@faker-js/faker": "8.0.2",
"@histoire/plugin-screenshot": "0.17.0",
"@histoire/plugin-vue": "0.17.1",
"@rushstack/eslint-patch": "1.4.0",
"@tsconfig/node18": "18.2.2",
"@types/codemirror": "5.60.15",
"@types/dompurify": "3.0.5",
"@types/flexsearch": "0.7.6",
"@types/is-touch-device": "1.0.2",
"@types/lodash.debounce": "4.0.9",
"@types/marked": "5.0.2",
"@types/node": "20.10.3",
"@types/codemirror": "5.60.10",
"@types/dompurify": "3.0.2",
"@types/flexsearch": "0.7.4",
"@types/is-touch-device": "1.0.0",
"@types/lodash.debounce": "4.0.7",
"@types/marked": "5.0.1",
"@types/node": "18.17.16",
"@types/postcss-preset-env": "7.7.0",
"@types/sortablejs": "1.15.7",
"@typescript-eslint/eslint-plugin": "6.13.2",
"@typescript-eslint/parser": "6.13.2",
"@vitejs/plugin-legacy": "5.2.0",
"@vitejs/plugin-vue": "4.5.1",
"@vue/eslint-config-typescript": "12.0.0",
"@vue/test-utils": "2.4.3",
"@types/sortablejs": "1.15.2",
"@typescript-eslint/eslint-plugin": "6.7.0",
"@typescript-eslint/parser": "6.7.0",
"@vitejs/plugin-legacy": "4.1.1",
"@vitejs/plugin-vue": "4.3.4",
"@vue/eslint-config-typescript": "11.0.3",
"@vue/test-utils": "2.4.1",
"@vue/tsconfig": "0.4.0",
"autoprefixer": "10.4.16",
"browserslist": "4.22.2",
"caniuse-lite": "1.0.30001566",
"autoprefixer": "10.4.15",
"browserslist": "4.21.10",
"caniuse-lite": "1.0.30001534",
"css-has-pseudo": "6.0.0",
"csstype": "3.1.2",
"cypress": "13.6.1",
"esbuild": "0.19.8",
"eslint": "8.55.0",
"eslint-plugin-vue": "9.19.2",
"happy-dom": "12.10.3",
"histoire": "0.17.6",
"postcss": "8.4.32",
"cypress": "12.17.4",
"esbuild": "0.19.3",
"eslint": "8.49.0",
"eslint-plugin-vue": "9.17.0",
"happy-dom": "10.11.2",
"histoire": "0.17.0",
"postcss": "8.4.29",
"postcss-easing-gradients": "3.0.1",
"postcss-easings": "4.0.0",
"postcss-focus-within": "8.0.0",
"postcss-preset-env": "9.3.0",
"rollup": "4.6.1",
"rollup-plugin-visualizer": "5.10.0",
"sass": "1.69.5",
"start-server-and-test": "2.0.3",
"typescript": "5.3.2",
"vite": "5.0.6",
"postcss-preset-env": "9.1.3",
"rollup": "3.29.1",
"rollup-plugin-visualizer": "5.9.2",
"sass": "1.67.0",
"start-server-and-test": "2.0.0",
"typescript": "5.2.2",
"vite": "4.4.9",
"vite-plugin-inject-preload": "1.3.3",
"vite-plugin-pwa": "0.17.3",
"vite-plugin-pwa": "0.16.5",
"vite-plugin-sentry": "1.3.0",
"vite-svg-loader": "5.1.0",
"vitest": "1.0.1",
"vue-tsc": "1.8.25",
"wait-on": "7.2.0",
"vite-svg-loader": "4.0.0",
"vitest": "0.34.4",
"vue-tsc": "1.8.11",
"wait-on": "7.0.1",
"workbox-cli": "7.0.0"
},
"pnpm": {

File diff suppressed because it is too large Load Diff

View File

@ -27,13 +27,6 @@
"histoire"
]
},
{
"groupName": "tiptap",
"matchPackagePrefixes": [
"@tiptap/",
"tiptap"
]
},
{
"matchDepTypes": ["devDependencies"],
"groupName": "dev-dependencies",

View File

@ -75,7 +75,6 @@ import {useI18n} from 'vue-i18n'
import flatPickr from 'vue-flatpickr-component'
import 'flatpickr/dist/flatpickr.css'
import {parseDateOrString} from '@/helpers/time/parseDateOrString'
import Popup from '@/components/misc/popup.vue'
import {DATE_RANGES} from '@/components/date/dateRanges'
@ -121,9 +120,9 @@ watch(
to.value = newValue.dateTo
// Only set the date back to flatpickr when it's an actual date.
// Otherwise flatpickr runs in an endless loop and slows down the browser.
const dateFrom = parseDateOrString(from.value, false)
const dateTo = parseDateOrString(to.value, false)
if (dateFrom instanceof Date && dateTo instanceof Date) {
const dateFrom = new Date(from.value)
const dateTo = new Date(to.value)
if (dateTo.getTime() === dateTo.getTime() && dateFrom.getTime() === dateFrom.getTime()) {
flatpickrRange.value = `${from.value} to ${to.value}`
}
},

View File

@ -3,7 +3,7 @@
class="menu-show-button"
@click="baseStore.toggleMenu()"
@shortkey="() => baseStore.toggleMenu()"
v-shortcut="'Mod+e'"
v-shortcut="'Control+e'"
:title="$t('keyboardShortcuts.toggleMenu')"
:aria-label="menuActive ? $t('misc.hideMenu') : $t('misc.showMenu')"
/>

View File

@ -27,7 +27,10 @@
</div>
<div class="navbar-end">
<OpenQuickActions/>
<BaseButton @click="openQuickActions" class="trigger-button" v-shortcut="'Control+k'"
:title="$t('keyboardShortcuts.quickSearch')">
<icon icon="search" />
</BaseButton>
<Notifications />
<dropdown>
<template #trigger="{ toggleOpen, open }">
@ -77,7 +80,6 @@ import Notifications from '@/components/notifications/notifications.vue'
import Logo from '@/components/home/Logo.vue'
import BaseButton from '@/components/base/BaseButton.vue'
import MenuButton from '@/components/home/MenuButton.vue'
import OpenQuickActions from '@/components/misc/OpenQuickActions.vue'
import { getProjectTitle } from '@/helpers/getProjectTitle'
@ -96,6 +98,10 @@ const authStore = useAuthStore()
const configStore = useConfigStore()
const imprintUrl = computed(() => configStore.legal.imprintUrl)
const privacyPolicyUrl = computed(() => configStore.legal.privacyPolicyUrl)
function openQuickActions() {
baseStore.setQuickActionsActive(true)
}
</script>
<style lang="scss" scoped>

View File

@ -39,7 +39,7 @@
</router-view>
<modal
:enabled="typeof currentModal !== 'undefined'"
:enabled="Boolean(currentModal)"
@close="closeModal()"
variant="scrolling"
class="task-detail-view-modal"

View File

@ -1,5 +1,3 @@
import {createAsyncComponent} from '@/helpers/createAsyncComponent'
const TipTap = createAsyncComponent(() => import('@/components/input/editor/TipTap.vue'))
export default TipTap
export default createAsyncComponent(() => import('@/components/input/editor.vue'))

View File

@ -20,20 +20,11 @@ import type {IProject} from '@/modelTypes/IProject'
import ProjectService from '@/services/project'
import {includesById} from '@/helpers/utils'
type ProjectFilterFunc = (p: IProject) => boolean
const props = defineProps({
modelValue: {
type: Array as PropType<IProject[]>,
default: () => [],
},
projectFilter: {
type: Function as PropType<ProjectFilterFunc>,
default: () => {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
return (_: IProject) => true
},
},
})
const emit = defineEmits<{
(e: 'update:modelValue', value: IProject[]): void
@ -67,8 +58,6 @@ async function findProjects(query: string) {
const response = await projectService.getAll({}, {s: query}) as IProject[]
// Filter selected items from the results
foundProjects.value = response
.filter(({id}) => !includesById(projects.value, id))
.filter(props.projectFilter)
foundProjects.value = response.filter(({id}) => !includesById(projects.value, id))
}
</script>

View File

@ -0,0 +1,444 @@
<template>
<div class="editor">
<div class="clear"></div>
<vue-easymde
:configs="config"
@change="() => bubbleNow()"
@update:modelValue="handleInput"
class="content"
v-if="isEditActive"
v-model="text"/>
<div class="preview content" v-html="preview" v-if="isPreviewActive && text !== ''">
</div>
<p class="has-text-centered has-text-grey is-italic my-5" v-if="showPreviewText">
{{ emptyText }}
<template v-if="isEditEnabled">
<ButtonLink
@click="toggleEdit"
v-shortcut="editShortcut"
class="d-print-none">
{{ $t('input.editor.edit') }}
</ButtonLink>.
</template>
</p>
<ul class="actions d-print-none" v-if="bottomActions.length > 0">
<li v-if="isEditEnabled && !showPreviewText && showSave">
<BaseButton
v-if="showEditButton"
@click="toggleEdit"
v-shortcut="editShortcut">
{{ $t('input.editor.edit') }}
</BaseButton>
<BaseButton
v-else-if="isEditActive"
@click="bubbleSaveClick"
class="done-edit">
{{ $t('misc.save') }}
</BaseButton>
</li>
<li v-for="(action, k) in bottomActions" :key="k">
<BaseButton @click="action.action">{{ action.title }}</BaseButton>
</li>
</ul>
<template v-else-if="isEditEnabled && showSave">
<ul v-if="showEditButton" class="actions d-print-none">
<li>
<BaseButton
@click="toggleEdit"
v-shortcut="editShortcut">
{{ $t('input.editor.edit') }}
</BaseButton>
</li>
</ul>
<x-button
v-else-if="isEditActive"
@click="bubbleSaveClick"
variant="secondary"
:shadow="false"
v-cy="'saveEditor'">
{{ $t('misc.save') }}
</x-button>
</template>
</div>
</template>
<script setup lang="ts">
import {computed, nextTick, onMounted, ref, toRefs, watch} from 'vue'
import VueEasymde from './vue-easymde.vue'
import {marked} from 'marked'
import DOMPurify from 'dompurify'
import {createEasyMDEConfig} from './editorConfig'
import AttachmentModel from '@/models/attachment'
import AttachmentService from '@/services/attachment'
import {setupMarkdownRenderer} from '@/helpers/markdownRenderer'
import {findCheckboxesInText} from '@/helpers/checklistFromText'
import {createRandomID} from '@/helpers/randomId'
import BaseButton from '@/components/base/BaseButton.vue'
import ButtonLink from '@/components/misc/ButtonLink.vue'
import type {IAttachment} from '@/modelTypes/IAttachment'
import type {ITask} from '@/modelTypes/ITask'
const props = defineProps({
modelValue: {
type: String,
default: '',
},
placeholder: {
type: String,
default: '',
},
uploadEnabled: {
type: Boolean,
default: false,
},
uploadCallback: {
type: Function,
},
hasPreview: {
type: Boolean,
default: true,
},
previewIsDefault: {
type: Boolean,
default: true,
},
isEditEnabled: {
default: true,
},
bottomActions: {
type: Array,
default: () => [],
},
emptyText: {
type: String,
default: '',
},
showSave: {
type: Boolean,
default: false,
},
// If a key is passed the editor will go in "edit" mode when the key is pressed.
// Disabled if an empty string is passed.
editShortcut: {
type: String,
default: '',
},
})
const emit = defineEmits(['update:modelValue', 'save'])
const text = ref('')
const isEditActive = ref(false)
const isPreviewActive = ref(true)
const showPreviewText = computed(() => isPreviewActive.value && text.value === '' && props.emptyText !== '')
const showEditButton = computed(() => !isEditActive.value && text.value !== '')
const preview = ref('')
const attachmentService = new AttachmentService()
type CacheKey = `${ITask['id']}-${IAttachment['id']}`
const loadedAttachments = ref<{ [key: CacheKey]: string }>({})
const config = ref(createEasyMDEConfig({
placeholder: props.placeholder,
uploadImage: props.uploadEnabled,
imageUploadFunction: props.uploadCallback,
}))
const checkboxId = ref(createRandomID())
const {modelValue} = toRefs(props)
watch(
modelValue,
async (value) => {
text.value = value
await nextTick()
renderPreview()
},
)
watch(
text,
(newVal, oldVal) => {
// Only bubble the new value if it actually changed, but not if the component just got mounted and the text changed from the outside.
if (oldVal === '' && text.value === modelValue.value) {
return
}
bubbleNow()
},
)
onMounted(() => {
if (modelValue.value !== '') {
text.value = modelValue.value
}
if (props.previewIsDefault && props.hasPreview) {
nextTick(() => renderPreview())
return
}
isPreviewActive.value = false
isEditActive.value = true
})
// This gets triggered when only pasting content into the editor.
// A change event would not get generated by that, an input event does.
// Therefore, we're using this handler to catch paste events.
// But because this also gets triggered when typing into the editor, we give
// it a higher timeout to make the timouts cancel each other in that case so
// that in the end, only one change event is triggered to the outside per change.
function handleInput(val: string) {
// Don't bubble if the text is up to date
if (val === text.value) {
return
}
text.value = val
bubbleNow()
}
function bubbleNow() {
emit('update:modelValue', text.value)
}
function replaceAt(str: string, index: number, replacement: string) {
return str.slice(0, index) + replacement + str.slice(index + replacement.length)
}
function findNthIndex(str: string, n: number) {
const checkboxes = findCheckboxesInText(str)
return checkboxes[n]
}
function renderPreview() {
setupMarkdownRenderer(checkboxId.value)
preview.value = DOMPurify.sanitize(marked(text.value, {
mangle: false,
headerIds: false,
}), {ADD_ATTR: ['target']})
// Since the render function is synchronous, we can't do async http requests in it.
// Therefore, we can't resolve the blob url at (markdown) compile time.
// To work around this, we modify the url after rendering it in the vue component.
// We're doing the whole thing in the next tick to ensure the image elements are available in the
// dom tree. If we're calling this right after setting this.preview it could be the images were
// not already made available.
// Some docs at https://stackoverflow.com/q/62865160/10924593
nextTick().then(async () => {
const attachmentImage = document.querySelectorAll<HTMLImageElement>('.attachment-image')
if (attachmentImage) {
Array.from(attachmentImage).forEach(async (img) => {
// The url is something like /tasks/<id>/attachments/<id>
const parts = img.dataset.src?.slice(window.API_URL.length + 1).split('/')
const taskId = Number(parts[1])
const attachmentId = Number(parts[3])
const cacheKey: CacheKey = `${taskId}-${attachmentId}`
if (typeof loadedAttachments.value[cacheKey] !== 'undefined') {
img.src = loadedAttachments.value[cacheKey]
return
}
const attachment = new AttachmentModel({taskId: taskId, id: attachmentId})
const url = await attachmentService.getBlobUrl(attachment)
img.src = url
loadedAttachments.value[cacheKey] = url
})
}
const textCheckbox = document.querySelectorAll<HTMLInputElement>(`.text-checkbox-${checkboxId.value}`)
if (textCheckbox) {
Array.from(textCheckbox).forEach(check => {
check.removeEventListener('change', handleCheckboxClick)
check.addEventListener('change', handleCheckboxClick)
check.parentElement?.classList.add('has-checkbox')
})
}
})
}
function handleCheckboxClick(e: Event) {
// Find the original markdown checkbox this is targeting
const checked = (e.target as HTMLInputElement).checked
const numMarkdownCheck = Number((e.target as HTMLInputElement).dataset.checkboxNum)
const index = findNthIndex(text.value, numMarkdownCheck)
if (index < 0 || typeof index === 'undefined') {
console.debug('no index found')
return
}
const projectPrefix = text.value.substring(index, index + 1)
console.debug({index, projectPrefix, checked, text: text.value})
text.value = replaceAt(text.value, index, `${projectPrefix} ${checked ? '[x]' : '[ ]'} `)
bubbleNow()
emit('save', text.value)
renderPreview()
}
function toggleEdit() {
isPreviewActive.value = false
isEditActive.value = true
}
function bubbleSaveClick() {
isPreviewActive.value = true
isEditActive.value = false
renderPreview()
bubbleNow()
emit('save', text.value)
}
</script>
<style lang="scss">
@import 'codemirror/lib/codemirror.css';
@import 'highlight.js/scss/base16/equilibrium-gray-light';
.editor {
.clear {
clear: both;
}
.preview.content {
margin-bottom: .5rem;
overflow-wrap: anywhere; // Safari does not understand "break-word" so we put that first to make sure it at least is able to show it somewhat properly there.
overflow-wrap: break-word;
ul li {
input[type="checkbox"] {
margin-right: .5rem;
}
&.has-checkbox {
margin-left: -1.25rem;
list-style: none;
}
}
}
}
.CodeMirror {
padding: .5rem;
border: 1px solid var(--grey-200) !important;
background: var(--white);
&-lines pre {
margin: 0 !important;
}
&-placeholder {
color: var(--grey-400) !important;
font-style: italic;
}
&-cursor {
border-color: var(--grey-700);
}
}
.editor-preview {
padding: 0;
&-side {
padding: .5rem;
}
}
.editor-toolbar {
background: var(--grey-50);
border: 1px solid var(--grey-200);
border-bottom: none;
button {
color: var(--grey-700);
&.active {
background: var(--grey-200);
}
svg {
vertical-align: middle;
&, rect {
width: 20px;
height: 20px;
}
}
&::after {
position: absolute;
top: 24px;
margin-left: -3px;
}
&:hover {
background: var(--grey-200);
border-color: var(--grey-300);
}
}
i.separator {
border-color: var(--grey-200) !important;
}
}
pre.CodeMirror-line {
margin-bottom: 0 !important;
color: var(--grey-700) !important;
}
.cm-header {
font-family: $vikunja-font;
font-weight: 400;
}
ul.actions {
font-size: .8rem;
margin: 0;
li {
display: inline-block;
&::after {
content: '·';
padding: 0 .25rem;
}
&:last-child:after {
content: '';
}
}
&, a {
color: var(--grey-500);
&.done-edit {
color: var(--primary);
}
}
a:hover {
text-decoration: underline;
}
}
.vue-easymde.content {
margin-bottom: 0 !important;
}
</style>

View File

@ -1,145 +0,0 @@
<template>
<div class="items">
<template v-if="items.length">
<button
class="item"
:class="{ 'is-selected': index === selectedIndex }"
v-for="(item, index) in items"
:key="index"
@click="selectItem(index)"
>
<icon :icon="item.icon"/>
<div class="description">
<p>{{ item.title }}</p>
<p>{{ item.description }}</p>
</div>
</button>
</template>
<div class="item" v-else>
No result
</div>
</div>
</template>
<script>
export default {
props: {
items: {
type: Array,
required: true,
},
command: {
type: Function,
required: true,
},
},
data() {
return {
selectedIndex: 0,
}
},
watch: {
items() {
this.selectedIndex = 0
},
},
methods: {
onKeyDown({event}) {
if (event.key === 'ArrowUp') {
this.upHandler()
return true
}
if (event.key === 'ArrowDown') {
this.downHandler()
return true
}
if (event.key === 'Enter') {
this.enterHandler()
return true
}
return false
},
upHandler() {
this.selectedIndex = ((this.selectedIndex + this.items.length) - 1) % this.items.length
},
downHandler() {
this.selectedIndex = (this.selectedIndex + 1) % this.items.length
},
enterHandler() {
this.selectItem(this.selectedIndex)
},
selectItem(index) {
const item = this.items[index]
if (item) {
this.command(item)
}
},
},
}
</script>
<style lang="scss" scoped>
.items {
padding: 0.2rem;
position: relative;
border-radius: 0.5rem;
background: var(--white);
color: var(--grey-900);
overflow: hidden;
font-size: 0.9rem;
box-shadow: var(--shadow-md);
}
.item {
display: flex;
align-items: center;
margin: 0;
width: 100%;
text-align: left;
background: transparent;
border-radius: $radius;
border: 0;
padding: 0.2rem 0.4rem;
transition: background-color $transition;
&.is-selected, &:hover {
background: var(--grey-100);
cursor: pointer;
}
> svg {
box-sizing: border-box;
width: 2rem;
height: 2rem;
border: 1px solid var(--grey-300);
padding: .5rem;
margin-right: .5rem;
border-radius: $radius;
color: var(--grey-700);
}
}
.description {
display: flex;
flex-direction: column;
font-size: .9rem;
color: var(--grey-800);
p:last-child {
font-size: .75rem;
color: var(--grey-500);
}
}
</style>

View File

@ -1,439 +0,0 @@
<template>
<div class="editor-toolbar">
<div class="editor-toolbar__segment">
<BaseButton
class="editor-toolbar__button"
@click="editor.chain().focus().toggleHeading({ level: 1 }).run()"
:class="{ 'is-active': editor.isActive('heading', { level: 1 }) }"
v-tooltip="$t('input.editor.heading1')"
>
<span class="icon">
<icon :icon="['fa', 'fa-header']"/>
<span class="icon__lower-text">1</span>
</span>
</BaseButton>
<BaseButton
class="editor-toolbar__button"
@click="editor.chain().focus().toggleHeading({ level: 2 }).run()"
:class="{ 'is-active': editor.isActive('heading', { level: 2 }) }"
v-tooltip="$t('input.editor.heading2')"
>
<span class="icon">
<icon :icon="['fa', 'fa-header']"/>
<span class="icon__lower-text">2</span>
</span>
</BaseButton>
<BaseButton
class="editor-toolbar__button"
@click="editor.chain().focus().toggleHeading({ level: 3 }).run()"
:class="{ 'is-active': editor.isActive('heading', { level: 3 }) }"
v-tooltip="$t('input.editor.heading3')"
>
<span class="icon">
<icon :icon="['fa', 'fa-header']"/>
<span class="icon__lower-text">3</span>
</span>
</BaseButton>
</div>
<div class="editor-toolbar__segment">
<BaseButton
class="editor-toolbar__button"
@click="editor.chain().focus().toggleBold().run()"
:class="{ 'is-active': editor.isActive('bold') }"
v-tooltip="$t('input.editor.bold')"
>
<span class="icon">
<icon :icon="['fa', 'fa-bold']"/>
</span>
</BaseButton>
<BaseButton
class="editor-toolbar__button"
@click="editor.chain().focus().toggleItalic().run()"
:class="{ 'is-active': editor.isActive('italic') }"
v-tooltip="$t('input.editor.italic')"
>
<span class="icon">
<icon :icon="['fa', 'fa-italic']"/>
</span>
</BaseButton>
<BaseButton
class="editor-toolbar__button"
@click="editor.chain().focus().toggleUnderline().run()"
:class="{ 'is-active': editor.isActive('underline') }"
v-tooltip="$t('input.editor.underline')"
>
<span class="icon">
<icon :icon="['fa', 'fa-underline']"/>
</span>
</BaseButton>
<BaseButton
class="editor-toolbar__button"
@click="editor.chain().focus().toggleStrike().run()"
:class="{ 'is-active': editor.isActive('strike') }"
v-tooltip="$t('input.editor.strikethrough')"
>
<span class="icon">
<icon :icon="['fa', 'fa-strikethrough']"/>
</span>
</BaseButton>
</div>
<div class="editor-toolbar__segment">
<BaseButton
class="editor-toolbar__button"
@click="editor.chain().focus().toggleCodeBlock().run()"
:class="{ 'is-active': editor.isActive('codeBlock') }"
v-tooltip="$t('input.editor.code')"
>
<span class="icon">
<icon :icon="['fa', 'fa-code']"/>
</span>
</BaseButton>
<BaseButton
class="editor-toolbar__button"
@click="editor.chain().focus().toggleBlockquote().run()"
:class="{ 'is-active': editor.isActive('blockquote') }"
v-tooltip="$t('input.editor.quote')"
>
<span class="icon">
<icon :icon="['fa', 'fa-quote-right']"/>
</span>
</BaseButton>
</div>
<div class="editor-toolbar__segment">
<BaseButton
class="editor-toolbar__button"
@click="editor.chain().focus().toggleBulletList().run()"
:class="{ 'is-active': editor.isActive('bulletList') }"
v-tooltip="$t('input.editor.bulletList')"
>
<span class="icon">
<icon :icon="['fa', 'fa-list-ol']"/>
</span>
</BaseButton>
<BaseButton
class="editor-toolbar__button"
@click="editor.chain().focus().toggleOrderedList().run()"
:class="{ 'is-active': editor.isActive('orderedList') }"
v-tooltip="$t('input.editor.orderedList')"
>
<span class="icon">
<icon :icon="['fa', 'fa-list-ul']"/>
</span>
</BaseButton>
<BaseButton
class="editor-toolbar__button"
@click="editor.chain().focus().toggleTaskList().run()"
:class="{ 'is-active': editor.isActive('taskList') }"
v-tooltip="$t('input.editor.taskList')"
>
<span class="icon">
<icon icon="fa-list-check"/>
</span>
</BaseButton>
</div>
<div class="editor-toolbar__segment">
<BaseButton
class="editor-toolbar__button"
@click="openImagePicker"
v-tooltip="$t('input.editor.image')"
>
<span class="icon">
<icon icon="fa-image"/>
</span>
</BaseButton>
</div>
<div class="editor-toolbar__segment">
<BaseButton
class="editor-toolbar__button"
@click="setLink"
:class="{ 'is-active': editor.isActive('link') }"
title="set link"
v-tooltip="$t('input.editor.link')"
>
<span class="icon">
<icon :icon="['fa', 'fa-link']"/>
</span>
</BaseButton>
<BaseButton
class="editor-toolbar__button"
@click="editor.chain().focus().setParagraph().run()"
:class="{ 'is-active': editor.isActive('paragraph') }"
title="paragraph"
v-tooltip="$t('input.editor.text')"
>
<span class="icon">
<icon :icon="['fa', 'fa-paragraph']"/>
</span>
</BaseButton>
<BaseButton
class="editor-toolbar__button"
@click="editor.chain().focus().setHorizontalRule().run()"
v-tooltip="$t('input.editor.horizontalRule')"
>
<span class="icon">
<icon :icon="['fa', 'fa-ruler-horizontal']"/>
</span>
</BaseButton>
</div>
<div class="editor-toolbar__segment">
<BaseButton
class="editor-toolbar__button"
@click="editor.chain().focus().undo().run()"
v-tooltip="$t('input.editor.undo')"
>
<span class="icon">
<icon :icon="['fa', 'fa-undo']"/>
</span>
</BaseButton>
<BaseButton
class="editor-toolbar__button"
@click="editor.chain().focus().redo().run()"
v-tooltip="$t('input.editor.redo')"
>
<span class="icon">
<icon :icon="['fa', 'fa-redo']"/>
</span>
</BaseButton>
</div>
<div class="editor-toolbar__segment">
<!-- table -->
<BaseButton
class="editor-toolbar__button"
@click="toggleTableMode"
:class="{ 'is-active': editor.isActive('table') }"
v-tooltip="$t('input.editor.table.title')"
>
<span class="icon">
<icon :icon="['fa', 'fa-table']"/>
</span>
</BaseButton>
<div v-if="tableMode" class="editor-toolbar__table-buttons">
<BaseButton
class="editor-toolbar__button"
@click="
editor
.chain()
.focus()
.insertTable({ rows: 3, cols: 3, withHeaderRow: true })
.run()
"
>
{{ $t('input.editor.table.insert') }}
</BaseButton>
<BaseButton
class="editor-toolbar__button"
@click="editor.chain().focus().addColumnBefore().run()"
:disabled="!editor.can().addColumnBefore"
>
{{ $t('input.editor.table.addColumnBefore') }}
</BaseButton>
<BaseButton
class="editor-toolbar__button"
@click="editor.chain().focus().addColumnAfter().run()"
:disabled="!editor.can().addColumnAfter"
>
{{ $t('input.editor.table.addColumnAfter') }}
</BaseButton>
<BaseButton
class="editor-toolbar__button"
@click="editor.chain().focus().deleteColumn().run()"
:disabled="!editor.can().deleteColumn"
>
{{ $t('input.editor.table.deleteColumn') }}
</BaseButton>
<BaseButton
class="editor-toolbar__button"
@click="editor.chain().focus().addRowBefore().run()"
:disabled="!editor.can().addRowBefore"
>
{{ $t('input.editor.table.addRowBefore') }}
</BaseButton>
<BaseButton
class="editor-toolbar__button"
@click="editor.chain().focus().addRowAfter().run()"
:disabled="!editor.can().addRowAfter"
>
{{ $t('input.editor.table.addRowAfter') }}
</BaseButton>
<BaseButton
class="editor-toolbar__button"
@click="editor.chain().focus().deleteRow().run()"
:disabled="!editor.can().deleteRow"
>
{{ $t('input.editor.table.deleteRow') }}
</BaseButton>
<BaseButton
class="editor-toolbar__button"
@click="editor.chain().focus().deleteTable().run()"
:disabled="!editor.can().deleteTable"
>
{{ $t('input.editor.table.deleteTable') }}
</BaseButton>
<BaseButton
class="editor-toolbar__button"
@click="editor.chain().focus().mergeCells().run()"
:disabled="!editor.can().mergeCells"
>
{{ $t('input.editor.table.mergeCells') }}
</BaseButton>
<BaseButton
class="editor-toolbar__button"
@click="editor.chain().focus().splitCell().run()"
:disabled="!editor.can().splitCell"
>
{{ $t('input.editor.table.splitCell') }}
</BaseButton>
<BaseButton
class="editor-toolbar__button"
@click="editor.chain().focus().toggleHeaderColumn().run()"
:disabled="!editor.can().toggleHeaderColumn"
>
{{ $t('input.editor.table.toggleHeaderColumn') }}
</BaseButton>
<BaseButton
class="editor-toolbar__button"
@click="editor.chain().focus().toggleHeaderRow().run()"
:disabled="!editor.can().toggleHeaderRow"
>
{{ $t('input.editor.table.toggleHeaderRow') }}
</BaseButton>
<BaseButton
class="editor-toolbar__button"
@click="editor.chain().focus().toggleHeaderCell().run()"
:disabled="!editor.can().toggleHeaderCell"
>
{{ $t('input.editor.table.toggleHeaderCell') }}
</BaseButton>
<BaseButton
class="editor-toolbar__button"
@click="editor.chain().focus().mergeOrSplit().run()"
:disabled="!editor.can().mergeOrSplit"
>
{{ $t('input.editor.table.mergeOrSplit') }}
</BaseButton>
<BaseButton
class="editor-toolbar__button"
@click="editor.chain().focus().fixTables().run()"
:disabled="!editor.can().fixTables"
>
{{ $t('input.editor.table.fixTables') }}
</BaseButton>
</div>
</div>
</div>
</template>
<script setup lang="ts">
import {ref} from 'vue'
import {Editor} from '@tiptap/vue-3'
import BaseButton from '@/components/base/BaseButton.vue'
const {
editor = null,
} = defineProps<{
editor: Editor,
}>()
const tableMode = ref(false)
function toggleTableMode() {
tableMode.value = !tableMode.value
}
function openImagePicker() {
document.getElementById('tiptap__image-upload').click()
}
function setLink() {
const previousUrl = editor.getAttributes('link').href
const url = window.prompt('URL', previousUrl)
// cancelled
if (url === null) {
return
}
// empty
if (url === '') {
editor.chain().focus().extendMarkRange('link').unsetLink().run()
return
}
// update link
editor
.chain()
.focus()
.extendMarkRange('link')
.setLink({href: url, target: '_blank'})
.run()
}
</script>
<style lang="scss" scoped>
.editor-toolbar {
background: var(--white);
border: 1px solid var(--grey-200);
user-select: none;
padding: .5rem;
border-radius: $radius;
display: flex;
flex-wrap: wrap;
> * + * {
border-left: 1px solid var(--grey-200);
margin-left: 6px;
padding-left: 6px;
}
}
.editor-toolbar__button {
min-width: 2rem;
height: 2rem;
border-radius: $radius;
border: 1px solid transparent;
color: var(--grey-700);
transition: all $transition;
background: transparent;
margin-right: .25rem;
&:hover {
background: var(--grey-100);
border-color: var(--grey-200);
}
.icon {
position: relative;
.icon__lower-text {
font-size: .75rem;
position: absolute;
bottom: -3px;
right: -2px;
font-weight: bold;
}
}
}
.editor-toolbar__table-buttons {
margin-top: .5rem;
> .editor-toolbar__button {
margin-right: .5rem;
margin-bottom: .5rem;
padding: 0 .25rem;
border: 1px solid var(--grey-400);
font-size: .75rem;
height: 1.5rem;
}
}
</style>

View File

@ -1,927 +0,0 @@
<template>
<div class="tiptap" ref="tiptapInstanceRef">
<EditorToolbar
v-if="editor && isEditing"
:editor="editor"
:upload-callback="uploadCallback"
/>
<BubbleMenu
v-if="editor && isEditing"
:editor="editor"
class="editor-bubble__wrapper"
>
<BaseButton
class="editor-bubble__button"
@click="editor.chain().focus().toggleBold().run()"
:class="{ 'is-active': editor.isActive('bold') }"
v-tooltip="$t('input.editor.bold')"
>
<icon :icon="['fa', 'fa-bold']"/>
</BaseButton>
<BaseButton
class="editor-bubble__button"
@click="editor.chain().focus().toggleItalic().run()"
:class="{ 'is-active': editor.isActive('italic') }"
v-tooltip="$t('input.editor.italic')"
>
<icon :icon="['fa', 'fa-italic']"/>
</BaseButton>
<BaseButton
class="editor-bubble__button"
@click="editor.chain().focus().toggleUnderline().run()"
:class="{ 'is-active': editor.isActive('underline') }"
v-tooltip="$t('input.editor.underline')"
>
<icon :icon="['fa', 'fa-underline']"/>
</BaseButton>
<BaseButton
class="editor-bubble__button"
@click="editor.chain().focus().toggleStrike().run()"
:class="{ 'is-active': editor.isActive('strike') }"
v-tooltip="$t('input.editor.strikethrough')"
>
<icon :icon="['fa', 'fa-strikethrough']"/>
</BaseButton>
<BaseButton
class="editor-bubble__button"
@click="editor.chain().focus().toggleCode().run()"
:class="{ 'is-active': editor.isActive('code') }"
v-tooltip="$t('input.editor.code')"
>
<icon :icon="['fa', 'fa-code']"/>
</BaseButton>
<BaseButton
class="editor-bubble__button"
@click="setLink"
:class="{ 'is-active': editor.isActive('link') }"
v-tooltip="$t('input.editor.link')"
>
<icon :icon="['fa', 'fa-link']"/>
</BaseButton>
</BubbleMenu>
<editor-content
class="tiptap__editor"
:class="{'tiptap__editor-is-edit-enabled': isEditing}"
:editor="editor"
/>
<input
v-if="isEditing"
type="file"
id="tiptap__image-upload"
class="is-hidden"
ref="uploadInputRef"
@change="addImage"
/>
<ul class="tiptap__editor-actions d-print-none" v-if="bottomActions.length === 0 && !isEditing">
<li>
<BaseButton
@click="setEdit"
class="done-edit">
{{ $t('input.editor.edit') }}
</BaseButton>
</li>
</ul>
<ul class="tiptap__editor-actions d-print-none" v-if="bottomActions.length > 0">
<li v-if="isEditing && showSave">
<BaseButton
@click="bubbleSave"
class="done-edit">
{{ $t('misc.save') }}
</BaseButton>
</li>
<li v-if="!isEditing">
<BaseButton
@click="setEdit"
class="done-edit">
{{ $t('input.editor.edit') }}
</BaseButton>
</li>
<li v-for="(action, k) in bottomActions" :key="k">
<BaseButton @click="action.action">{{ action.title }}</BaseButton>
</li>
</ul>
<x-button
v-else-if="isEditing && showSave"
class="mt-4"
@click="bubbleSave"
variant="secondary"
:shadow="false"
v-cy="'saveEditor'"
>
{{ $t('misc.save') }}
</x-button>
</div>
</template>
<script setup lang="ts">
import {computed, nextTick, onBeforeUnmount, onMounted, ref, watch} from 'vue'
import {refDebounced} from '@vueuse/core'
import EditorToolbar from './EditorToolbar.vue'
import Link from '@tiptap/extension-link'
import CodeBlockLowlight from '@tiptap/extension-code-block-lowlight'
import Table from '@tiptap/extension-table'
import TableCell from '@tiptap/extension-table-cell'
import TableHeader from '@tiptap/extension-table-header'
import TableRow from '@tiptap/extension-table-row'
import Typography from '@tiptap/extension-typography'
import Image from '@tiptap/extension-image'
import Underline from '@tiptap/extension-underline'
import TaskItem from '@tiptap/extension-task-item'
import TaskList from '@tiptap/extension-task-list'
import {Blockquote} from '@tiptap/extension-blockquote'
import {Bold} from '@tiptap/extension-bold'
import {BulletList} from '@tiptap/extension-bullet-list'
import {Code} from '@tiptap/extension-code'
import {Document} from '@tiptap/extension-document'
import {Dropcursor} from '@tiptap/extension-dropcursor'
import {Gapcursor} from '@tiptap/extension-gapcursor'
import {HardBreak} from '@tiptap/extension-hard-break'
import {Heading} from '@tiptap/extension-heading'
import {History} from '@tiptap/extension-history'
import {HorizontalRule} from '@tiptap/extension-horizontal-rule'
import {Italic} from '@tiptap/extension-italic'
import {ListItem} from '@tiptap/extension-list-item'
import {OrderedList} from '@tiptap/extension-ordered-list'
import {Paragraph} from '@tiptap/extension-paragraph'
import {Strike} from '@tiptap/extension-strike'
import {Text} from '@tiptap/extension-text'
import {BubbleMenu, EditorContent, useEditor} from '@tiptap/vue-3'
import {Node} from '@tiptap/pm/model'
import Commands from './commands'
import suggestionSetup from './suggestion'
import {lowlight} from 'lowlight'
import type {BottomAction, UploadCallback} from './types'
import type {ITask} from '@/modelTypes/ITask'
import type {IAttachment} from '@/modelTypes/IAttachment'
import AttachmentModel from '@/models/attachment'
import AttachmentService from '@/services/attachment'
import {useI18n} from 'vue-i18n'
import BaseButton from '@/components/base/BaseButton.vue'
import XButton from '@/components/input/button.vue'
import {Placeholder} from '@tiptap/extension-placeholder'
import {eventToHotkeyString} from '@github/hotkey'
import {mergeAttributes} from '@tiptap/core'
import {createRandomID} from '@/helpers/randomId'
const tiptapInstanceRef = ref<HTMLInputElement | null>(null)
const {t} = useI18n()
const CustomTableCell = TableCell.extend({
addAttributes() {
return {
// extend the existing attributes
...this.parent?.(),
// and add a new one
backgroundColor: {
default: null,
parseHTML: (element: HTMLElement) => element.getAttribute('data-background-color'),
renderHTML: (attributes) => {
return {
'data-background-color': attributes.backgroundColor,
style: `background-color: ${attributes.backgroundColor}`,
}
},
},
}
},
})
type CacheKey = `${ITask['id']}-${IAttachment['id']}`
const loadedAttachments = ref<{ [key: CacheKey]: string }>({})
const CustomImage = Image.extend({
addAttributes() {
return {
src: {
default: null,
},
alt: {
default: null,
},
title: {
default: null,
},
id: {
default: null,
},
'data-src': {
default: null,
},
}
},
renderHTML({HTMLAttributes}) {
if (HTMLAttributes.src?.startsWith(window.API_URL) || HTMLAttributes['data-src']?.startsWith(window.API_URL)) {
const imageUrl = HTMLAttributes['data-src'] ?? HTMLAttributes.src
const id = 'tiptap-image-' + createRandomID()
nextTick(async () => {
const img = document.getElementById(id)
if (!img) return
// The url is something like /tasks/<id>/attachments/<id>
const parts = imageUrl.slice(window.API_URL.length + 1).split('/')
const taskId = Number(parts[1])
const attachmentId = Number(parts[3])
const cacheKey: CacheKey = `${taskId}-${attachmentId}`
if (typeof loadedAttachments.value[cacheKey] === 'undefined') {
const attachment = new AttachmentModel({taskId: taskId, id: attachmentId})
const attachmentService = new AttachmentService()
loadedAttachments.value[cacheKey] = await attachmentService.getBlobUrl(attachment)
}
img.src = loadedAttachments.value[cacheKey]
})
return ['img', mergeAttributes(this.options.HTMLAttributes, {
'data-src': imageUrl,
src: '#',
alt: HTMLAttributes.alt,
title: HTMLAttributes.title,
id,
})]
}
return ['img', mergeAttributes(this.options.HTMLAttributes, HTMLAttributes)]
},
})
type Mode = 'edit' | 'preview'
const {
modelValue,
uploadCallback,
isEditEnabled = true,
bottomActions = [],
showSave = false,
placeholder = '',
editShortcut = '',
initialMode = 'edit',
} = defineProps<{
modelValue: string,
uploadCallback?: UploadCallback,
isEditEnabled?: boolean,
bottomActions?: BottomAction[],
showSave?: boolean,
placeholder?: string,
editShortcut?: string,
initialMode?: Mode,
}>()
const emit = defineEmits(['update:modelValue', 'save'])
const inputHTML = ref('')
const internalMode = ref<Mode>(initialMode)
const isEditing = computed(() => internalMode.value === 'edit' && isEditEnabled)
const editor = useEditor({
content: modelValue,
editable: isEditing.value,
extensions: [
// Starterkit:
Blockquote,
Bold,
BulletList,
Code,
CodeBlockLowlight.configure({
lowlight,
}),
Document,
Dropcursor,
Gapcursor,
HardBreak.extend({
addKeyboardShortcuts() {
return {
'Mod-Enter': () => {
bubbleSave()
},
}
},
}),
Heading,
History,
HorizontalRule,
Italic,
ListItem,
OrderedList,
Paragraph,
Strike,
Text,
Placeholder.configure({
placeholder: ({editor}) => {
if (!isEditing.value) {
return ''
}
if (editor.getText() !== '' && !editor.isFocused) {
return ''
}
return placeholder !== ''
? placeholder
: t('input.editor.placeholder')
},
}),
Typography,
Underline,
Link.configure({
openOnClick: true,
validate: (href: string) => /^https?:\/\//.test(href),
}),
Table.configure({
resizable: true,
}),
TableRow,
TableHeader,
// Custom TableCell with backgroundColor attribute
CustomTableCell,
CustomImage,
TaskList,
TaskItem.configure({
nested: true,
onReadOnlyChecked: (node: Node, checked: boolean): boolean => {
if (isEditEnabled) {
node.attrs.checked = checked
inputHTML.value = editor.value?.getHTML()
bubbleSave()
return true
}
return false
},
}),
Commands.configure({
suggestion: suggestionSetup(t),
}),
BubbleMenu,
],
onUpdate: () => {
inputHTML.value = editor.value!.getHTML()
},
})
watch(
() => modelValue,
value => {
inputHTML.value = value
if (!editor?.value) return
if (editor.value.getHTML() === value) {
return
}
editor.value.commands.setContent(value, false)
},
)
const debouncedInputHTML = refDebounced(inputHTML, 1000)
watch(debouncedInputHTML, () => bubbleNow())
function bubbleNow() {
emit('update:modelValue', inputHTML.value)
}
function bubbleSave() {
bubbleNow()
emit('save', inputHTML.value)
if (isEditing.value) {
internalMode.value = 'preview'
}
}
function setEdit() {
internalMode.value = 'edit'
editor.value?.commands.focus()
}
watch(
() => isEditing.value,
() => {
editor.value?.setEditable(isEditing.value)
},
)
onBeforeUnmount(() => editor.value?.destroy())
const uploadInputRef = ref<HTMLInputElement | null>(null)
function uploadAndInsertFiles(files: File[] | FileList) {
uploadCallback(files).then(urls => {
urls?.forEach(url => {
editor.value
?.chain()
.focus()
.setImage({src: url})
.run()
})
bubbleSave()
})
}
function addImage() {
if (typeof uploadCallback !== 'undefined') {
const files = uploadInputRef.value?.files
if (!files || files.length === 0) {
return
}
uploadAndInsertFiles(files)
return
}
const url = window.prompt('URL')
if (url) {
editor.value?.chain().focus().setImage({src: url}).run()
bubbleSave()
}
}
function setLink() {
const previousUrl = editor.value?.getAttributes('link').href
const url = window.prompt('URL', previousUrl)
// cancelled
if (url === null) {
return
}
// empty
if (url === '') {
editor.value
?.chain()
.focus()
.extendMarkRange('link')
.unsetLink()
.run()
return
}
// update link
editor.value
?.chain()
.focus()
.extendMarkRange('link')
.setLink({href: url, target: '_blank'})
.run()
}
onMounted(() => {
internalMode.value = initialMode
nextTick(() => {
const input = tiptapInstanceRef.value?.querySelectorAll('.tiptap__editor')[0]?.children[0]
input?.addEventListener('paste', handleImagePaste)
})
if (editShortcut !== '') {
document.addEventListener('keydown', setFocusToEditor)
}
})
onBeforeUnmount(() => {
nextTick(() => {
const input = tiptapInstanceRef.value?.querySelectorAll('.tiptap__editor')[0]?.children[0]
input?.removeEventListener('paste', handleImagePaste)
})
if (editShortcut !== '') {
document.removeEventListener('keydown', setFocusToEditor)
}
})
function handleImagePaste(event) {
if (event?.clipboardData?.items?.length === 0) {
return
}
event.preventDefault()
const image = event.clipboardData.items[0]
if (image.kind === 'file' && image.type.startsWith('image/')) {
console.log('img', image.getAsFile())
uploadAndInsertFiles([image.getAsFile()])
}
}
// See https://github.com/github/hotkey/discussions/85#discussioncomment-5214660
function setFocusToEditor(event) {
const hotkeyString = eventToHotkeyString(event)
if (!hotkeyString) return
if (hotkeyString !== editShortcut ||
event.target.tagName.toLowerCase() === 'input' ||
event.target.tagName.toLowerCase() === 'textarea' ||
event.target.contentEditable === 'true') {
return
}
event.preventDefault()
if (initialMode === 'preview' && isEditEnabled && !isEditing.value) {
internalMode.value = 'edit'
}
editor.value?.commands.focus()
}
function clickTasklistCheckbox(event) {
event.stopImmediatePropagation()
if (event.target.localName !== 'p') {
return
}
event.target.parentNode.parentNode.firstChild.click()
}
watch(
() => isEditing.value,
editing => {
nextTick(() => {
const checkboxes = tiptapInstanceRef.value?.querySelectorAll('[data-checked]')
if (typeof checkboxes === 'undefined' || checkboxes.length === 0) {
return
}
if (editing) {
checkboxes.forEach(check => {
if (check.children.length < 2) {
return
}
// We assume the first child contains the label element with the checkbox and the second child the actual label
// When the actual label is clicked, we forward that click to the checkbox.
check.children[1].removeEventListener('click', clickTasklistCheckbox)
})
return
}
checkboxes.forEach(check => {
if (check.children.length < 2) {
return
}
// We assume the first child contains the label element with the checkbox and the second child the actual label
// When the actual label is clicked, we forward that click to the checkbox.
check.children[1].addEventListener('click', clickTasklistCheckbox)
})
})
},
{immediate: true},
)
</script>
<style lang="scss">
.tiptap__editor {
&.tiptap__editor-is-edit-enabled {
min-height: 10rem;
.ProseMirror {
padding: .5rem;
}
&:focus-within, &:focus {
box-shadow: 0 0 0 2px hsla(var(--primary-hsl), 0.5);
}
ul[data-type='taskList'] li > div {
cursor: text;
}
}
transition: box-shadow $transition;
border-radius: $radius;
}
.tiptap p::before {
content: attr(data-placeholder);
color: var(--grey-400);
pointer-events: none;
height: 0;
float: left;
}
// Basic editor styles
.ProseMirror {
padding: .5rem .5rem .5rem 0;
&:focus-within, &:focus {
box-shadow: none;
}
> * + * {
margin-top: 0.75em;
}
ul,
ol {
padding: 0 1rem;
}
h1,
h2,
h3,
h4,
h5,
h6 {
line-height: 1.1;
}
a {
color: #68cef8;
}
code {
background-color: rgba(#616161, 0.1);
color: #616161;
}
pre {
background: #0d0d0d;
color: #fff;
font-family: 'JetBrainsMono', monospace;
padding: 0.75rem 1rem;
border-radius: 0.5rem;
code {
color: inherit;
padding: 0;
background: none;
font-size: 0.8rem;
}
}
pre {
background: #0d0d0d;
color: #fff;
font-family: 'JetBrainsMono', monospace;
padding: 0.75rem 1rem;
border-radius: 0.5rem;
code {
color: inherit;
padding: 0;
background: none;
font-size: 0.8rem;
}
.hljs-comment,
.hljs-quote {
color: #616161;
}
.hljs-variable,
.hljs-template-variable,
.hljs-attribute,
.hljs-tag,
.hljs-name,
.hljs-regexp,
.hljs-link,
.hljs-name,
.hljs-selector-id,
.hljs-selector-class {
color: #f98181;
}
.hljs-number,
.hljs-meta,
.hljs-built_in,
.hljs-builtin-name,
.hljs-literal,
.hljs-type,
.hljs-params {
color: #fbbc88;
}
.hljs-string,
.hljs-symbol,
.hljs-bullet {
color: #b9f18d;
}
.hljs-title,
.hljs-section {
color: #faf594;
}
.hljs-keyword,
.hljs-selector-tag {
color: #70cff8;
}
.hljs-emphasis {
font-style: italic;
}
.hljs-strong {
font-weight: 700;
}
}
img {
max-width: 100%;
height: auto;
&.ProseMirror-selectednode {
outline: 3px solid #68cef8;
}
}
blockquote {
padding-left: 1rem;
border-left: 2px solid rgba(#0d0d0d, 0.1);
}
hr {
border: none;
border-top: 2px solid rgba(#0d0d0d, 0.1);
margin: 2rem 0;
}
}
.ProseMirror {
/* Table-specific styling */
table {
border-collapse: collapse;
table-layout: fixed;
width: 100%;
margin: 0;
overflow: hidden;
td,
th {
min-width: 1em;
border: 2px solid #ced4da;
padding: 3px 5px;
vertical-align: top;
box-sizing: border-box;
position: relative;
> * {
margin-bottom: 0;
}
}
th {
font-weight: bold;
text-align: left;
background-color: #f1f3f5;
}
.selectedCell:after {
z-index: 2;
position: absolute;
content: '';
left: 0;
right: 0;
top: 0;
bottom: 0;
background: rgba(200, 200, 255, 0.4);
pointer-events: none;
}
.column-resize-handle {
position: absolute;
right: -2px;
top: 0;
bottom: -2px;
width: 4px;
background-color: #adf;
pointer-events: none;
}
p {
margin: 0;
}
}
// Lists
ul {
margin-left: .5rem;
margin-top: 0 !important;
li {
margin-top: 0;
}
p {
margin-bottom: 0 !important;
}
}
}
.tableWrapper {
overflow-x: auto;
}
.resize-cursor {
cursor: ew-resize;
cursor: col-resize;
}
// tasklist
ul[data-type='taskList'] {
list-style: none;
padding: 0;
margin-left: 0;
li {
display: flex;
> label {
flex: 0 0 auto;
margin-right: 0.5rem;
user-select: none;
}
> div {
flex: 1 1 auto;
cursor: pointer;
}
}
input[type='checkbox'] {
cursor: pointer;
}
}
.editor-bubble__wrapper {
background: var(--white);
border-radius: $radius;
border: 1px solid var(--grey-200);
box-shadow: var(--shadow-md);
display: flex;
overflow: hidden;
}
.editor-bubble__button {
color: var(--grey-700);
transition: all $transition;
background: transparent;
svg {
box-sizing: border-box;
display: block;
width: 1rem;
height: 1rem;
padding: .5rem;
margin: 0;
}
&:hover {
background: var(--grey-200);
}
}
ul.tiptap__editor-actions {
font-size: .8rem;
margin: 0;
li {
display: inline-block;
&::after {
content: '·';
padding: 0 .25rem;
}
&:last-child:after {
content: '';
}
}
&, a {
color: var(--grey-500);
&.done-edit {
color: var(--primary);
}
}
a:hover {
text-decoration: underline;
}
}
</style>

View File

@ -1,28 +0,0 @@
import {Extension} from '@tiptap/core'
import Suggestion from '@tiptap/suggestion'
// Copied and adjusted from https://github.com/ueberdosis/tiptap/tree/252acb32d27a0f9af14813eeed83d8a50059a43a/demos/src/Experiments/Commands/Vue
export default Extension.create({
name: 'slash-menu-commands',
addOptions() {
return {
suggestion: {
char: '/',
command: ({editor, range, props}) => {
props.command({editor, range})
},
},
}
},
addProseMirrorPlugins() {
return [
Suggestion({
editor: this.editor,
...this.options.suggestion,
}),
]
},
})

View File

@ -1,214 +0,0 @@
import {VueRenderer} from '@tiptap/vue-3'
import tippy from 'tippy.js'
import CommandsList from './CommandsList.vue'
export default function suggestionSetup(t) {
return {
items: ({query}: { query: string }) => {
return [
{
title: t('input.editor.text'),
description: t('input.editor.textTooltip'),
icon: 'fa-font',
command: ({editor, range}) => {
editor
.chain()
.focus()
.deleteRange(range)
.setNode('paragraph', {level: 1})
.run()
},
},
{
title: t('input.editor.heading1'),
description: t('input.editor.heading1Tooltip'),
icon: 'fa-header',
command: ({editor, range}) => {
editor
.chain()
.focus()
.deleteRange(range)
.setNode('heading', {level: 1})
.run()
},
},
{
title: t('input.editor.heading2'),
description: t('input.editor.heading2Tooltip'),
icon: 'fa-header',
command: ({editor, range}) => {
editor
.chain()
.focus()
.deleteRange(range)
.setNode('heading', {level: 2})
.run()
},
},
{
title: t('input.editor.heading3'),
description: t('input.editor.heading3Tooltip'),
icon: 'fa-header',
command: ({editor, range}) => {
editor
.chain()
.focus()
.deleteRange(range)
.setNode('heading', {level: 2})
.run()
},
},
{
title: t('input.editor.bulletList'),
description: t('input.editor.bulletListTooltip'),
icon: 'fa-list-ul',
command: ({editor, range}) => {
editor
.chain()
.focus()
.deleteRange(range)
.toggleBulletList()
.run()
},
},
{
title: t('input.editor.orderedList'),
description: t('input.editor.orderedListTooltip'),
icon: 'fa-list-ol',
command: ({editor, range}) => {
editor
.chain()
.focus()
.deleteRange(range)
.toggleOrderedList()
.run()
},
},
{
title: t('input.editor.taskList'),
description: t('input.editor.taskListTooltip'),
icon: 'fa-list-check',
command: ({editor, range}) => {
editor
.chain()
.focus()
.deleteRange(range)
.toggleTaskList()
.run()
},
},
{
title: t('input.editor.quote'),
description: t('input.editor.quoteTooltip'),
icon: 'fa-quote-right',
command: ({editor, range}) => {
editor
.chain()
.focus()
.deleteRange(range)
.toggleBlockquote()
.run()
},
},
{
title: t('input.editor.code'),
description: t('input.editor.codeTooltip'),
icon: 'fa-code',
command: ({editor, range}) => {
editor
.chain()
.focus()
.deleteRange(range)
.toggleCodeBlock()
.run()
},
},
{
title: t('input.editor.image'),
description: t('input.editor.imageTooltip'),
icon: 'fa-image',
command: ({editor, range}) => {
editor
.chain()
.focus()
.deleteRange(range)
.run()
document.getElementById('tiptap__image-upload').click()
},
},
{
title: t('input.editor.horizontalRule'),
description: t('input.editor.horizontalRuleTooltip'),
icon: 'fa-ruler-horizontal',
command: ({editor, range}) => {
editor
.chain()
.focus()
.deleteRange(range)
.setHorizontalRule()
.run()
},
},
].filter(item => item.title.toLowerCase().startsWith(query.toLowerCase()))
},
render: () => {
let component: VueRenderer
let popup
return {
onStart: props => {
component = new VueRenderer(CommandsList, {
// using vue 2:
// parent: this,
// propsData: props,
props,
editor: props.editor,
})
if (!props.clientRect) {
return
}
popup = tippy('body', {
getReferenceClientRect: props.clientRect,
appendTo: () => document.body,
content: component.element,
showOnCreate: true,
interactive: true,
trigger: 'manual',
placement: 'bottom-start',
})
},
onUpdate(props) {
component.updateProps(props)
if (!props.clientRect) {
return
}
popup[0].setProps({
getReferenceClientRect: props.clientRect,
})
},
onKeyDown(props) {
if (props.event.key === 'Escape') {
popup[0].hide()
return true
}
return component.ref?.onKeyDown(props)
},
onExit() {
popup[0].destroy()
component.destroy()
},
}
},
}
}

View File

@ -1,6 +0,0 @@
export type UploadCallback = (files: File[] | FileList) => Promise<string[]>
export interface BottomAction {
title: string
action: () => void,
}

View File

@ -0,0 +1,135 @@
import EasyMDE from 'easymde'
import {i18n} from '@/i18n'
export function createEasyMDEConfig({ placeholder, uploadImage, imageUploadFunction }) {
return {
autoDownloadFontAwesome: false,
spellChecker: false,
placeholder,
uploadImage,
imageUploadFunction,
minHeight: '150px',
sideBySideFullscreen: false,
toolbar: [
{
name: 'heading-1',
action: EasyMDE.toggleHeading1,
title: i18n.global.t('input.editor.heading1'),
icon: '<svg viewBox="0 0 24 24"><rect fill="none" rx="0" ry="0"/><path fill="currentColor" fill-rule="evenodd" clip-rule="evenodd" d="M18.2773 19.25L12.5773 4.34995C12.5773 4.34995 12.5773 4.24995 12.4773 4.24995C12.4773 4.24995 12.4773 4.14995 12.3773 4.14995C12.3773 4.14995 12.2773 4.14995 12.2773 4.04995L12.1773 3.94995H12.0773H11.9773C11.8773 3.94995 11.8773 3.94995 11.8773 3.94995H11.7773C11.6773 4.04995 11.6773 4.14995 11.5773 4.14995C11.5773 4.14995 11.5773 4.14995 11.4773 4.14995C11.4773 4.14995 11.4773 4.24995 11.3773 4.24995L11.2773 4.34995L5.67733 19.25C5.57733 19.55 5.67733 19.95 5.97733 20.05C6.07733 20.05 6.07733 20.05 6.17733 20.05C6.37733 20.05 6.67733 19.95 6.77733 19.65L7.87733 16.85H16.1773L17.2773 19.65C17.3773 19.85 17.5773 20.05 17.8773 20.05C17.9773 20.05 17.9773 20.05 18.0773 20.05C18.2773 19.85 18.4773 19.55 18.2773 19.25ZM8.27733 15.65L11.9773 6.24995L15.6773 15.65H8.27733Z"/></svg>',
},
{
name: 'heading-2',
action: EasyMDE.toggleHeading2,
title: i18n.global.t('input.editor.heading2'),
icon: '<svg viewBox="0 0 24 24"><rect fill="none" rx="0" ry="0"/><path fill="currentColor" fill-rule="evenodd" clip-rule="evenodd" d="M18.2773 19.25L12.5773 4.34995C12.5773 4.34995 12.5773 4.24995 12.4773 4.24995C12.4773 4.24995 12.4773 4.14995 12.3773 4.14995C12.3773 4.14995 12.2773 4.14995 12.2773 4.04995L12.1773 3.94995H12.0773H11.9773C11.8773 3.94995 11.8773 3.94995 11.8773 3.94995H11.7773C11.6773 4.04995 11.6773 4.14995 11.5773 4.14995C11.5773 4.14995 11.5773 4.14995 11.4773 4.14995C11.4773 4.14995 11.4773 4.24995 11.3773 4.24995L11.2773 4.34995L5.67733 19.25C5.57733 19.55 5.67733 19.95 5.97733 20.05C6.07733 20.05 6.07733 20.05 6.17733 20.05C6.37733 20.05 6.67733 19.95 6.77733 19.65L7.87733 16.85H16.1773L17.2773 19.65C17.3773 19.85 17.5773 20.05 17.8773 20.05C17.9773 20.05 17.9773 20.05 18.0773 20.05C18.2773 19.85 18.4773 19.55 18.2773 19.25ZM8.27733 15.65L11.9773 6.24995L15.6773 15.65H8.27733Z"/></svg>',
},
{
name: 'heading-3',
action: EasyMDE.toggleHeading3,
title: i18n.global.t('input.editor.heading3'),
icon: '<svg viewBox="0 0 24 24"><rect fill="none" rx="0" ry="0"/><path fill="currentColor" fill-rule="evenodd" clip-rule="evenodd" d="M18.2773 19.25L12.5773 4.34995C12.5773 4.34995 12.5773 4.24995 12.4773 4.24995C12.4773 4.24995 12.4773 4.14995 12.3773 4.14995C12.3773 4.14995 12.2773 4.14995 12.2773 4.04995L12.1773 3.94995H12.0773H11.9773C11.8773 3.94995 11.8773 3.94995 11.8773 3.94995H11.7773C11.6773 4.04995 11.6773 4.14995 11.5773 4.14995C11.5773 4.14995 11.5773 4.14995 11.4773 4.14995C11.4773 4.14995 11.4773 4.24995 11.3773 4.24995L11.2773 4.34995L5.67733 19.25C5.57733 19.55 5.67733 19.95 5.97733 20.05C6.07733 20.05 6.07733 20.05 6.17733 20.05C6.37733 20.05 6.67733 19.95 6.77733 19.65L7.87733 16.85H16.1773L17.2773 19.65C17.3773 19.85 17.5773 20.05 17.8773 20.05C17.9773 20.05 17.9773 20.05 18.0773 20.05C18.2773 19.85 18.4773 19.55 18.2773 19.25ZM8.27733 15.65L11.9773 6.24995L15.6773 15.65H8.27733Z"/></svg>',
},
{
name: 'heading-smaller',
action: EasyMDE.toggleHeadingSmaller,
title: i18n.global.t('input.editor.headingSmaller'),
icon: '<svg viewBox="0 0 24 24"><rect fill="none" rx="0" ry="0"/><path fill="currentColor" fill-rule="evenodd" clip-rule="evenodd" d="M18.2773 19.25L12.5773 4.34995C12.5773 4.34995 12.5773 4.24995 12.4773 4.24995C12.4773 4.24995 12.4773 4.14995 12.3773 4.14995C12.3773 4.14995 12.2773 4.14995 12.2773 4.04995L12.1773 3.94995H12.0773H11.9773C11.8773 3.94995 11.8773 3.94995 11.8773 3.94995H11.7773C11.6773 4.04995 11.6773 4.14995 11.5773 4.14995C11.5773 4.14995 11.5773 4.14995 11.4773 4.14995C11.4773 4.14995 11.4773 4.24995 11.3773 4.24995L11.2773 4.34995L5.67733 19.25C5.57733 19.55 5.67733 19.95 5.97733 20.05C6.07733 20.05 6.07733 20.05 6.17733 20.05C6.37733 20.05 6.67733 19.95 6.77733 19.65L7.87733 16.85H16.1773L17.2773 19.65C17.3773 19.85 17.5773 20.05 17.8773 20.05C17.9773 20.05 17.9773 20.05 18.0773 20.05C18.2773 19.85 18.4773 19.55 18.2773 19.25ZM8.27733 15.65L11.9773 6.24995L15.6773 15.65H8.27733Z"/></svg>',
},
{
name: 'heading-bigger',
action: EasyMDE.toggleHeadingBigger,
title: i18n.global.t('input.editor.headingBigger'),
icon: '<svg viewBox="0 0 24 24"><rect fill="none" rx="0" ry="0"/><path fill="currentColor" fill-rule="evenodd" clip-rule="evenodd" d="M18.2773 19.25L12.5773 4.34995C12.5773 4.34995 12.5773 4.24995 12.4773 4.24995C12.4773 4.24995 12.4773 4.14995 12.3773 4.14995C12.3773 4.14995 12.2773 4.14995 12.2773 4.04995L12.1773 3.94995H12.0773H11.9773C11.8773 3.94995 11.8773 3.94995 11.8773 3.94995H11.7773C11.6773 4.04995 11.6773 4.14995 11.5773 4.14995C11.5773 4.14995 11.5773 4.14995 11.4773 4.14995C11.4773 4.14995 11.4773 4.24995 11.3773 4.24995L11.2773 4.34995L5.67733 19.25C5.57733 19.55 5.67733 19.95 5.97733 20.05C6.07733 20.05 6.07733 20.05 6.17733 20.05C6.37733 20.05 6.67733 19.95 6.77733 19.65L7.87733 16.85H16.1773L17.2773 19.65C17.3773 19.85 17.5773 20.05 17.8773 20.05C17.9773 20.05 17.9773 20.05 18.0773 20.05C18.2773 19.85 18.4773 19.55 18.2773 19.25ZM8.27733 15.65L11.9773 6.24995L15.6773 15.65H8.27733Z"/></svg>',
},
'|',
{
name: 'bold',
action: EasyMDE.toggleBold,
title: i18n.global.t('input.editor.bold'),
icon: '<svg viewBox="0 0 24 24"><rect fill="none" rx="0" ry="0"/><path fill="currentColor" fill-rule="evenodd" clip-rule="evenodd" d="M3.5 3H6.5H15.25C18.15 3 20.5 5.36 20.5 8.25C20.5 9.8 19.81 11.19 18.73 12.15C20.37 13.04 21.5 14.76 21.5 16.75C21.5 19.64 19.15 22 16.25 22H6.5H3.5C2.95 22 2.5 21.55 2.5 21C2.5 20.45 2.95 20 3.5 20H5.5V5H3.5C2.95 5 2.5 4.55 2.5 4C2.5 3.45 2.95 3 3.5 3ZM7.5 20H16.25C18.04 20 19.5 18.54 19.5 16.75C19.5 14.96 18.04 13.5 16.25 13.5H7.5V20ZM7.5 11.5H15.25C17.04 11.5 18.5 10.04 18.5 8.25C18.5 6.46 17.04 5 15.25 5H7.5V11.5Z"/></svg>',
},
{
name: 'italic',
action: EasyMDE.toggleItalic,
title: i18n.global.t('input.editor.italic'),
icon: '<svg viewBox="0 0 24 24"><rect fill="none" rx="0" ry="0"/><path fill="currentColor" fill-rule="evenodd" clip-rule="evenodd" d="M14.0967 4.2H17.0001C17.3301 4.2 17.6001 3.93 17.6001 3.6C17.6001 3.27 17.3301 3 17.0001 3H10.2001C9.8701 3 9.6001 3.27 9.6001 3.6C9.6001 3.93 9.8701 4.2 10.2001 4.2H12.8748L9.90335 19.8H6.9999C6.6699 19.8 6.3999 20.07 6.3999 20.4C6.3999 20.73 6.6699 21 6.9999 21H13.7999C14.1299 21 14.3999 20.73 14.3999 20.4C14.3999 20.07 14.1299 19.8 13.7999 19.8H11.1253L14.0967 4.2Z"/></svg>',
},
{
name: 'strikethrough',
action: EasyMDE.toggleStrikethrough,
title: i18n.global.t('input.editor.strikethrough'),
icon: '<svg viewBox="0 0 24 24"><rect fill="none" rx="0" ry="0"/><path fill="currentColor" fill-rule="evenodd" clip-rule="evenodd" d="M18.25 7.17005C18.25 7.50005 17.98 7.77005 17.65 7.77005C17.32 7.77005 17.05 7.50005 17.05 7.17005V5.96005C15.97 5.12005 14.17 4.56005 12.79 4.31005C11.1 4.00005 9.51 4.30005 8.41 5.12005C7.2 6.03005 6.67 7.67005 7.19 8.88005C7.56 9.73005 8.37 10.31 8.98 10.64C9.57215 10.9644 10.1961 11.2013 10.8465 11.3999H20.4C20.73 11.3999 21 11.6699 21 11.9999C21 12.3299 20.73 12.5999 20.4 12.5999H15.3012C16.6583 13.0929 17.5255 13.7765 17.95 14.69C18.73 16.36 17.74 18.33 16.36 19.41C15.05 20.4401 13.35 21 11.54 21H11.16C9.78 20.9401 8.34 20.5301 6.95 19.85V20.3601C6.95 20.6901 6.68 20.96 6.35 20.96C6.02 20.96 5.75 20.6901 5.75 20.3601V17.36C5.75 17.03 6.02 16.76 6.35 16.76C6.68 16.76 6.95 17.03 6.95 17.36V18.5C8.35 19.2801 9.81 19.74 11.21 19.8C12.86 19.89 14.46 19.39 15.62 18.48C16.6 17.71 17.37 16.3 16.86 15.21C16.55 14.54 15.8 14.0201 14.58 13.63C13.9711 13.4331 13.3222 13.2762 12.6906 13.1235C12.6168 13.1056 12.5432 13.0878 12.47 13.07C12.4313 13.0607 12.3925 13.0514 12.3537 13.0421C11.7861 12.9055 11.2108 12.767 10.6413 12.5999H3.6C3.27 12.5999 3 12.3299 3 11.9999C3 11.6699 3.27 11.3999 3.6 11.3999H7.90288C7.04984 10.8343 6.42752 10.1363 6.09 9.36005C5.34 7.63005 6.03 5.40005 7.69 4.16005C9.05 3.15005 10.99 2.77005 13 3.13005C13.64 3.25005 15.53 3.66005 17.05 4.53005V4.17005C17.05 3.84005 17.32 3.57005 17.65 3.57005C17.98 3.57005 18.25 3.84005 18.25 4.17005V7.17005Z"/></svg>',
},
{
name: 'code',
action: EasyMDE.toggleCodeBlock,
title: i18n.global.t('input.editor.code'),
icon: '<svg viewBox="0 0 24 24"><rect fill="none" rx="0" ry="0"/><path fill="currentColor" fill-rule="evenodd" clip-rule="evenodd" d="M8.57 20.9601C8.64 20.9901 8.71 21.0001 8.78 21.0001C9.02 21.0001 9.24 20.8501 9.34 20.6101L15.79 3.81005C15.9 3.50005 15.75 3.15005 15.44 3.03005C15.14 2.92005 14.79 3.07005 14.67 3.38005L8.22 20.1801C8.11 20.4901 8.26 20.8401 8.57 20.9601ZM7.00007 18.0001C6.85007 18.0001 6.69007 17.9401 6.58007 17.8201L1.18007 12.4201C0.950068 12.1901 0.950068 11.8101 1.18007 11.5701L6.58007 6.17006C6.81007 5.94006 7.19007 5.94006 7.43007 6.17006C7.66007 6.40006 7.66007 6.78006 7.43007 7.02006L2.45007 12.0001L7.43007 16.9801C7.66007 17.2101 7.66007 17.5901 7.43007 17.8301C7.31007 17.9401 7.15007 18.0001 7.00007 18.0001ZM17 18.0001C16.85 18.0001 16.69 17.9401 16.58 17.8201C16.35 17.5901 16.35 17.2101 16.58 16.9701L21.55 12.0001L16.57 7.02006C16.34 6.79006 16.34 6.41006 16.57 6.17006C16.81 5.94006 17.19 5.94006 17.42 6.17006L22.82 11.5701C23.05 11.8001 23.05 12.1801 22.82 12.4201L17.42 17.8201C17.31 17.9401 17.15 18.0001 17 18.0001Z"/></svg>',
},
{
name: 'quote',
action: EasyMDE.toggleBlockquote,
title: i18n.global.t('input.editor.quote'),
icon: '<svg viewBox="0 0 24 24"><rect fill="none" rx="0" ry="0"/><path fill="currentColor" fill-rule="evenodd" clip-rule="evenodd" d="M19.373 5.16357H5.62695C4.79102 5.16357 4.11133 5.84326 4.11133 6.6792V16.2095C4.11133 17.0464 4.79102 17.7261 5.62695 17.7261H6.8877V21.1245C6.8877 21.3667 7.0332 21.5854 7.25684 21.6782C7.33203 21.7095 7.41016 21.7241 7.4873 21.7241C7.64258 21.7241 7.7959 21.6636 7.91113 21.5493L11.748 17.7261H19.373C20.209 17.7261 20.8887 17.0464 20.8887 16.2095V6.6792C20.8887 5.84326 20.209 5.16357 19.373 5.16357ZM19.6895 16.2095C19.6895 16.3843 19.5469 16.5269 19.373 16.5269H11.5C11.3408 16.5269 11.1895 16.5894 11.0762 16.7017L8.08691 19.6802V17.1265C8.08691 16.7954 7.81836 16.5269 7.4873 16.5269H5.62695C5.45312 16.5269 5.31055 16.3843 5.31055 16.2095V6.6792C5.31055 6.50537 5.45312 6.36279 5.62695 6.36279H19.373C19.5469 6.36279 19.6895 6.50537 19.6895 6.6792V16.2095ZM10.3431 8.45264C9.46326 8.45264 8.75 9.16589 8.75 10.0458C8.75 10.9257 9.46326 11.639 10.3431 11.639C10.4775 11.639 10.6058 11.6173 10.7305 11.5861V11.6195C10.7305 12.1322 10.3135 12.5492 9.75586 12.5492C9.4248 12.5492 9.17871 12.8177 9.17871 13.1488C9.17871 13.4799 9.46973 13.7484 9.80078 13.7484C10.9746 13.7484 11.9297 12.7933 11.9297 11.6195V10.1176L11.9294 10.1165L11.9292 10.1155C11.9297 10.1049 11.9312 10.0946 11.9326 10.0843L11.9326 10.0843C11.9345 10.0716 11.9363 10.059 11.9363 10.0458C11.9363 9.16589 11.223 8.45264 10.3431 8.45264ZM13.0637 10.0458C13.0637 9.16589 13.7771 8.45264 14.657 8.45264C15.5369 8.45264 16.2501 9.16589 16.2501 10.0458C16.2501 10.0584 16.2484 10.0706 16.2466 10.0828C16.2452 10.0929 16.2437 10.103 16.2433 10.1134C16.2433 10.1149 16.2441 10.1161 16.2441 10.1176V11.6195C16.2441 12.7933 15.2891 13.7484 14.1152 13.7484C13.7842 13.7484 13.4922 13.4799 13.4922 13.1488C13.4922 12.8177 13.7383 12.5492 14.0693 12.5492C14.6279 12.5492 15.0449 12.1322 15.0449 11.6195V11.5858C14.9202 11.6173 14.7915 11.639 14.657 11.639C13.7771 11.639 13.0637 10.9257 13.0637 10.0458Z"/></svg>',
},
{
name: 'unordered-list',
action: EasyMDE.toggleUnorderedList,
title: i18n.global.t('input.editor.unorderedList'),
icon: '<svg viewBox="0 0 24 24"><rect fill="none" rx="0" ry="0"/><path fill="currentColor" fill-rule="evenodd" clip-rule="evenodd" d="M6.5281 3.7002H3.5281C3.1981 3.7002 2.9281 3.9702 2.9281 4.3002V7.3002C2.9281 7.6302 3.1981 7.9002 3.5281 7.9002H6.5281C6.8581 7.9002 7.1281 7.6302 7.1281 7.3002V4.3002C7.1281 3.9702 6.8581 3.7002 6.5281 3.7002ZM5.9281 6.7002H4.1281V4.9002H5.9281V6.7002ZM3.5281 9.90015H6.5281C6.8581 9.90015 7.1281 10.1701 7.1281 10.5001V13.5001C7.1281 13.8301 6.8581 14.1001 6.5281 14.1001H3.5281C3.1981 14.1001 2.9281 13.8301 2.9281 13.5001V10.5001C2.9281 10.1701 3.1981 9.90015 3.5281 9.90015ZM4.1281 12.9001H5.9281V11.1001H4.1281V12.9001ZM3.5281 16.1001H6.5281C6.8581 16.1001 7.1281 16.3701 7.1281 16.7001V19.7001C7.1281 20.0301 6.8581 20.3001 6.5281 20.3001H3.5281C3.1981 20.3001 2.9281 20.0301 2.9281 19.7001V16.7001C2.9281 16.3701 3.1981 16.1001 3.5281 16.1001ZM4.1281 19.1001H5.9281V17.3001H4.1281V19.1001ZM9.72817 6.4002H20.7282C21.0582 6.4002 21.3282 6.1302 21.3282 5.8002C21.3282 5.4702 21.0582 5.2002 20.7282 5.2002H9.72817C9.39817 5.2002 9.12817 5.4702 9.12817 5.8002C9.12817 6.1302 9.39817 6.4002 9.72817 6.4002ZM9.72817 11.4001H20.7282C21.0582 11.4001 21.3282 11.6701 21.3282 12.0001C21.3282 12.3301 21.0582 12.6001 20.7282 12.6001H9.72817C9.39817 12.6001 9.12817 12.3301 9.12817 12.0001C9.12817 11.6701 9.39817 11.4001 9.72817 11.4001ZM9.72817 17.6001H20.7282C21.0582 17.6001 21.3282 17.8701 21.3282 18.2001C21.3282 18.5301 21.0582 18.8001 20.7282 18.8001H9.72817C9.39817 18.8001 9.12817 18.5301 9.12817 18.2001C9.12817 17.8701 9.39817 17.6001 9.72817 17.6001Z"/></svg>',
},
{
name: 'ordered-list',
action: EasyMDE.toggleOrderedList,
title: i18n.global.t('input.editor.orderedList'),
icon: '<svg viewBox="0 0 24 24"><rect fill="none" rx="0" ry="0"/><path fill="currentColor" fill-rule="evenodd" clip-rule="evenodd" d="M4.19494 8.29994H5.99494C6.26494 8.29994 6.49494 8.07995 6.49494 7.79994C6.49494 7.51995 6.27494 7.29994 5.99494 7.29994H5.59494V3.79994C5.59494 3.62994 5.50494 3.46994 5.36494 3.37994C5.22494 3.28994 5.04494 3.26994 4.89494 3.33994L3.89494 3.76994C3.64494 3.87994 3.52494 4.17994 3.63494 4.42994C3.74494 4.67994 4.03494 4.79994 4.29494 4.68994L4.59494 4.55994V7.29994H4.19494C3.91494 7.29994 3.69494 7.51995 3.69494 7.79994C3.69494 8.07995 3.91494 8.29994 4.19494 8.29994ZM20.195 6.39995H9.19497C8.86497 6.39995 8.59497 6.12995 8.59497 5.79995C8.59497 5.46995 8.86497 5.19995 9.19497 5.19995H20.195C20.525 5.19995 20.795 5.46995 20.795 5.79995C20.795 6.12995 20.525 6.39995 20.195 6.39995ZM3.78486 14.36H6.37486C6.65486 14.36 6.87486 14.14 6.87486 13.86C6.87486 13.58 6.65486 13.36 6.37486 13.36H4.88486C5.00486 13.23 5.12486 13.09 5.23486 12.95C5.26626 12.9151 5.29645 12.8802 5.32626 12.8458L5.32629 12.8457C5.38192 12.7814 5.43627 12.7186 5.49486 12.66C5.73486 12.4 5.98486 12.12 6.17486 11.79C6.47486 11.25 6.41486 10.63 6.01486 10.17C5.57486 9.66 4.86486 9.5 4.24486 9.74C3.74486 9.95 3.39486 10.35 3.22486 10.91C3.14486 11.18 3.29486 11.46 3.56486 11.54C3.82486 11.61 4.10486 11.46 4.18486 11.2C4.29486 10.85 4.48486 10.73 4.62486 10.67C4.88486 10.57 5.13486 10.68 5.26486 10.82C5.38486 10.96 5.40486 11.12 5.30486 11.29C5.17595 11.5202 4.99618 11.7165 4.80458 11.9257L4.75486 11.98C4.67298 12.0801 4.58283 12.1801 4.49946 12.2727L4.49945 12.2727L4.47486 12.3C4.12486 12.72 3.76486 13.13 3.40486 13.53C3.27486 13.68 3.23486 13.9 3.32486 14.07C3.41486 14.24 3.58486 14.36 3.78486 14.36ZM3.68486 20.3699C4.04486 20.5899 4.46486 20.6999 4.87486 20.6999C5.13486 20.6999 5.38486 20.6499 5.61486 20.5499C6.31486 20.2799 6.73486 19.5599 6.60486 18.8799C6.53486 18.5499 6.35486 18.2899 6.12486 18.0899C6.32486 17.8999 6.45486 17.6499 6.50486 17.3799C6.57486 17.0099 6.49486 16.6299 6.27486 16.3099C5.85486 15.6899 5.07486 15.5199 4.10486 15.8299C3.83486 15.9199 3.69486 16.1999 3.77486 16.4599C3.86486 16.7299 4.14486 16.8699 4.40486 16.7899C4.70486 16.6999 5.24486 16.5799 5.45486 16.8899C5.51486 16.9899 5.54486 17.0999 5.52486 17.1999C5.51486 17.2699 5.47486 17.3599 5.36486 17.4299C5.26486 17.4999 5.12486 17.5399 4.95486 17.5799L4.77486 17.6299C4.54486 17.6999 4.40486 17.9099 4.41486 18.1499C4.42486 18.3899 4.61486 18.5799 4.84486 18.6099C5.20486 18.6599 5.58486 18.8299 5.63486 19.0799C5.67486 19.2999 5.46486 19.5499 5.25486 19.6299C4.94486 19.7599 4.52486 19.7099 4.21486 19.5199C3.97486 19.3699 3.67486 19.4399 3.52486 19.6799C3.37486 19.9199 3.44486 20.2299 3.68486 20.3699ZM20.195 18.7999H9.19497C8.86497 18.7999 8.59497 18.5299 8.59497 18.1999C8.59497 17.8699 8.86497 17.5999 9.19497 17.5999H20.195C20.525 17.5999 20.795 17.8699 20.795 18.1999C20.795 18.5299 20.525 18.7999 20.195 18.7999ZM9.19497 12.5999H20.195C20.525 12.5999 20.795 12.3299 20.795 11.9999C20.795 11.6699 20.525 11.3999 20.195 11.3999H9.19497C8.86497 11.3999 8.59497 11.6699 8.59497 11.9999C8.59497 12.3299 8.86497 12.5999 9.19497 12.5999Z"/></svg>',
},
'|',
{
name: 'clean-block',
action: EasyMDE.cleanBlock,
title: i18n.global.t('input.editor.cleanBlock'),
icon: '<svg viewBox="0 0 24 24"><rect fill="none" rx="0" ry="0"/><path fill="currentColor" fill-rule="evenodd" clip-rule="evenodd" d="M9.25989 6.18384H20.4513C20.7823 6.18384 21.0509 6.45239 21.0509 6.78345V17.9749C21.0509 18.3059 20.7823 18.5745 20.4513 18.5745H9.25989C9.0929 18.5745 8.93469 18.5061 8.82043 18.384L3.6095 12.7883C3.39563 12.5579 3.39563 12.2004 3.6095 11.97L8.82043 6.37427C8.93469 6.2522 9.0929 6.18384 9.25989 6.18384ZM9.52063 17.3752H19.8517V7.38306H9.52063L4.86926 12.3792L9.52063 17.3752ZM12.7755 15.0686C12.6222 15.0686 12.4679 15.01 12.3517 14.8928C12.1173 14.6584 12.1173 14.2786 12.3517 14.0452L14.0503 12.3469L12.3517 10.6487C12.1173 10.4153 12.1173 10.0354 12.3517 9.80103C12.5841 9.56665 12.965 9.56665 13.1993 9.80103L14.8981 11.4994L16.5968 9.80103C16.8312 9.56665 17.212 9.56665 17.4445 9.80103C17.6788 10.0354 17.6788 10.4153 17.4445 10.6487L15.7458 12.3469L17.4445 14.0452C17.6788 14.2786 17.6788 14.6584 17.4445 14.8928C17.3282 15.01 17.174 15.0686 17.0206 15.0686C16.8673 15.0686 16.714 15.01 16.5968 14.8928L14.8981 13.1945L13.1993 14.8928C13.0822 15.01 12.9288 15.0686 12.7755 15.0686Z"/></svg>',
},
{
name: 'link',
action: EasyMDE.drawLink,
title: i18n.global.t('input.editor.link'),
icon: '<svg viewBox="0 0 24 24"><rect fill="none" rx="0" ry="0"/><path fill="currentColor" fill-rule="evenodd" clip-rule="evenodd" d="M11.4399 15.3452C11.4999 15.3652 11.5699 15.3752 11.6299 15.3752C11.8799 15.3752 12.1199 15.2152 12.1999 14.9652C12.2999 14.6452 12.1299 14.3052 11.8199 14.2052C11.3499 14.0452 10.9299 13.7852 10.5699 13.4152C10.1999 13.0552 9.9399 12.6452 9.7799 12.1552C9.6599 11.8252 9.5999 11.4652 9.5999 11.0952C9.5999 10.2152 9.9399 9.38518 10.5699 8.75518L15.1599 4.15518C16.4499 2.87518 18.5399 2.87518 19.8299 4.15518C20.4499 4.78518 20.7899 5.61518 20.7899 6.49518C20.7899 7.37518 20.4499 8.20518 19.8299 8.82518L16.7399 11.9052C16.5099 12.1452 16.5099 12.5252 16.7399 12.7552C16.9799 12.9852 17.3599 12.9852 17.5899 12.7552L20.6799 9.67518C21.5299 8.83518 21.9999 7.69518 21.9999 6.49518C21.9999 5.29518 21.5299 4.16518 20.6899 3.30518C18.9299 1.55518 16.0799 1.55518 14.3199 3.30518L9.7299 7.90518C8.8699 8.75518 8.3999 9.88518 8.3999 11.0952C8.3999 11.6152 8.4899 12.1152 8.6499 12.5552C8.8599 13.1952 9.2399 13.7952 9.7199 14.2652C10.1999 14.7552 10.7999 15.1352 11.4399 15.3452ZM3.32 20.6851C4.2 21.5551 5.35 21.9951 6.5 21.9951C7.65 21.9951 8.81 21.5551 9.69 20.7051L14.28 16.1051C15.14 15.2551 15.61 14.1251 15.61 12.9151C15.61 12.4551 15.54 11.9951 15.4 11.5551C15.17 10.8651 14.8 10.2551 14.28 9.73509C13.76 9.21509 13.15 8.84509 12.46 8.61509C12.14 8.51509 11.8 8.68509 11.7 8.99509C11.6 9.30509 11.77 9.64509 12.1 9.75509C12.61 9.91509 13.06 10.1951 13.44 10.5751C13.82 10.9551 14.09 11.4051 14.26 11.9151C14.36 12.2351 14.41 12.5651 14.41 12.9051C14.41 13.7951 14.06 14.6251 13.43 15.2451L8.84 19.8451C7.55 21.1251 5.46 21.1251 4.17 19.8451C3.55 19.2151 3.21 18.3951 3.21 17.5051C3.21 16.6151 3.55 15.7851 4.17 15.1651L7.35 11.9851C7.58 11.7451 7.59 11.3651 7.35 11.1351C7.11 10.9051 6.73 10.9051 6.5 11.1351L3.32 14.3151C2.47 15.1551 2 16.2851 2 17.4951C2 18.7051 2.47 19.8351 3.32 20.6851Z"/></svg>',
},
{
name: 'image',
action: EasyMDE.drawImage,
title: i18n.global.t('input.editor.image'),
icon: '<svg viewBox="0 0 24 24"><rect fill="none" rx="0" ry="0"/><path fill="currentColor" fill-rule="evenodd" clip-rule="evenodd" d="M4 4C2.89543 4 2 4.89543 2 6V16V17.5152V18C2 19.1046 2.89543 20 4 20H20C21.0528 20 21.9156 19.1866 21.9942 18.1539L22 18.1632V18V16V6C22 4.89543 21.1046 4 20 4H4ZM3.2 17.7V16.5642L6.78192 13.7254C6.8616 13.6622 6.97597 13.6689 7.04776 13.7409L10.3126 17.0146C10.7026 17.4056 11.3357 17.4065 11.7268 17.0165C11.7606 16.9827 11.792 16.9465 11.8207 16.9083L16.736 10.352C16.8023 10.2636 16.9277 10.2457 17.016 10.312C17.0355 10.3265 17.0521 10.3445 17.0651 10.365L20.8 16.2669V17.7C20.8 18.3075 20.3075 18.8 19.7 18.8H4.3C3.69249 18.8 3.2 18.3075 3.2 17.7ZM17.3865 8.61836L20.8 14.08V6.3C20.8 5.69249 20.3075 5.2 19.7 5.2H4.3C3.69249 5.2 3.2 5.69249 3.2 6.3V15.04L6.65054 12.2796C6.84949 12.1204 7.13629 12.1363 7.31645 12.3164L10.8369 15.8369C10.915 15.915 11.0417 15.915 11.1198 15.8369C11.1265 15.8302 16.5625 8.58336 16.5625 8.58336C16.7282 8.36245 17.0416 8.31768 17.2625 8.48336C17.3118 8.52034 17.3538 8.56611 17.3865 8.61836ZM8 8.5C8 9.32843 7.32843 10 6.5 10C5.67157 10 5 9.32843 5 8.5C5 7.67157 5.67157 7 6.5 7C7.32843 7 8 7.67157 8 8.5Z"/></svg>',
},
{
name: 'table',
action: EasyMDE.drawTable,
title: i18n.global.t('input.editor.table'),
icon: '<svg viewBox="0 0 24 24"><rect fill="none" rx="0" ry="0"/><path fill="currentColor" fill-rule="evenodd" clip-rule="evenodd" d="M6.18524 3.08496H19.4152C20.6752 3.08496 21.7152 4.11496 21.7152 5.38496V18.615C21.7152 19.885 20.6852 20.915 19.4152 20.915H6.18524C4.91524 20.915 3.88525 19.885 3.88525 18.615V5.38496C3.88525 4.11496 4.91524 3.08496 6.18524 3.08496ZM19.4052 19.705C20.0152 19.705 20.5052 19.215 20.5052 18.605H20.5153V5.38496C20.5153 4.77496 20.0252 4.28496 19.4152 4.28496H6.18524C5.57524 4.28496 5.08521 4.77496 5.08521 5.38496V18.605C5.08521 19.215 5.57524 19.705 6.18524 19.705H19.4052ZM17.4453 9.15503H8.15527C7.82527 9.15503 7.5553 9.42503 7.5553 9.75503C7.5553 10.085 7.82527 10.355 8.15527 10.355H17.4453C17.7753 10.355 18.0453 10.085 18.0453 9.75503C18.0453 9.42503 17.7753 9.15503 17.4453 9.15503ZM17.4453 13.635H8.15527C7.82527 13.635 7.5553 13.905 7.5553 14.235C7.5553 14.565 7.82527 14.835 8.15527 14.835H17.4453C17.7753 14.835 18.0453 14.565 18.0453 14.235C18.0453 13.905 17.7753 13.635 17.4453 13.635Z"/></svg>',
},
{
name: 'horizontal-rule',
action: EasyMDE.drawHorizontalRule,
title: i18n.global.t('input.editor.horizontalRule'),
icon: '<svg viewBox="0 0 24 24"><rect fill="none" rx="0" ry="0"/><path fill="currentColor" fill-rule="evenodd" clip-rule="evenodd" d="M21 13H3C2.45 13 2 12.55 2 12C2 11.45 2.45 11 3 11H21C21.55 11 22 11.45 22 12C22 12.55 21.55 13 21 13Z"/></svg>',
},
'|',
{
name: 'side-by-side',
action: EasyMDE.toggleSideBySide,
title: i18n.global.t('input.editor.sideBySide'),
icon: '<svg viewBox="0 0 24 24"><rect fill="none" rx="0" ry="0"/><path fill="currentColor" fill-rule="evenodd" clip-rule="evenodd" d="M18.4787 14.58C18.3587 14.69 18.2987 14.85 18.2987 15C18.2987 15.15 18.3587 15.31 18.4787 15.42C18.7187 15.65 19.0987 15.65 19.3287 15.42L22.3287 12.42C22.5587 12.18 22.5587 11.8 22.3287 11.57L19.3287 8.56996C19.0887 8.33996 18.7087 8.33996 18.4787 8.56996C18.2487 8.80996 18.2487 9.18996 18.4787 9.41996L20.451 11.3999L14.4487 11.3999L14.4487 4.6C14.4487 4.27 14.1787 4 13.8487 4C13.5187 4 13.2487 4.27 13.2487 4.6L13.2487 19.4C13.2487 19.73 13.5187 20 13.8487 20C14.1787 20 14.4487 19.73 14.4487 19.4L14.4487 12.5999L20.4511 12.5999L18.4787 14.58ZM9.54878 19.4L9.54878 12.5999L3.5486 12.5999L5.52867 14.58C5.75867 14.81 5.75867 15.19 5.52867 15.43C5.29867 15.66 4.91867 15.66 4.67867 15.43L1.67867 12.43C1.63274 12.384 1.5956 12.3323 1.56725 12.2774C1.53058 12.2077 1.50724 12.1299 1.50068 12.0477C1.49934 12.0317 1.49867 12.0158 1.49867 12C1.49867 11.9841 1.49933 11.9682 1.50067 11.9522C1.51454 11.778 1.60365 11.6242 1.73526 11.5234L4.67867 8.57997C4.90867 8.34997 5.28867 8.34997 5.52867 8.57997C5.75867 8.80997 5.75867 9.18997 5.52867 9.42997L3.55107 11.3999L9.54878 11.3999L9.54878 4.6C9.54878 4.27 9.81878 4 10.1488 4C10.4788 4 10.7488 4.27 10.7488 4.6L10.7488 11.9999L10.7488 19.4C10.7488 19.73 10.4788 20 10.1488 20C9.81878 20 9.54878 19.73 9.54878 19.4Z"/></svg>',
},
{
name: 'guide',
action() {
window.open('https://www.markdownguide.org/basic-syntax/', '_blank')
},
title: i18n.global.t('input.editor.guide'),
icon: '<svg viewBox="0 0 24 24"><rect fill="none" rx="0" ry="0"/><path fill="currentColor" fill-rule="evenodd" clip-rule="evenodd" d="M19.4999 2.3999H6.4999C5.0699 2.3999 3.8999 3.5699 3.8999 4.9999V18.9999C3.8999 20.4299 5.0699 21.5999 6.4999 21.5999H19.4999C19.8299 21.5999 20.0999 21.3299 20.0999 20.9999V16.9999V2.9999C20.0999 2.6699 19.8299 2.3999 19.4999 2.3999ZM5.0999 4.9999V16.8118C5.50468 16.5513 5.98546 16.3999 6.4999 16.3999H18.8999V3.5999H6.4999C5.7299 3.5999 5.0999 4.2299 5.0999 4.9999ZM6.4999 17.5999H18.8999V20.3999H6.4999C5.7299 20.3999 5.0999 19.7699 5.0999 18.9999C5.0999 18.2299 5.7299 17.5999 6.4999 17.5999ZM8.4999 8.5999H15.4999C15.8299 8.5999 16.0999 8.3299 16.0999 7.9999C16.0999 7.6699 15.8299 7.3999 15.4999 7.3999H8.4999C8.1699 7.3999 7.8999 7.6699 7.8999 7.9999C7.8999 8.3299 8.1699 8.5999 8.4999 8.5999ZM15.4999 11.3999H8.4999C8.1699 11.3999 7.8999 11.6699 7.8999 11.9999C7.8999 12.3299 8.1699 12.5999 8.4999 12.5999H15.4999C15.8299 12.5999 16.0999 12.3299 16.0999 11.9999C16.0999 11.6699 15.8299 11.3999 15.4999 11.3999Z"/></svg>',
},
],
}
}

View File

@ -9,9 +9,9 @@
<div class="control" :class="{'is-loading': loading || localLoading}">
<div
class="input-wrapper input"
:class="{'has-multiple': hasMultiple, 'has-removal-button': removalAvailable}"
:class="{'has-multiple': hasMultiple}"
>
<slot
<slot
v-if="Array.isArray(internalValue)"
name="items"
:items="internalValue"
@ -19,14 +19,14 @@
>
<template v-for="(item, key) in internalValue">
<slot name="tag" :item="item">
<span :key="`item${key}`" class="tag ml-2 mt-2">
{{ label !== '' ? item[label] : item }}
<BaseButton @click="() => remove(item)" class="delete is-small"></BaseButton>
</span>
<span :key="`item${key}`" class="tag ml-2 mt-2">
{{ label !== '' ? item[label] : item }}
<BaseButton @click="() => remove(item)" class="delete is-small"></BaseButton>
</span>
</slot>
</template>
</slot>
<input
type="text"
class="input"
@ -40,13 +40,6 @@
:autocomplete="autocompleteEnabled ? undefined : 'off'"
:spellcheck="autocompleteEnabled ? undefined : 'false'"
/>
<BaseButton
v-if="removalAvailable"
class="removal-button"
@click="resetSelectedValue"
>
<icon icon="times"/>
</BaseButton>
</div>
</div>
@ -107,7 +100,6 @@ import {closeWhenClickedOutside} from '@/helpers/closeWhenClickedOutside'
import BaseButton from '@/components/base/BaseButton.vue'
import CustomTransition from '@/components/misc/CustomTransition.vue'
// eslint-disable-next-line @typescript-eslint/no-explicit-any
function elementInResults(elem: string | any, label: string, query: string): boolean {
// Don't make create available if we have an exact match in our search results.
if (label !== '') {
@ -136,8 +128,7 @@ const props = defineProps({
* The search results where the @search listener needs to put the results into
*/
searchResults: {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
type: Array as PropType<{ [id: string]: any }>,
type: Array as PropType<{[id: string]: any}>,
default: () => [],
},
/**
@ -152,8 +143,7 @@ const props = defineProps({
* The object with the value, updated every time an entry is selected.
*/
modelValue: {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
type: [Object] as PropType<{ [key: string]: any }>,
type: [Object] as PropType<{[key: string]: any}>,
default: null,
},
/**
@ -169,7 +159,7 @@ const props = defineProps({
createPlaceholder: {
type: String,
default() {
const {t} = useI18n({useScope: 'global'})
const {t} = useI18n({useScope: 'global'})
return t('input.multiselect.createPlaceholder')
},
},
@ -179,7 +169,7 @@ const props = defineProps({
selectPlaceholder: {
type: String,
default() {
const {t} = useI18n({useScope: 'global'})
const {t} = useI18n({useScope: 'global'})
return t('input.multiselect.selectPlaceholder')
},
},
@ -225,33 +215,30 @@ const props = defineProps({
})
const emit = defineEmits<{
(e: 'update:modelValue', value: null): void
(e: 'update:modelValue', value: null): void
/**
* Triggered every time the search query input changes
*/
(e: 'search', query: string): void
(e: 'search', query: string): void
/**
* Triggered every time an option from the search results is selected. Also triggers a change in v-model.
*/
// eslint-disable-next-line @typescript-eslint/no-explicit-any
(e: 'select', value: { [key: string]: any }): void
(e: 'select', value: {[key: string]: any}): void
/**
* If nothing or no exact match was found and `creatable` is true, this event is triggered with the current value of the search query.
*/
(e: 'create', query: string): void
(e: 'create', query: string): void
/**
* If `multiple` is enabled, this will be fired every time an item is removed from the array of selected items.
*/
(e: 'remove', value: null): void
(e: 'remove', value: null): void
}>()
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const query = ref<string | { [key: string]: any }>('')
const query = ref<string | {[key: string]: any}>('')
const searchTimeout = ref<ReturnType<typeof setTimeout> | null>(null)
const localLoading = ref(false)
const showSearchResults = ref(false)
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const internalValue = ref<string | { [key: string]: any } | any[] | null>(null)
const internalValue = ref<string | {[key: string]: any} | any[] | null>(null)
onMounted(() => document.addEventListener('click', hideSearchResultsHandler))
onBeforeUnmount(() => document.removeEventListener('click', hideSearchResultsHandler))
@ -279,19 +266,17 @@ const searchResultsVisible = computed(() => {
})
const creatableAvailable = computed(() => {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const hasResult = filteredSearchResults.value.some((elem: any) => elementInResults(elem, props.label, query.value))
const hasQueryAlreadyAdded = Array.isArray(internalValue.value) && internalValue.value.some(elem => elementInResults(elem, props.label, query.value))
return props.creatable
&& query.value !== ''
return props.creatable
&& query.value !== ''
&& !(hasResult || hasQueryAlreadyAdded)
})
const filteredSearchResults = computed(() => {
const currentInternal = internalValue.value
if (props.multiple && currentInternal !== null && Array.isArray(currentInternal)) {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
return searchResults.value.filter((item: any) => !currentInternal.some(e => e === item))
}
@ -302,13 +287,7 @@ const hasMultiple = computed(() => {
return props.multiple && Array.isArray(internalValue.value) && internalValue.value.length > 0
})
const removalAvailable = computed(() => !props.multiple && internalValue.value !== null && query.value !== '')
function resetSelectedValue() {
select(null)
}
const searchInput = ref<HTMLInputElement | null>(null)
// Searching will be triggered with a 200ms delay to avoid searching on every keyup event.
function search() {
@ -333,7 +312,6 @@ function search() {
}
const multiselectRoot = ref<HTMLElement | null>(null)
function hideSearchResultsHandler(e: MouseEvent) {
closeWhenClickedOutside(e, multiselectRoot.value, closeSearchResults)
}
@ -350,14 +328,12 @@ function handleFocus() {
}, 10)
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
function select(object: { [key: string]: any } | null) {
function select(object: {[key: string]: any}) {
if (props.multiple) {
if (internalValue.value === null) {
internalValue.value = []
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
(internalValue.value as any[]).push(object)
} else {
internalValue.value = object
@ -371,8 +347,7 @@ function select(object: { [key: string]: any } | null) {
}
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
function setSelectedObject(object: string | { [id: string]: any } | null, resetOnly = false) {
function setSelectedObject(object: string | {[id: string]: any} | null, resetOnly = false) {
internalValue.value = object
// We assume we're getting an array when multiple is enabled and can therefore leave the query
@ -395,7 +370,6 @@ function setSelectedObject(object: string | { [id: string]: any } | null, resetO
}
const results = ref<(Element | ComponentPublicInstance)[]>([])
function setResult(el: Element | ComponentPublicInstance | null, index: number) {
if (el === null) {
delete results.value[index]
@ -441,9 +415,8 @@ function createOrSelectOnEnter() {
if (!creatableAvailable.value) {
// Check if there's an exact match for our search term
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const exactMatch = filteredSearchResults.value.find((elem: any) => elementInResults(elem, props.label, query.value))
if (exactMatch) {
if(exactMatch) {
select(exactMatch)
}
@ -453,7 +426,6 @@ function createOrSelectOnEnter() {
create()
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
function remove(item: any) {
for (const ind in internalValue.value) {
if (internalValue.value[ind] === item) {
@ -600,14 +572,4 @@ function focus() {
transition: color $transition;
padding-left: .5rem;
}
.has-removal-button {
position: relative;
}
.removal-button {
position: absolute;
right: .5rem;
color: var(--danger);
}
</style>

View File

@ -0,0 +1,522 @@
<template>
<div class="vue-easymde" ref="easymdeRef">
<textarea
class="vue-simplemde-textarea"
:name="name"
:value="modelValue"
@input="handleInput(($event.target as HTMLTextAreaElement).value)"
/>
</div>
</template>
<script setup lang="ts">
import {ref, watch, onMounted, onDeactivated, onBeforeUnmount, nextTick, shallowReactive, type ShallowReactive, type PropType} from 'vue'
import EasyMDE, {toggleFullScreen} from 'easymde'
import {marked} from 'marked'
import type CodeMirror from 'codemirror'
const props = defineProps({
modelValue: {
type: String,
default: '',
},
name: {
type: String,
},
previewClass: {
type: String,
},
autoinit: {
type: Boolean,
default: true,
},
highlight: {
type: Boolean,
default: false,
},
sanitize: {
type: Boolean,
default: false,
},
configs: {
type: Object,
default: () => ({}),
},
previewRender: {
type: Function as PropType<EasyMDE.Options['previewRender']>,
},
})
const emit = defineEmits(['update:modelValue', 'blur', 'initialized'])
const isValueUpdateFromInner = ref(false)
let easymde: ShallowReactive<EasyMDE> | undefined
onMounted(() => {
if (props.autoinit) initialize()
})
onDeactivated(() => {
if (easymde === undefined) return
if (easymde.isFullscreenActive()) toggleFullScreen(easymde)
easymde.toTextArea
})
onBeforeUnmount(() => {
if (easymde) {
easymde.toTextArea()
easymde.cleanup()
easymde = undefined
}
})
const easymdeRef = ref<HTMLElement | null>(null)
function initialize() {
const configs: EasyMDE.Options = Object.assign({
element: easymdeRef.value?.firstElementChild as HTMLElement,
initialValue: props.modelValue,
previewRender: props.previewRender,
renderingConfig: {},
}, props.configs)
// Synchronize the values of value and initialValue
if (configs.initialValue) {
emit('update:modelValue', configs.initialValue)
}
// Determine whether to enable code highlighting
if (props.highlight) {
configs.renderingConfig!.codeSyntaxHighlighting = true
}
// Set whether to render the input html
marked.setOptions({ sanitize: props.sanitize })
// Instantiated editor
easymde = shallowReactive(new EasyMDE(configs))
// Add a custom previewClass
const className = props.previewClass || ''
addPreviewClass(easymde, className)
// Binding event
easymde.codemirror.on('change', handleCodemirrorInput)
easymde.codemirror.on('blur', handleCodemirrorBlur)
nextTick(() => emit('initialized', easymde))
}
function addPreviewClass(easymde: EasyMDE, className: string) {
const wrapper = easymde.codemirror.getWrapperElement()
const preview = document.createElement('div')
wrapper.nextSibling.className += ` ${className}`
preview.className = `editor-preview ${className}`
wrapper.appendChild(preview)
}
function handleInput(val: string) {
isValueUpdateFromInner.value = true
emit('update:modelValue', val)
}
function handleCodemirrorInput(instance: CodeMirror.Editor, changeObj: CodeMirror.EditorChange) {
if (changeObj.origin === 'setValue' || easymde === undefined) {
return
}
handleInput(easymde.value())
}
function handleCodemirrorBlur() {
if (easymde === undefined) {
return
}
isValueUpdateFromInner.value = true
emit('blur', easymde.value())
}
watch(
() => props.modelValue,
(val) => {
if (isValueUpdateFromInner.value) {
isValueUpdateFromInner.value = false
} else {
easymde?.value(val)
}
},
)
</script>
<style lang="scss">
.EasyMDEContainer {
display: block;
}
.EasyMDEContainer.sided--no-fullscreen {
display: flex;
flex-direction: row;
flex-wrap: wrap;
}
.EasyMDEContainer .CodeMirror {
box-sizing: border-box;
height: auto;
border: 1px solid #ddd;
border-bottom-left-radius: 4px;
border-bottom-right-radius: 4px;
padding: 10px;
font: inherit;
z-index: 0;
word-wrap: break-word;
}
.EasyMDEContainer .CodeMirror-scroll {
cursor: text;
}
.EasyMDEContainer .CodeMirror-fullscreen {
background: #fff;
position: fixed !important;
top: 50px;
left: 0;
right: 0;
bottom: 0;
height: auto;
z-index: 8;
border-right: none !important;
border-bottom-right-radius: 0 !important;
}
.EasyMDEContainer .CodeMirror-sided {
width: 50% !important;
}
.EasyMDEContainer.sided--no-fullscreen .CodeMirror-sided {
border-right: none!important;
border-bottom-right-radius: 0px;
position: relative;
flex: 1 1 auto;
}
.EasyMDEContainer .CodeMirror-placeholder {
opacity: .5;
}
.EasyMDEContainer .CodeMirror-focused .CodeMirror-selected {
background: #d9d9d9;
}
.editor-toolbar {
position: relative;
user-select: none;
padding: 9px 10px;
border-top: 1px solid #bbb;
border-left: 1px solid #bbb;
border-right: 1px solid #bbb;
border-top-left-radius: 4px;
border-top-right-radius: 4px;
}
.editor-toolbar.fullscreen {
width: 100%;
height: 50px;
padding-top: 10px;
padding-bottom: 10px;
box-sizing: border-box;
background: #fff;
border: 0;
position: fixed;
top: 0;
left: 0;
opacity: 1;
z-index: 9;
}
.editor-toolbar.fullscreen::before {
width: 20px;
height: 50px;
background: linear-gradient(to right, rgba(255, 255, 255, 1) 0%, rgba(255, 255, 255, 0) 100%);
position: fixed;
top: 0;
left: 0;
margin: 0;
padding: 0;
}
.editor-toolbar.fullscreen::after {
width: 20px;
height: 50px;
background: linear-gradient(to right, rgba(255, 255, 255, 0) 0%, rgba(255, 255, 255, 1) 100%);
position: fixed;
top: 0;
right: 0;
margin: 0;
padding: 0;
}
.EasyMDEContainer.sided--no-fullscreen .editor-toolbar {
width: 100%;
}
.editor-toolbar button, .editor-toolbar .easymde-dropdown {
background: transparent;
display: inline-block;
text-align: center;
text-decoration: none !important;
height: 30px;
margin: 0;
padding: 0;
border: 1px solid transparent;
border-radius: 3px;
cursor: pointer;
}
.editor-toolbar button {
width: 30px;
}
.editor-toolbar button.active,
.editor-toolbar button:hover {
background: #fcfcfc;
border-color: #95a5a6;
}
.editor-toolbar i.separator {
display: inline-block;
width: 0;
border-left: 1px solid #d9d9d9;
border-right: 1px solid #fff;
color: transparent;
text-indent: -10px;
margin: 0 6px;
}
.editor-toolbar button:after {
font-family: Arial, "Helvetica Neue", Helvetica, sans-serif;
font-size: 65%;
vertical-align: text-bottom;
position: relative;
top: 2px;
}
.editor-toolbar button.heading-1:after {
content: "1";
}
.editor-toolbar button.heading-2:after {
content: "2";
}
.editor-toolbar button.heading-3:after {
content: "3";
}
.editor-toolbar button.heading-bigger:after {
content: "▲";
}
.editor-toolbar button.heading-smaller:after {
content: "▼";
}
.editor-toolbar.disabled-for-preview button:not(.no-disable) {
opacity: .6;
pointer-events: none;
}
@media only screen and (max-width: 700px) {
.editor-toolbar i.no-mobile {
display: none;
}
}
.editor-statusbar {
padding: 8px 10px;
font-size: 12px;
color: #959694;
text-align: right;
}
.EasyMDEContainer.sided--no-fullscreen .editor-statusbar {
width: 100%;
}
.editor-statusbar span {
display: inline-block;
min-width: 4em;
margin-left: 1em;
}
.editor-statusbar .lines:before {
content: 'lines: '
}
.editor-statusbar .words:before {
content: 'words: '
}
.editor-statusbar .characters:before {
content: 'characters: '
}
.editor-preview-full {
position: absolute;
width: 100%;
height: 100%;
top: 0;
left: 0;
z-index: 7;
overflow: auto;
display: none;
box-sizing: border-box;
}
.editor-preview-side {
position: fixed;
bottom: 0;
width: 50%;
top: 50px;
right: 0;
z-index: 9;
overflow: auto;
display: none;
box-sizing: border-box;
border: 1px solid #ddd;
word-wrap: break-word;
}
.editor-preview-active-side {
display: block
}
.EasyMDEContainer.sided--no-fullscreen .editor-preview-active-side {
flex: 1 1 auto;
height: auto;
position: static;
}
.editor-preview-active {
display: block
}
.editor-preview {
padding: 10px;
background: #fafafa;
}
.editor-preview > p {
margin-top: 0
}
.editor-preview pre {
background: #eee;
margin-bottom: 10px;
}
.editor-preview table td,
.editor-preview table th {
border: 1px solid #ddd;
padding: 5px;
}
.cm-s-easymde .cm-tag {
color: #63a35c;
}
.cm-s-easymde .cm-attribute {
color: #795da3;
}
.cm-s-easymde .cm-string {
color: #183691;
}
.cm-s-easymde .cm-header-1 {
font-size: 200%;
line-height: 200%;
}
.cm-s-easymde .cm-header-2 {
font-size: 160%;
line-height: 160%;
}
.cm-s-easymde .cm-header-3 {
font-size: 125%;
line-height: 125%;
}
.cm-s-easymde .cm-header-4 {
font-size: 110%;
line-height: 110%;
}
.cm-s-easymde .cm-comment {
background: rgba(0, 0, 0, .05);
border-radius: 2px;
}
.cm-s-easymde .cm-link {
color: #7f8c8d;
}
.cm-s-easymde .cm-url {
color: #aab2b3;
}
.cm-s-easymde .cm-quote {
color: #7f8c8d;
font-style: italic;
}
.editor-toolbar .easymde-dropdown {
position: relative;
background: linear-gradient(to bottom right, #fff 0%, #fff 84%, #333 50%, #333 100%);
border-radius: 0;
border: 1px solid #fff;
}
.editor-toolbar .easymde-dropdown:hover {
background: linear-gradient(to bottom right, #fff 0%, #fff 84%, #333 50%, #333 100%);
}
.easymde-dropdown-content {
display: block;
visibility: hidden;
position: absolute;
background-color: #f9f9f9;
box-shadow: 0 8px 16px 0 rgba(0, 0, 0, 0.2);
padding: 8px;
z-index: 2;
top: 30px;
}
.easymde-dropdown:active .easymde-dropdown-content,
.easymde-dropdown:focus .easymde-dropdown-content {
visibility: visible;
}
span[data-img-src]::after{
content: '';
background-image: var(--bg-image);
display: block;
max-height: 100%;
max-width: 100%;
background-size: contain;
height: 0;
padding-top: var(--height);
width: var(--width);
background-repeat: no-repeat;
}
</style>
<style lang="scss" scoped>
.vue-easymde .markdown-body {
padding: 0.5em
}
.vue-easymde .editor-preview-active,
.vue-easymde .editor-preview-active-side {
display: block;
}
</style>

View File

@ -1,7 +1,6 @@
<template>
<transition :name="name">
<!-- eslint-disable-next-line -->
<slot/>
<slot />
</transition>
</template>

View File

@ -6,13 +6,8 @@ import {
faArchive,
faArrowLeft,
faArrowUpFromBracket,
faBold,
faItalic,
faStrikethrough,
faCode,
faBars,
faBell,
faBolt,
faCalendar,
faCheck,
faCheckDouble,
@ -33,7 +28,6 @@ import {
faFilter,
faForward,
faGripLines,
faHeader,
faHistory,
faImage,
faKeyboard,
@ -64,26 +58,14 @@ import {
faTimes,
faTrashAlt,
faUser,
faUsers,
faQuoteRight,
faListUl,
faLink,
faUndo,
faRedo,
faUnlink,
faParagraph,
faTable,
faX, faArrowTurnDown, faListCheck, faXmark, faXmarksLines, faFont, faRulerHorizontal, faUnderline,
faUsers, faX,
} from '@fortawesome/free-solid-svg-icons'
import {
faBellSlash,
faCalendarAlt,
faCheckSquare,
faClock,
faComments,
faFileImage,
faSave,
faSquareCheck,
faStar,
faSun,
faTimesCircle,
@ -93,21 +75,6 @@ import {FontAwesomeIcon} from '@fortawesome/vue-fontawesome'
import type {FontAwesomeIcon as FontAwesomeIconFixedTypes} from '@/types/vue-fontawesome'
library.add(faBold)
library.add(faUndo)
library.add(faRedo)
library.add(faItalic)
library.add(faLink)
library.add(faUnlink)
library.add(faParagraph)
library.add(faSquareCheck)
library.add(faTable)
library.add(faFileImage)
library.add(faCheckSquare)
library.add(faStrikethrough)
library.add(faCode)
library.add(faQuoteRight)
library.add(faListUl)
library.add(faAlignLeft)
library.add(faAngleRight)
library.add(faArchive)
@ -139,7 +106,6 @@ library.add(faFillDrip)
library.add(faFilter)
library.add(faForward)
library.add(faGripLines)
library.add(faHeader)
library.add(faHistory)
library.add(faImage)
library.add(faKeyboard)
@ -178,14 +144,6 @@ library.add(faUsers)
library.add(faArrowUpFromBracket)
library.add(faX)
library.add(faAnglesUp)
library.add(faBolt)
library.add(faArrowTurnDown)
library.add(faListCheck)
library.add(faXmark)
library.add(faXmarksLines)
library.add(faFont)
library.add(faRulerHorizontal)
library.add(faUnderline)
// overwriting the wrong types
export default FontAwesomeIcon as unknown as FontAwesomeIconFixedTypes

View File

@ -1,40 +0,0 @@
<script setup lang="ts">
import BaseButton from '@/components/base/BaseButton.vue'
import {useBaseStore} from '@/stores/base'
import {onBeforeUnmount, onMounted} from 'vue'
import {eventToHotkeyString} from '@github/hotkey'
const baseStore = useBaseStore()
// See https://github.com/github/hotkey/discussions/85#discussioncomment-5214660
function openQuickActionsViaHotkey(event) {
const hotkeyString = eventToHotkeyString(event)
if (!hotkeyString) return
if (hotkeyString !== 'Control+k' && hotkeyString !== 'Meta+k') return
event.preventDefault()
openQuickActions()
}
onMounted(() => {
document.addEventListener('keydown', openQuickActionsViaHotkey)
})
onBeforeUnmount(() => {
document.removeEventListener('keydown', openQuickActionsViaHotkey)
})
function openQuickActions() {
baseStore.setQuickActionsActive(true)
}
</script>
<template>
<BaseButton
@click="openQuickActions"
class="trigger-button"
:title="$t('keyboardShortcuts.quickSearch')"
>
<icon icon="search"/>
</BaseButton>
</template>

View File

@ -152,10 +152,6 @@ export const KEYBOARD_SHORTCUTS : ShortcutGroup[] = [
title: 'keyboardShortcuts.task.favorite',
keys: ['s'],
},
{
title: 'keyboardShortcuts.task.save',
keys: [ctrl, 's'],
},
],
},
]

View File

@ -14,7 +14,7 @@
>
<div
class="modal-container"
@mousedown.self.prevent.stop="$emit('close')"
@click.self.prevent.stop="$emit('close')"
v-shortcut="'Escape'"
>
<div
@ -195,9 +195,10 @@ $modal-width: 1024px;
}
.close {
$close-button-min-space: 84px;
$close-button-padding: 26px;
position: fixed;
top: .5rem;
top: 5px;
right: $close-button-padding;
color: var(--grey-900);
font-size: 2rem;
@ -212,10 +213,6 @@ $modal-width: 1024px;
@media screen and (min-width: calc(#{$desktop } + #{$close-button-min-space})) {
color: var(--white);
}
@media screen and (min-width: $tablet) and (max-width: #{$desktop + $close-button-min-space}) {
top: .75rem;
}
}
</style>

View File

@ -36,14 +36,6 @@
</span>
</div>
</div>
<x-button
v-if="notifications.length > 0 && unreadNotifications > 0"
@click="markAllRead"
variant="tertiary"
class="mt-2 is-fullwidth"
>
{{ $t('notification.markAllRead') }}
</x-button>
<p class="nothing" v-if="notifications.length === 0">
{{ $t('notification.none') }}<br/>
<span class="explainer">
@ -68,15 +60,11 @@ import {closeWhenClickedOutside} from '@/helpers/closeWhenClickedOutside'
import {formatDateLong, formatDateSince} from '@/helpers/time/formatDate'
import {getDisplayName} from '@/models/user'
import {useAuthStore} from '@/stores/auth'
import XButton from '@/components/input/button.vue'
import {success} from '@/message'
import {useI18n} from 'vue-i18n'
const LOAD_NOTIFICATIONS_INTERVAL = 10000
const authStore = useAuthStore()
const router = useRouter()
const {t} = useI18n()
const allNotifications = ref<INotification[]>([])
const showNotifications = ref(false)
@ -150,12 +138,6 @@ function to(n, index) {
allNotifications.value[index] = await notificationService.update(n)
}
}
async function markAllRead() {
const notificationService = new NotificationService()
await notificationService.markAllRead()
success({message: t('notification.markAllReadSuccess')})
}
</script>
<style lang="scss" scoped>

View File

@ -164,7 +164,6 @@
v-model="entities.projects"
@select="changeMultiselectFilter('projects', 'project_id')"
@remove="changeMultiselectFilter('projects', 'project_id')"
:project-filter="p => p.id > 0"
/>
</div>
</div>
@ -177,9 +176,8 @@ export const ALPHABETICAL_SORT = 'title'
</script>
<script setup lang="ts">
import {computed, nextTick, onMounted, reactive, ref, shallowReactive, toRefs} from 'vue'
import {computed, nextTick, onMounted, reactive, ref, shallowReactive, toRefs, watch} from 'vue'
import {camelCase} from 'camel-case'
import {watchDebounced} from '@vueuse/core'
import type {ILabel} from '@/modelTypes/ILabel'
import type {IUser} from '@/modelTypes/IUser'
@ -275,16 +273,15 @@ onMounted(() => {
filters.value.requireAllFilters = params.value.filter_concat === 'and'
})
// Using watchDebounced to prevent the filter re-triggering itself.
// FIXME: Only here until this whole component changes a lot with the new filter syntax.
watchDebounced(
watch(
modelValue,
(value) => {
// FIXME: filters should only be converted to snake case in the last moment
// FIXME: filters should only be converted to snake case in
// the last moment
params.value = objectToSnakeCase(value)
prepareFilters()
},
{immediate: true, debounce: 500, maxWait: 1000},
{immediate: true},
)
const sortAlphabetically = computed({
@ -313,7 +310,7 @@ function prepareFilters() {
prepareDate('end_date', 'endDate')
prepareSingleValue('priority', 'priority', 'usePriority', true)
prepareSingleValue('percent_done', 'percentDone', 'usePercentDone', true)
prepareDate('reminders', 'reminders')
prepareDate('reminders')
prepareRelatedObjectFilter('users', 'assignees')
prepareProjectsFilter()
@ -389,13 +386,13 @@ function setDateFilter(filterName, {dateFrom, dateTo}) {
change()
}
function prepareDate(filterName: string, variableName: 'dueDate' | 'startDate' | 'endDate' | 'reminders') {
function prepareDate(filterName, variableName) {
if (typeof params.value.filter_by === 'undefined') {
return
}
let foundDateStart: boolean | string = false
let foundDateEnd: boolean | string = false
let foundDateStart = false
let foundDateEnd = false
for (const i in params.value.filter_by) {
if (params.value.filter_by[i] === filterName && params.value.filter_comparator[i] === 'greater_equals') {
foundDateStart = i
@ -414,10 +411,10 @@ function prepareDate(filterName: string, variableName: 'dueDate' | 'startDate' |
const endDate = new Date(params.value.filter_value[foundDateEnd])
filters.value[variableName] = {
dateFrom: !isNaN(startDate)
? `${startDate.getUTCFullYear()}-${startDate.getUTCMonth() + 1}-${startDate.getUTCDate()}`
? `${startDate.getFullYear()}-${startDate.getMonth() + 1}-${startDate.getDate()}`
: params.value.filter_value[foundDateStart],
dateTo: !isNaN(endDate)
? `${endDate.getUTCFullYear()}-${endDate.getUTCMonth() + 1}-${endDate.getUTCDate()}`
? `${endDate.getFullYear()}-${endDate.getMonth() + 1}-${endDate.getDate()}`
: params.value.filter_value[foundDateEnd],
}
}

View File

@ -72,12 +72,6 @@
@update:model-value="setSubscriptionInStore"
type="dropdown"
/>
<dropdown-item
:to="{ name: 'project.settings.webhooks', params: { projectId: project.id } }"
icon="bolt"
>
{{ $t('project.webhooks.title') }}
</dropdown-item>
<dropdown-item
v-if="level < 2"
:to="{ name: 'project.createFromParent', params: { parentProjectId: project.id } }"

View File

@ -93,7 +93,6 @@ import {success} from '@/message'
import type {ITeam} from '@/modelTypes/ITeam'
import type {ITask} from '@/modelTypes/ITask'
import type {IProject} from '@/modelTypes/IProject'
import type {IAbstract} from '@/modelTypes/IAbstract'
const {t} = useI18n({useScope: 'global'})
const router = useRouter()
@ -104,7 +103,7 @@ const labelStore = useLabelStore()
const taskStore = useTaskStore()
const authStore = useAuthStore()
type DoAction<Type> = { type: ACTION_TYPE } & Type
type DoAction<Type = any> = { type: ACTION_TYPE } & Type
enum ACTION_TYPE {
CMD = 'cmd',
@ -191,7 +190,7 @@ const foundCommands = computed(() => availableCmds.value.filter((a) =>
interface Result {
type: ACTION_TYPE
title: string
items: DoAction<IAbstract>
items: DoAction<any>
}
const results = computed<Result[]>(() => {

View File

@ -3,7 +3,7 @@
v-if="props.isLoading && !ganttBars.length || dayjsLanguageLoading"
class="gantt-container"
/>
<div ref="ganttContainer" class="gantt-container" v-else>
<div class="gantt-container" v-else>
<GGanttChart
:date-format="DAYJS_ISO_DATE_FORMAT"
:chart-start="isoToKebabDate(filters.dateFrom)"
@ -14,7 +14,7 @@
:grid="true"
@dragend-bar="updateGanttTask"
@dblclick-bar="openTask"
:width="ganttChartWidth"
:width="ganttChartWidth + 'px'"
>
<template #timeunit="{value, date}">
<div
@ -85,8 +85,6 @@ const dayjsLanguageLoading = ref(false)
// const dayjsLanguageLoading = useDayjsLanguageSync(dayjs)
extendDayjs()
const ganttContainer = ref(null)
const router = useRouter()
const dateFromDate = computed(() => new Date(new Date(filters.value.dateFrom).setHours(0,0,0,0)))
@ -94,15 +92,9 @@ const dateToDate = computed(() => new Date(new Date(filters.value.dateTo).setHou
const DAY_WIDTH_PIXELS = 30
const ganttChartWidth = computed(() => {
const ganttContainerReference = ganttContainer?.value
const ganttContainerWidth = ganttContainerReference ? (ganttContainerReference['clientWidth'] ?? 0) : 0
const dateDiff = Math.floor((dateToDate.value.valueOf() - dateFromDate.value.valueOf()) / MILLISECONDS_A_DAY)
const calculatedWidth = dateDiff * DAY_WIDTH_PIXELS
return (calculatedWidth > ganttContainerWidth) ? calculatedWidth + 'px' : '100%'
return dateDiff * DAY_WIDTH_PIXELS
})
const ganttBars = ref<GanttBarObject[][]>([])

View File

@ -178,7 +178,7 @@ async function addTask() {
return rel
})
await Promise.all(relations)
} catch (e) {
} catch (e: any) {
newTaskTitle.value = taskTitleBackup
if (e?.message === 'NO_PROJECT') {
errorMessage.value = t('project.create.addProjectRequired')

View File

@ -4,6 +4,8 @@ import BaseButton from '@/components/base/BaseButton.vue'
import User from '@/components/misc/user.vue'
import {computed} from 'vue'
type removeFunction = (item: any) => void
const {
assignees,
remove,
@ -12,7 +14,7 @@ const {
inline = false,
} = defineProps<{
assignees: IUser[],
remove?: (user: IUser) => void,
remove?: removeFunction,
disabled?: boolean,
avatarSize?: number,
inline?: boolean,

View File

@ -37,8 +37,8 @@
>
<div class="filename">
{{ a.file.name }}
<span
v-if="task.coverImageAttachmentId === a.id"
<span
v-if="task.coverImageAttachmentId === a.id"
class="is-task-cover"
>
{{ $t('task.attachment.usedAsCover') }}
@ -115,20 +115,18 @@
</x-button>
<!-- Dropzone -->
<Teleport to="body">
<div
:class="{ hidden: !isOverDropZone }"
class="dropzone"
v-if="editEnabled"
>
<div class="drop-hint">
<div class="icon">
<icon icon="cloud-upload-alt"/>
</div>
<div class="hint">{{ $t('task.attachment.drop') }}</div>
<div
:class="{ hidden: !isOverDropZone }"
class="dropzone"
v-if="editEnabled"
>
<div class="drop-hint">
<div class="icon">
<icon icon="cloud-upload-alt"/>
</div>
<div class="hint">{{ $t('task.attachment.drop') }}</div>
</div>
</Teleport>
</div>
<!-- Delete modal -->
<modal
@ -325,7 +323,7 @@ async function setCoverImage(attachment: IAttachment | null) {
.dropzone {
position: fixed;
background: hsla(var(--grey-100-hsl), 0.8);
background: rgba(250, 250, 250, 0.8);
top: 0;
left: 0;
bottom: 0;
@ -358,11 +356,11 @@ async function setCoverImage(attachment: IAttachment | null) {
.hint {
margin: .5rem auto 2rem;
border-radius: $radius;
border-radius: 2px;
box-shadow: var(--shadow-md);
background: var(--primary);
padding: 1rem;
color: $white; // Should always be white because of the background, regardless of the theme
color: var(--white);
width: 100%;
max-width: 300px;
}

View File

@ -66,6 +66,7 @@
</CustomTransition>
</div>
<editor
:hasPreview="true"
:is-edit-enabled="canWrite && c.author.id === currentUserId"
:upload-callback="attachmentUpload"
:upload-enabled="true"
@ -82,7 +83,6 @@
}"
:bottom-actions="actions[c.id]"
:show-save="true"
initial-mode="preview"
/>
</div>
</div>
@ -114,12 +114,12 @@
taskCommentService.loading &&
!isCommentEdit,
}"
:hasPreview="false"
:upload-callback="attachmentUpload"
:upload-enabled="true"
:placeholder="$t('task.comment.placeholder')"
v-if="editorActive"
v-model="newComment.comment"
@save="addComment()"
/>
</div>
<div class="field">
@ -218,19 +218,13 @@ const actions = computed(() => {
])))
})
async function attachmentUpload(files: File[] | FileList): (Promise<string[]>) {
const uploadPromises: Promise<string>[] = []
files.forEach((file: File) => {
const promise = new Promise<string>((resolve) => {
uploadFile(props.taskId, file, (uploadedFileUrl: string) => resolve(uploadedFileUrl))
})
uploadPromises.push(promise)
})
return await Promise.all(uploadPromises)
function attachmentUpload(
file: File,
onSuccess: (url: string) => void,
// eslint-disable-next-line @typescript-eslint/no-unused-vars
onError: (error: string) => void,
) {
return uploadFile(props.taskId, file, onSuccess)
}
const taskCommentService = shallowReactive(new TaskCommentService())
@ -305,7 +299,7 @@ async function editComment() {
if (commentEdit.comment === '') {
return
}
if (changeTimeout.value !== null) {
clearTimeout(changeTimeout.value)
}
@ -374,7 +368,7 @@ async function deleteComment(commentToDelete: ITaskComment) {
}
.image.is-avatar {
border-radius: 100%;
border-radius: 100%;
}
.media-content {

View File

@ -17,45 +17,47 @@
</CustomTransition>
</h3>
<editor
class="tiptap__task-description"
:is-edit-enabled="canWrite"
:upload-callback="uploadCallback"
:upload-callback="attachmentUpload"
:upload-enabled="true"
:placeholder="$t('task.description.placeholder')"
:empty-text="$t('task.description.empty')"
:show-save="true"
edit-shortcut="e"
v-model="description"
v-model="task.description"
@update:model-value="saveWithDelay"
@save="save"
:initial-mode="isEditorContentEmpty(description) ? 'edit' : 'preview'"
/>
</div>
</template>
<script setup lang="ts">
import {ref, computed, watch} from 'vue'
import {ref, computed, watch, type PropType} from 'vue'
import CustomTransition from '@/components/misc/CustomTransition.vue'
import Editor from '@/components/input/AsyncEditor'
import type {ITask} from '@/modelTypes/ITask'
import {useTaskStore} from '@/stores/tasks'
import {isEditorContentEmpty} from '@/helpers/editorContentEmpty'
import TaskModel from '@/models/task'
type AttachmentUploadFunction = (file: File, onSuccess: (attachmentUrl: string) => void) => Promise<string>
const {
modelValue,
attachmentUpload,
canWrite,
} = defineProps<{
modelValue: ITask,
attachmentUpload: AttachmentUploadFunction,
canWrite: boolean,
}>()
const props = defineProps({
modelValue: {
type: Object as PropType<ITask>,
required: true,
},
attachmentUpload: {
required: true,
},
canWrite: {
type: Boolean,
required: true,
},
})
const emit = defineEmits(['update:modelValue'])
const description = ref<string>('')
const task = ref<ITask>(new TaskModel())
const saved = ref(false)
// Since loading is global state, this variable ensures we're only showing the saving icon when saving the description.
@ -65,9 +67,9 @@ const taskStore = useTaskStore()
const loading = computed(() => taskStore.isLoading)
watch(
() => modelValue.description,
value => {
description.value = value
props.modelValue,
(value) => {
task.value = value
},
{immediate: true},
)
@ -93,11 +95,8 @@ async function save() {
try {
// FIXME: don't update state from internal.
const updated = await taskStore.update({
...modelValue,
description: description.value,
})
emit('update:modelValue', updated)
task.value = await taskStore.update(task.value)
emit('update:modelValue', task.value)
saved.value = true
setTimeout(() => {
@ -107,27 +106,5 @@ async function save() {
saving.value = false
}
}
async function uploadCallback(files: File[] | FileList): (Promise<string[]>) {
const uploadPromises: Promise<string>[] = []
files.forEach((file: File) => {
const promise = new Promise<string>((resolve) => {
attachmentUpload(file, (uploadedFileUrl: string) => resolve(uploadedFileUrl))
})
uploadPromises.push(promise)
})
return await Promise.all(uploadPromises)
}
</script>
<style lang="scss" scoped>
.tiptap__task-description {
// The exact amount of pixels we need to make the description icon align with the buttons and the form inside the editor.
// The icon is not exactly the same length on all sides so we need to hack our way around it.
margin-left: 4px;
}
</style>

View File

@ -113,7 +113,7 @@ async function save(title: string) {
<style lang="scss" scoped>
.heading {
display: flex;
justify-content: flex-start;
justify-content: space-between;
text-transform: none;
align-items: center;
@ -134,10 +134,6 @@ async function save(title: string) {
@media screen and (max-width: $tablet) {
margin: 0 -.3rem .5rem -.3rem; // the title has 0.3rem padding - this make the text inside of it align with the rest
}
@media screen and (min-width: $tablet) and (max-width: #{$desktop + $close-button-min-space}) {
width: calc(100% - 6.5rem);
}
}
.title.task-id {

View File

@ -14,7 +14,7 @@
<template v-if="priority === priorities.URGENT">{{ $t('task.priority.urgent') }}</template>
<template v-if="priority === priorities.DO_NOW">{{ $t('task.priority.doNow') }}</template>
</span>
<span class="icon pr-0" v-if="priority === priorities.DO_NOW">
<span class="icon" v-if="priority === priorities.DO_NOW">
<icon icon="exclamation"/>
</span>
</span>

View File

@ -70,11 +70,11 @@ function findProjects(query: string) {
foundProjects.value = projectStore.searchProject(query)
}
function select(p: IProject | null) {
if (p === null) {
Object.assign(project, {id: 0})
function select(l: IProject | null) {
if (l === null) {
return
}
Object.assign(project, p)
Object.assign(project, l)
emit('update:modelValue', project)
}
</script>

View File

@ -3,10 +3,7 @@
<div
:class="{'is-loading': taskService.loading}"
class="task loader-container"
@mouseup.stop.self="openTaskDetail"
@mousedown.stop.self="focusTaskLink"
ref="taskContainerRef"
tabindex="-1"
@click.stop.self="openTaskDetail"
>
<fancycheckbox
:disabled="(isArchived || disabled) && !canMarkAsDone"
@ -15,7 +12,7 @@
/>
<ColorBubble
v-if="!showProjectSeparately && projectColor !== '' && currentProject?.id !== task.projectId"
v-if="showProjectColor && projectColor !== '' && currentProject?.id !== task.projectId"
:color="projectColor"
class="mr-1"
/>
@ -23,14 +20,12 @@
<div
:class="{ 'done': task.done, 'show-project': showProject && project}"
class="tasktext"
@mouseup.stop.self="openTaskDetail"
@mousedown.stop.self="focusTaskLink"
>
<span>
<router-link
v-if="showProject && typeof project !== 'undefined'"
:to="{ name: 'project.list', params: { projectId: task.projectId } }"
class="task-project mr-1"
class="task-project"
:class="{'mr-2': task.hexColor !== ''}"
v-tooltip="$t('task.detail.belongsToProject', {project: project.title})"
>
@ -43,7 +38,7 @@
class="mr-1"
/>
<priority-label :priority="task.priority" :done="task.done" class="pr-2"/>
<priority-label :priority="task.priority" :done="task.done"/>
<router-link
:to="taskDetailRoute"
@ -112,14 +107,8 @@
{{ task.percentDone * 100 }}%
</progress>
<ColorBubble
v-if="showProjectSeparately && projectColor !== '' && currentProject?.id !== task.projectId"
:color="projectColor"
class="mr-1"
/>
<router-link
v-if="showProjectSeparately"
v-if="!showProject && currentProject?.id !== task.projectId && project"
:to="{ name: 'project.list', params: { projectId: task.projectId } }"
class="task-project"
v-tooltip="$t('task.detail.belongsToProject', {project: project.title})"
@ -143,6 +132,7 @@
<single-task-in-project
:key="subtask.id"
:the-task="getTaskById(subtask.id)"
:show-project-color="showProjectColor"
:disabled="disabled"
:can-mark-as-done="canMarkAsDone"
:all-tasks="allTasks"
@ -190,6 +180,7 @@ const {
isArchived = false,
showProject = false,
disabled = false,
showProjectColor = false,
canMarkAsDone = true,
allTasks = [],
} = defineProps<{
@ -197,6 +188,7 @@ const {
isArchived?: boolean,
showProject?: boolean,
disabled?: boolean,
showProjectColor?: boolean,
canMarkAsDone?: boolean,
allTasks?: ITask[],
}>()
@ -240,8 +232,6 @@ const taskStore = useTaskStore()
const project = computed(() => projectStore.projects[task.value.projectId])
const projectColor = computed(() => project.value ? project.value?.hexColor : '')
const showProjectSeparately = computed(() => !showProject && currentProject.value?.id !== task.value.projectId && project.value)
const currentProject = computed(() => {
return typeof baseStore.currentProject === 'undefined' ? {
id: 0,
@ -318,24 +308,13 @@ function hideDeferDueDatePopup(e) {
}
const taskLink = ref<HTMLElement | null>(null)
const taskContainerRef = ref<HTMLElement | null>(null)
function hasTextSelected() {
const isTextSelected = window.getSelection().toString()
return !(typeof isTextSelected === 'undefined' || isTextSelected === '' || isTextSelected === '\n')
}
function openTaskDetail() {
if (!hasTextSelected()) {
const isTextSelected = window.getSelection().toString()
if (!isTextSelected) {
taskLink.value.$el.click()
}
}
function focusTaskLink() {
if (!hasTextSelected()) {
taskContainerRef.value.focus()
}
}
</script>
<style lang="scss" scoped>

View File

@ -2,7 +2,6 @@ import {computed, ref, watch, type Ref} from 'vue'
import {useRouter, type RouteLocationNormalized, type RouteLocationRaw, type RouteRecordName} from 'vue-router'
import equal from 'fast-deep-equal/es6'
// eslint-disable-next-line @typescript-eslint/no-explicit-any
export type Filters = Record<string, any>
export function useRouteFilters<CurrentFilters extends Filters>(

View File

@ -24,18 +24,13 @@ export function useRouteWithModal() {
// this is adapted from vue-router
// https://github.com/vuejs/vue-router-next/blob/798cab0d1e21f9b4d45a2bd12b840d2c7415f38a/src/RouterView.ts#L125
const routePropsOption = route.matched[0]?.props.default
let routeProps = undefined
if (routePropsOption) {
if (routePropsOption === true) {
routeProps = route.params
} else {
if(typeof routePropsOption === 'function') {
routeProps = routePropsOption(route)
} else {
routeProps = routePropsOption
}
}
}
const routeProps = routePropsOption
? routePropsOption === true
? route.params
: typeof routePropsOption === 'function'
? routePropsOption(route)
: routePropsOption
: {}
if (typeof routeProps === 'undefined') {
currentModal.value = undefined

View File

@ -1,11 +1,15 @@
import type {Directive} from 'vue'
import {install, uninstall} from '@github/hotkey'
import {isAppleDevice} from '@/helpers/isAppleDevice'
const directive = <Directive<HTMLElement,string>>{
mounted(el, {value}) {
if(value === '') {
return
}
if (isAppleDevice() && value.includes('Control')) {
value = value.replace('Control', 'Meta')
}
install(el, value)
},
beforeUnmount(el) {

View File

@ -4,7 +4,6 @@ import {snakeCase} from 'snake-case'
/**
* Transforms field names to camel case.
*/
// eslint-disable-next-line @typescript-eslint/no-explicit-any
export function objectToCamelCase(object: Record<string, any>) {
// When calling recursively, this can be called without being and object or array in which case we just return the value
@ -12,7 +11,6 @@ export function objectToCamelCase(object: Record<string, any>) {
return object
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const parsedObject: Record<string, any> = {}
for (const m in object) {
parsedObject[camelCase(m)] = object[m]
@ -25,7 +23,6 @@ export function objectToCamelCase(object: Record<string, any>) {
// Call it again for arrays
if (Array.isArray(object[m])) {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
parsedObject[camelCase(m)] = object[m].map((o: Record<string, any>) => objectToCamelCase(o))
// Because typeof [] === 'object' is true for arrays, we leave the loop here to prevent converting arrays to objects.
continue
@ -42,7 +39,6 @@ export function objectToCamelCase(object: Record<string, any>) {
/**
* Transforms field names to snake case - used before making an api request.
*/
// eslint-disable-next-line @typescript-eslint/no-explicit-any
export function objectToSnakeCase(object: Record<string, any>) {
// When calling recursively, this can be called without being and object or array in which case we just return the value
@ -50,7 +46,6 @@ export function objectToSnakeCase(object: Record<string, any>) {
return object
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const parsedObject: Record<string, any> = {}
for (const m in object) {
parsedObject[snakeCase(m)] = object[m]
@ -66,7 +61,6 @@ export function objectToSnakeCase(object: Record<string, any>) {
// Call it again for arrays
if (Array.isArray(object[m])) {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
parsedObject[snakeCase(m)] = object[m].map((o: Record<string, any>) => objectToSnakeCase(o))
// Because typeof [] === 'object' is true for arrays, we leave the loop here to prevent converting arrays to objects.
continue

View File

@ -10,56 +10,48 @@ describe('Find checklists in text', () => {
expect(checkboxes).toHaveLength(0)
})
it('should find multiple checkboxes', () => {
const text: string = `
<ul data-type="taskList">
<li data-checked="false" data-type="taskItem"><label><input type="checkbox"><span></span></label>
<div><p>Task</p></div>
</li>
<li data-checked="false" data-type="taskItem"><label><input type="checkbox"><span></span></label>
<div><p>Another task</p>
<ul data-type="taskList">
<li data-checked="false" data-type="taskItem"><label><input type="checkbox"><span></span></label>
<div><p>subtask</p></div>
</li>
<li data-checked="true" data-type="taskItem"><label><input type="checkbox"
checked="checked"><span></span></label>
<div><p>done</p></div>
</li>
</ul>
</div>
</li>
</ul>`
const text: string = `* [ ] Lorem Ipsum
* [ ] Dolor sit amet
Here's some text in between
* [x] Dolor sit amet
- [ ] Dolor sit amet`
const checkboxes = findCheckboxesInText(text)
expect(checkboxes).toHaveLength(4)
expect(checkboxes[0]).toBe(32)
expect(checkboxes[1]).toBe(163)
expect(checkboxes[2]).toBe(321)
expect(checkboxes[3]).toBe(464)
expect(checkboxes[0]).toBe(0)
expect(checkboxes[1]).toBe(18)
expect(checkboxes[2]).toBe(69)
expect(checkboxes[3]).toBe(90)
})
it('should find one unchecked checkbox', () => {
const text: string = `
<ul data-type="taskList">
<li data-checked="false" data-type="taskItem"><label><input type="checkbox"><span></span></label>
<div><p>Task</p></div>
</li>
</ul>`
it('should find one checkbox with *', () => {
const text: string = '* [ ] Lorem Ipsum'
const checkboxes = findCheckboxesInText(text)
expect(checkboxes).toHaveLength(1)
expect(checkboxes[0]).toBe(32)
expect(checkboxes[0]).toBe(0)
})
it('should find one checked checkbox', () => {
const text: string = `
<ul data-type="taskList">
<li data-checked="true" data-type="taskItem"><label><input type="checkbox"><span></span></label>
<div><p>Task</p></div>
</li>
</ul>`
it('should find one checkbox with -', () => {
const text: string = '- [ ] Lorem Ipsum'
const checkboxes = findCheckboxesInText(text)
expect(checkboxes).toHaveLength(1)
expect(checkboxes[0]).toBe(32)
expect(checkboxes[0]).toBe(0)
})
it('should find one checked checkbox with *', () => {
const text: string = '* [x] Lorem Ipsum'
const checkboxes = findCheckboxesInText(text)
expect(checkboxes).toHaveLength(1)
expect(checkboxes[0]).toBe(0)
})
it('should find one checked checkbox with -', () => {
const text: string = '- [x] Lorem Ipsum'
const checkboxes = findCheckboxesInText(text)
expect(checkboxes).toHaveLength(1)
expect(checkboxes[0]).toBe(0)
})
})
@ -71,60 +63,32 @@ describe('Get Checklist Statistics in a Text', () => {
expect(stats.total).toBe(0)
})
it('should find one checkbox', () => {
const text: string = `
<ul data-type="taskList">
<li data-checked="false" data-type="taskItem"><label><input type="checkbox"><span></span></label>
<div><p>Task</p></div>
</li>
</ul>`
const text: string = '* [ ] Lorem Ipsum'
const stats = getChecklistStatistics(text)
expect(stats.total).toBe(1)
expect(stats.checked).toBe(0)
})
it('should find one checked checkbox', () => {
const text: string = `
<ul data-type="taskList">
<li data-checked="true" data-type="taskItem"><label><input type="checkbox"><span></span></label>
<div><p>Task</p></div>
</li>
</ul>`
const text: string = '* [x] Lorem Ipsum'
const stats = getChecklistStatistics(text)
expect(stats.total).toBe(1)
expect(stats.checked).toBe(1)
})
it('should find multiple mixed and matched', () => {
const text: string = `
<ul data-type="taskList">
<li data-checked="false" data-type="taskItem"><label><input type="checkbox"><span></span></label>
<div><p>Task</p></div>
</li>
<li data-checked="false" data-type="taskItem"><label><input type="checkbox"><span></span></label>
<div><p>Another task</p>
<ul data-type="taskList">
<li data-checked="false" data-type="taskItem"><label><input type="checkbox"><span></span></label>
<div><p>subtask</p></div>
</li>
<li data-checked="false" data-type="taskItem"><label><input type="checkbox"><span></span></label>
<div><p>subtask 2</p></div>
</li>
<li data-checked="true" data-type="taskItem"><label><input type="checkbox"
checked="checked"><span></span></label>
<div><p>done</p></div>
</li>
<li data-checked="true" data-type="taskItem"><label><input type="checkbox"
checked="checked"><span></span></label>
<div><p>also done</p></div>
</li>
</ul>
</div>
</li>
</ul>`
const text: string = `* [ ] Lorem Ipsum
* [ ] Dolor sit amet
* [x] Dolor sit amet
- [x] Dolor sit amet
Here's some text in between
* [x] Dolor sit amet
- [ ] Dolor sit amet`
const stats = getChecklistStatistics(text)
expect(stats.total).toBe(6)
expect(stats.checked).toBe(2)
expect(stats.checked).toBe(3)
})
})

View File

@ -1,3 +1,5 @@
const checked = '[x]'
interface CheckboxStatistics {
total: number
checked: number
@ -9,7 +11,7 @@ interface MatchedCheckboxes {
}
const getCheckboxesInText = (text: string): MatchedCheckboxes => {
const regex = /data-checked="(true|false)"/g
const regex = /[*-] \[[ x]]/g
let match
const checkboxes: MatchedCheckboxes = {
checked: [],
@ -17,7 +19,7 @@ const getCheckboxesInText = (text: string): MatchedCheckboxes => {
}
while ((match = regex.exec(text)) !== null) {
if (match[1] === 'true') {
if (match[0].endsWith(checked)) {
checkboxes.checked.push(match.index)
} else {
checkboxes.unchecked.push(match.index)

View File

@ -1,3 +0,0 @@
export function isEditorContentEmpty(content: string): boolean {
return content === '' || content === '<p></p>'
}

View File

@ -1,11 +0,0 @@
export function isValidHttpUrl(urlToCheck: string): boolean {
let url
try {
url = new URL(urlToCheck)
} catch (_) {
return false
}
return url.protocol === 'http:' || url.protocol === 'https:'
}

View File

@ -0,0 +1,45 @@
import {marked} from 'marked'
import hljs from 'highlight.js/lib/common'
export function setupMarkdownRenderer(checkboxId: string) {
const renderer = new marked.Renderer()
const linkRenderer = renderer.link
let checkboxNum = -1
marked.use({
renderer: {
image(src: string, title: string, text: string) {
title = title ? ` title="${title}` : ''
// If the url starts with the api url, the image is likely an attachment and
// we'll need to download and parse it properly.
if (src.slice(0, window.API_URL.length + 7) === `${window.API_URL}/tasks/`) {
return `<img data-src="${src}" alt="${text}" ${title} class="attachment-image"/>`
}
return `<img src="${src}" alt="${text}" ${title}/>`
},
checkbox(checked: boolean) {
let checkedString = ''
if (checked) {
checkedString = 'checked'
}
checkboxNum++
return `<input type="checkbox" data-checkbox-num="${checkboxNum}" ${checkedString} class="text-checkbox-${checkboxId}"/>`
},
link(href: string, title: string, text: string) {
const isLocal = href.startsWith(`${location.protocol}//${location.hostname}`)
const html = linkRenderer.call(renderer, href, title, text)
return isLocal ? html : html.replace(/^<a /, '<a target="_blank" rel="noreferrer noopener nofollow" ')
},
},
highlight(code: string, language: string) {
const validLanguage = hljs.getLanguage(language) ? language : 'plaintext'
return hljs.highlight(code, {language: validLanguage}).value
},
})
return renderer
}

View File

@ -17,9 +17,7 @@ const spaceRegex = /^ */
* relation between each other.
*/
export function parseSubtasksViaIndention(taskTitles: string, prefixMode: PrefixMode): TaskWithParent[] {
let titles = taskTitles
.split(/[\r\n]+/)
.filter(t => t.replace(/\s/g, '').length > 0) // Remove titles which are empty or only contain spaces / tabs
let titles = taskTitles.split(/[\r\n]+/)
if (titles.length == 0) {
return []

View File

@ -1,12 +1,8 @@
export function parseDateOrString(rawValue: string | undefined | null, fallback: unknown): (unknown | string | Date) {
if (rawValue === null || typeof rawValue === 'undefined') {
export function parseDateOrString(rawValue: string | undefined, fallback: unknown) {
if (typeof rawValue === 'undefined') {
return fallback
}
if (rawValue.toLowerCase().includes('now') || rawValue.toLowerCase().includes('||')) {
return rawValue
}
const d = new Date(rawValue)
return !isNaN(+d)

View File

@ -6,11 +6,7 @@ export function findById<T extends {id: string | number}>(array : T[], id : stri
return array.find(({id: currentId}) => currentId === id)
}
interface ObjectWithId {
id: number
}
export function includesById(array: ObjectWithId[], id: string | number) {
export function includesById(array: any[], id: string | number) {
return array.some(({id: currentId}) => currentId === id)
}

View File

@ -19,8 +19,6 @@ export const SUPPORTED_LOCALES = {
'da-DK': 'Dansk',
'ja-JP': '日本語',
'hu-HU': 'Magyar',
'ar-SA': 'اَلْعَرَبِيَّةُ',
'sl-SI': 'Slovenščina',
} as const
export type SupportedLocale = keyof typeof SUPPORTED_LOCALES
@ -35,7 +33,6 @@ export const i18n = createI18n({
legacy: false,
messages: {
[DEFAULT_LANGUAGE]: langEN,
// eslint-disable-next-line @typescript-eslint/no-explicit-any
} as Record<SupportedLocale, any>,
})

File diff suppressed because it is too large Load Diff

View File

@ -6,7 +6,6 @@
"welcomeEvening": "Good Evening {username}!",
"lastViewed": "Last viewed",
"addToHomeScreen": "Add this app to your home screen for faster access and improved experience.",
"goToOverview": "Go to overview",
"project": {
"importText": "Import your projects and tasks from other services into Vikunja:",
"import": "Import your data into Vikunja"
@ -177,7 +176,6 @@
"title": "Delete your Vikunja Account",
"text1": "The deletion of your account is permanent and cannot be undone. We will delete all your projects, tasks and everything associated with it.",
"text2": "To proceed, please enter your password. You will receive an email with further instructions.",
"text3": "To proceed, please press the button below. You will receive an email with further instructions.",
"confirm": "Delete my account",
"requestSuccess": "The request was successful. You'll receive an email with further instructions.",
"passwordRequired": "Please enter your password.",
@ -185,7 +183,6 @@
"scheduled": "We will delete your Vikunja account at {date} ({dateSince}).",
"scheduledCancel": "To cancel the deletion of your account, click here.",
"scheduledCancelText": "To cancel the deletion of your account, please enter your password below:",
"scheduledCancelButton": "To cancel the deletion of your account, please press the button below:",
"scheduledCancelConfirm": "Cancel the deletion of my account",
"scheduledCancelSuccess": "We will not delete your account."
},
@ -259,7 +256,7 @@
"identifier": "Project Identifier",
"identifierPlaceholder": "The project identifier goes here…",
"description": "Description",
"descriptionPlaceholder": "Enter a description for this project, hit '/' for more options…",
"descriptionPlaceholder": "The projects description goes here…",
"color": "Color",
"success": "The project was successfully updated."
},
@ -360,21 +357,6 @@
"favorites": {
"title": "Favorites"
}
},
"webhooks": {
"title": "Webhooks",
"targetUrl": "Target URL",
"targetUrlInvalid": "Please provide a valid URL.",
"events": "Events",
"eventsHint": "Select all events this webhook should recieve updates for (within the current project).",
"mustSelectEvents": "You must select at least one event.",
"delete": "Delete this webhook",
"deleteText": "Are you sure you want to delete this webhook? External targets will not be notified of its events anymore.",
"deleteSuccess": "The webhook was successfully deleted.",
"create": "Create webhook",
"secret": "Secret",
"secretHint": "If provided, all requests to the webhook target URL will be signed using HMAC.",
"secretDocs": "Check out the docs for more details about how to use secrets."
}
},
"filters": {
@ -384,7 +366,7 @@
"title": "Title",
"titlePlaceholder": "The saved filter title goes here…",
"description": "Description",
"descriptionPlaceholder": "Add a description for this filter here, hit '/' for more options…",
"descriptionPlaceholder": "The description goes here…",
"includeNulls": "Include Tasks which don't have a value set",
"requireAll": "Require all filters to be true for a task to show up",
"showDoneTasks": "Show Done Tasks",
@ -425,9 +407,7 @@
"alreadyMigrated2": "Importing again is possible, but might create duplicates. Are you sure?",
"confirm": "I am sure, please start migrating now!",
"importUpload": "To import data from {name} into Vikunja, click the button below to select a file.",
"upload": "Upload file",
"migrationStartedWillReciveEmail": "Vikunja will now import your lists/projects, tasks, notes, reminders and files from {service}. As this will take a while, we will send you an email once done. You can close this window now.",
"migrationInProgress": "A migration is currently in progress. Please wait until it is done."
"upload": "Upload file"
},
"label": {
"title": "Labels",
@ -498,7 +478,6 @@
"custom": "Custom",
"id": "ID",
"created": "Created at",
"createdBy": "Created by {0}",
"actions": "Actions",
"cannotBeUndone": "This cannot be undone!"
},
@ -517,59 +496,24 @@
"edit": "Edit",
"done": "Done",
"heading1": "Heading 1",
"heading1Tooltip": "Big section heading.",
"heading2": "Heading 2",
"heading2Tooltip": "Medium section heading.",
"heading3": "Heading 3",
"heading3Tooltip": "Smaller section header.",
"headingSmaller": "Heading Smaller",
"headingBigger": "Heading Bigger",
"bold": "Bold",
"italic": "Italic",
"strikethrough": "Strikethrough",
"underline": "Underline",
"code": "Code",
"codeTooltip": "Capture a code snippet.",
"quote": "Quote",
"quoteTooltip": "Capture a quote.",
"bulletList": "Bullet list",
"bulletListTooltip": "Create a simple bullet list.",
"unorderedList": "Unordered list",
"orderedList": "Ordered list",
"orderedListTooltip": "Create a list with numbering.",
"unorderedList": "Unordered List",
"orderedList": "Ordered List",
"cleanBlock": "Clean Block",
"link": "Link",
"image": "Image",
"imageTooltip": "Upload an image from your computer.",
"table": {
"title": "Table",
"insert": "Insert table",
"addColumnBefore": "Add column before",
"addColumnAfter": "Add column after",
"deleteColumn": "Delete column",
"addRowBefore": "Add row before",
"addRowAfter": "Add row after",
"deleteRow": "Delete row",
"deleteTable": "Delete table",
"mergeCells": "Merge cells",
"splitCell": "Split cell",
"toggleHeaderColumn": "Toggle header column",
"toggleHeaderRow": "Toggle header row",
"toggleHeaderCell": "Toggle header cell",
"mergeOrSplit": "Merge or split",
"fixTables": "Fix tables"
},
"table": "Table",
"horizontalRule": "Horizontal Rule",
"horizontalRuleTooltip": "Divide a section.",
"sideBySide": "Side By Side",
"guide": "Guide",
"text": "Text",
"textTooltip": "Just start typing with plain text.",
"taskList": "Task list",
"taskListTooltip": "Track tasks with a to-do list.",
"undo": "Undo",
"redo": "Redo",
"placeholder": "Type some text or hit '/' to see more options…"
"guide": "Guide"
},
"multiselect": {
"createPlaceholder": "Create new",
@ -743,7 +687,7 @@
"loading": "Loading comments…",
"edited": "edited {date}",
"creating": "Creating comment…",
"placeholder": "Add your comment, hit '/' for more options…",
"placeholder": "Add your comment…",
"comment": "Comment",
"delete": "Delete this comment",
"deleteText1": "Are you sure you want to delete this comment?",
@ -757,7 +701,7 @@
"1week": "1 week"
},
"description": {
"placeholder": "Enter a description, hit '/' for more options…",
"placeholder": "Click here to enter a description…",
"empty": "No description available yet."
},
"assignee": {
@ -908,7 +852,7 @@
"namePlaceholder": "The team's name goes here…",
"nameRequired": "Please specify a name.",
"description": "Description",
"descriptionPlaceholder": "Describe the team here, hit '/' for more options…",
"descriptionPlaceholder": "The teams description goes here…",
"admin": "Admin",
"member": "Member"
}
@ -936,8 +880,7 @@
"description": "Toggle editing of the task description",
"delete": "Delete this task",
"priority": "Change the priority of this task",
"favorite": "Mark this task as favorite / unfavorite",
"save": "Save the current task"
"favorite": "Mark this task as favorite / unfavorite"
},
"project": {
"title": "Project Views",
@ -987,9 +930,7 @@
"notification": {
"title": "Notifications",
"none": "You don't have any notifications. Have a nice day!",
"explainer": "Notifications will appear here when actions projects or tasks you subscribed to happen.",
"markAllRead": "Mark all notifications as read",
"markAllReadSuccess": "Successfully marked all notifications as read."
"explainer": "Notifications will appear here when actions projects or tasks you subscribed to happen."
},
"quickActions": {
"commands": "Commands",

View File

@ -5,17 +5,16 @@
"welcomeDay": "Ahoj {username}!",
"welcomeEvening": "Dobrý večer {username}!",
"lastViewed": "Naposledy zobrazeno",
"addToHomeScreen": "Přidejte tuto aplikaci na domovskou obrazovku pro rychlejší přístup a lepší zážitek.",
"goToOverview": "Přejít na přehled",
"addToHomeScreen": "Add this app to your home screen for faster access and improved experience.",
"project": {
"importText": "Importujte své projekty a úkoly z jiných služeb do Vikunja:",
"import": "Importujte svá data do Vikunja"
"importText": "Import your projects and tasks from other services into Vikunja:",
"import": "Import your data into Vikunja"
}
},
"demo": {
"title": "Tato instance je v ukázkovém režimu. Nepoužívejte ji pro skutečná data!",
"everythingWillBeDeleted": "Všechno bude v pravidelných intervalech smazáno!",
"accountWillBeDeleted": "Váš účet bude smazán včetně všech projektů, úkolů a příloh, které můžete vytvořit."
"title": "This instance is in demo mode. Do not use this for real data!",
"everythingWillBeDeleted": "Everything will be deleted in regular intervals!",
"accountWillBeDeleted": "Your account will be deleted, including all projects, tasks and attachments you might create."
},
"404": {
"title": "Nenalezeno",
@ -83,17 +82,17 @@
"savedSuccess": "Nastavení bylo úspěšně aktualizováno.",
"emailReminders": "Posílat mi připomenutí pro úkoly e-mailem",
"overdueReminders": "Pošlete mi každý den shrnutí mých zpožděných úkolů",
"discoverableByName": "Umožnit ostatním uživatelům přidat mě jako člena do týmů nebo projektů, když hledají mé jméno",
"discoverableByEmail": "Umožnit ostatním uživatelům, aby mě přidali jako člena do týmů nebo projektů, když hledají můj úplný e-mail",
"discoverableByName": "Allow other users to add me as a member to teams or projects when they search for my name",
"discoverableByEmail": "Allow other users to add me as a member to teams or projects when they search for my full email",
"playSoundWhenDone": "Přehrát zvuk při označení úkolů jako hotovo",
"weekStart": "První den týdne",
"weekStart": "Začátek týdne",
"weekStartSunday": "Neděle",
"weekStartMonday": "Pondělí",
"language": "Jazyk",
"defaultProject": "Výchozí projekt",
"defaultProject": "Default Project",
"timezone": "Časové pásmo",
"overdueTasksRemindersTime": "Čas odeslání emailu o zpožděných úkolech",
"filterUsedOnOverview": "Uložený filtr použitý na stránce přehledu"
"filterUsedOnOverview": "Saved filter used on the overview page"
},
"totp": {
"title": "Dvoufaktorové ověření",
@ -147,37 +146,36 @@
}
},
"apiTokens": {
"title": "API Tokeny",
"general": "API tokeny umožňují používat Vikunja API bez uživatelských údajů.",
"apiDocs": "Podívejte se na dokumentaci api",
"createAToken": "Vytvořit token",
"createToken": "Vytvořit token",
"30d": "30 dní",
"60d": "60 dní",
"90d": "90 dní",
"permissionExplanation": "Oprávnění vám umožní nastavit, k čemu lze api token použít.",
"titleRequired": "Je vyžadován název",
"expired": "Platnost tohoto tokenu vypršela {ago}.",
"tokenCreatedSuccess": "Zde je tvůj nový api token: {token}",
"tokenCreatedNotSeeAgain": "Ulož jej na zabezpečeném místě, už ho znovu neuvidíš!",
"title": "API Tokens",
"general": "API tokens allow you to use Vikunja's API without user credentials.",
"apiDocs": "Check out the api docs",
"createAToken": "Create a token",
"createToken": "Create token",
"30d": "30 Days",
"60d": "60 Days",
"90d": "90 Days",
"permissionExplanation": "Permissions allow you to scope what an api token is allowed to do.",
"titleRequired": "The title is required",
"expired": "This token has expired {ago}.",
"tokenCreatedSuccess": "Here is your new api token: {token}",
"tokenCreatedNotSeeAgain": "Store it in a secure location, you won't see it again!",
"delete": {
"header": "Smazat tento token",
"text1": "Opravdu chcete smazat token \"{token}\"?",
"text2": "Tímto zrušíte přístup ke všem aplikacím nebo integracím, které ho používají. Toto nelze vrátit zpět."
"header": "Delete this token",
"text1": "Are you sure you want to delete the token \"{token}\"?",
"text2": "This will revoke access to all applications or integrations using it. You cannot undo this."
},
"attributes": {
"title": "Název",
"titlePlaceholder": "Zadejte název, podle kterýho ho později poznáte",
"expiresAt": "Vyprší v",
"permissions": "Oprávnění"
"title": "Title",
"titlePlaceholder": "Enter a title you will recognize later",
"expiresAt": "Expires at",
"permissions": "Permissions"
}
}
},
"deletion": {
"title": "Smazat svůj účet",
"text1": "Odstranění vašeho účtu je trvalé a nelze ho vrátit zpět. Vymažeme všechny vaše projekty, úkoly a vše, co je s ním spojeno.",
"text1": "The deletion of your account is permanent and cannot be undone. We will delete all your projects, tasks and everything associated with it.",
"text2": "Chcete-li pokračovat, zadejte své heslo. Obdržíte e-mail s dalšími pokyny.",
"text3": "Chcete-li pokračovat, klikněte na tlačítko níže. Obdržíte e-mail s dalšími pokyny.",
"confirm": "Smazat můj účet",
"requestSuccess": "Požadavek byl úspěšný. Obdržíte e-mail s dalšími pokyny.",
"passwordRequired": "Prosím zadejte Vaše heslo.",
@ -185,13 +183,12 @@
"scheduled": "Váš Vikunja účet odstraníme do {date} ({dateSince}).",
"scheduledCancel": "Chcete-li zrušit smazání vašeho účtu, klikněte zde.",
"scheduledCancelText": "Chcete-li zrušit smazání vašeho účtu, zadejte prosím své heslo níže:",
"scheduledCancelButton": "Chcete-li zrušit odstranění vašeho účtu, klikněte na tlačítko níže:",
"scheduledCancelConfirm": "Zrušit smazání mého účtu",
"scheduledCancelSuccess": "Váš účet nebude smazán."
},
"export": {
"title": "Exportovat data účtu",
"description": "Můžete si vyžádat kopii všech vašich dat Vikunje. To zahrnuje projekty, úkoly a vše, co je s nimi spojeno. Tato data můžete importovat v libovolné instanci Vikunja prostřednictvím migrační funkce.",
"description": "You can request a copy of all your Vikunja data. This includes Projects, Tasks and everything associated to them. You can import this data in any Vikunja instance through the migration function.",
"descriptionPasswordRequired": "Pokračujte zadáním vašeho hesla:",
"request": "Požádat o kopii mých dat",
"success": "Úspěšně jste požádali o svá data! Jakmile budou připravena ke stažení, pošleme Vám e-mail.",
@ -199,182 +196,167 @@
}
},
"project": {
"archivedMessage": "Tento projekt je archivován. Není možné vytvořit ani upravovat jeho úkoly.",
"archived": "Archivováno",
"showArchived": "Zobrazit archivované",
"title": "Název projektu",
"color": "Barva",
"projects": "Projekty",
"parent": "Nadřazený projekt",
"search": "Začni psát pro vyhledání projektu…",
"searchSelect": "Klikněte nebo stiskněte Enter pro výběr tohoto projektu",
"shared": "Sdílené projekty",
"noDescriptionAvailable": "Není k dispozici žádný popis projektu.",
"archivedMessage": "This project is archived. It is not possible to create new or edit tasks for it.",
"archived": "Archived",
"showArchived": "Show Archived",
"title": "Project Title",
"color": "Color",
"projects": "Projects",
"parent": "Parent Project",
"search": "Type to search for a project…",
"searchSelect": "Click or press enter to select this project",
"shared": "Shared Projects",
"noDescriptionAvailable": "No project description is available.",
"inboxTitle": "Inbox",
"create": {
"header": "Nový projekt",
"titlePlaceholder": "Název projektu přijde sem…",
"addTitleRequired": "Zadejte název prosím.",
"createdSuccess": "Projekt byl úspěšně vytvořen.",
"addProjectRequired": "Vyberte projekt nebo nastavte výchozí projekt v nastavení."
"header": "New project",
"titlePlaceholder": "The project's title goes here…",
"addTitleRequired": "Please specify a title.",
"createdSuccess": "The project was successfully created.",
"addProjectRequired": "Please specify a project or set a default project in the settings."
},
"archive": {
"title": "Archivovat \"{project}\"",
"archive": "Archivovat tento projekt",
"unarchive": "Zrušit archivaci tohoto projektu",
"unarchiveText": "Budete moci vytvářet nové úkoly nebo je upravovat.",
"archiveText": "Tento projekt nebudete moci upravovat ani v něm vytvářet nové úkoly, dokud jej neodarchivujete.",
"success": "Projekt byl úspěšně archivován."
"title": "Archive \"{project}\"",
"archive": "Archive this project",
"unarchive": "Un-Archive this project",
"unarchiveText": "You will be able to create new tasks or edit it.",
"archiveText": "You won't be able to edit this project or create new tasks until you un-archive it.",
"success": "The project was successfully archived."
},
"background": {
"title": "Nastavit pozadí projektu",
"remove": "Odstranit pozadí",
"upload": "Vyberte si pozadí ze svého počítače",
"searchPlaceholder": "Hledat pozadí…",
"poweredByUnsplash": "Běží na Unsplash",
"loadMore": "Načíst více fotek",
"success": "Pozadí bylo úspěšně nastaveno!",
"removeSuccess": "Pozadí bylo úspěšně odebráno!"
"title": "Set project background",
"remove": "Remove Background",
"upload": "Choose a background from your pc",
"searchPlaceholder": "Search for a background…",
"poweredByUnsplash": "Powered by Unsplash",
"loadMore": "Load more photos",
"success": "The background has been set successfully!",
"removeSuccess": "The background has been removed successfully!"
},
"delete": {
"title": "Smazat \"{project}\"",
"header": "Odstranit tento projekt",
"text1": "Opravdu chcete smazat projekt a všechny jeho úkoly?",
"text2": "To zahrnuje všechny úkoly a JE TO NEVRATNÉ!",
"success": "Projekt byl úspěšně smazán.",
"tasksToDelete": "Neodvolatelně tím odstraníme asi {count} úloh.",
"noTasksToDelete": "Tento projekt neobsahuje žádné úkoly, mělo by být bezpečné ho smazat."
"title": "Delete \"{project}\"",
"header": "Delete this project",
"text1": "Are you sure you want to delete this project and all of its contents?",
"text2": "This includes all tasks and CANNOT BE UNDONE!",
"success": "The project was successfully deleted.",
"tasksToDelete": "This will irrevocably remove approx. {count} tasks.",
"noTasksToDelete": "This project does not contain any tasks, it should be safe to delete."
},
"duplicate": {
"title": "Duplikovat projekt",
"label": "Duplikovat",
"text": "Vyberte projekt nadřazený duplikovanému projektu:",
"success": "Projekt byl úspěšně duplikován."
"title": "Duplicate this project",
"label": "Duplicate",
"text": "Select a parent project which should hold the duplicated project:",
"success": "The project was successfully duplicated."
},
"edit": {
"header": "Upravit tento projekt",
"title": "Upravit \"{project}\"",
"titlePlaceholder": "Název projektu přijde sem…",
"identifierTooltip": "Identifikátor projektu může být použit k jedinečné identifikaci úkolu napříč projekty. Můžete jej nastavit jako prázdný pro jeho vypnutí.",
"identifier": "Identifikátor projektu",
"identifierPlaceholder": "Identifikátor projektu přijde sem…",
"description": "Popis",
"descriptionPlaceholder": "Zadejte popis tohoto projektu, stiskněte '/' pro další možnosti…",
"color": "Barva",
"success": "Projekt byl úspěšně aktualizován."
"header": "Edit This Project",
"title": "Edit \"{project}\"",
"titlePlaceholder": "The project title goes here…",
"identifierTooltip": "The project identifier can be used to uniquely identify a task across projects. You can set it to empty to disable it.",
"identifier": "Project Identifier",
"identifierPlaceholder": "The project identifier goes here…",
"description": "Description",
"descriptionPlaceholder": "The projects description goes here…",
"color": "Color",
"success": "The project was successfully updated."
},
"share": {
"header": "Sdílet tento projekt",
"title": "Sdílet \"{project}\"",
"share": "Sdílet",
"header": "Share this project",
"title": "Share \"{project}\"",
"share": "Share",
"links": {
"title": "Sdílené odkazy",
"what": "Co je to sdílený odkaz?",
"explanation": "Sdílené odkazy vám umožní snadno sdílet projekt s ostatními uživateli, kteří nemají účet na Vikunja.",
"create": "Vytvořit sdílený odkaz",
"name": "Název (volitelné)",
"namePlaceholder": "např. Lorem Ipsum",
"nameExplanation": "Všechny akce provedené tímto sdíleným odkazem se zobrazí s tímto názvem.",
"password": "Heslo (volitelné)",
"passwordExplanation": "Při přihlášení bude uživatel muset zadat toto heslo.",
"noName": "Není nastaven žádný název",
"remove": "Odstranit sdílený odkaz",
"removeText": "Jste si jisti, že chcete odstranit tento sdílený odkaz? K tomuto projektu již nebude možné přistupovat s tímto sdíleným odkazem. Tuto akci nelze vrátit zpět!",
"createSuccess": "Sdílený odkaz byl úspěšně vytvořen.",
"deleteSuccess": "Sdílený odkaz byl úspěšně smazán",
"view": "Zobrazit",
"sharedBy": "Sdílel(a) {0}"
"title": "Share Links",
"what": "What is a share link?",
"explanation": "Share Links allow you to easily share a project with other users who don't have an account on Vikunja.",
"create": "Create a new link share",
"name": "Name (optional)",
"namePlaceholder": "e.g. Lorem Ipsum",
"nameExplanation": "All actions done by this link share will show up with the name.",
"password": "Password (optional)",
"passwordExplanation": "When signing in, the user will be required to enter this password.",
"noName": "No name set",
"remove": "Remove a link share",
"removeText": "Are you sure you want to remove this link share? It will no longer be possible to access this project with this link share. This cannot be undone!",
"createSuccess": "The link share was successfully created.",
"deleteSuccess": "The link share was successfully deleted",
"view": "View",
"sharedBy": "Shared by {0}"
},
"userTeam": {
"typeUser": "uživatel | uživatelé",
"typeTeam": "tým | týmy",
"shared": "Sdíleno s těmito {type}",
"you": "Ty",
"notShared": "Zatím není sdíleno s žádným {type}.",
"removeHeader": "Odstranit {type} z {sharable}",
"removeText": "Jste si jisti, že chcete odstranit {sharable} z {type}.? Tuto akci nelze vrátit zpět!",
"removeSuccess": "{sharable} byl úspěšně odebrán z {type}.",
"addedSuccess": "{type} byl úspěšně přidán.",
"updatedSuccess": "{type} byl úspěšně přidán."
"typeUser": "user | users",
"typeTeam": "team | teams",
"shared": "Shared with these {type}",
"you": "You",
"notShared": "Not shared with any {type} yet.",
"removeHeader": "Remove a {type} from the {sharable}",
"removeText": "Are you sure you want to remove this {sharable} from the {type}? This cannot be undone!",
"removeSuccess": "The {sharable} was successfully removed from the {type}.",
"addedSuccess": "The {type} was successfully added.",
"updatedSuccess": "The {type} was successfully added."
},
"right": {
"title": "Oprávnění",
"read": "Pouze pro čtení",
"readWrite": "Čtení a zápis",
"admin": "Administrátor"
"title": "Permission",
"read": "Read only",
"readWrite": "Read & write",
"admin": "Admin"
},
"attributes": {
"link": "Odkaz",
"delete": "Smazat"
"link": "Link",
"delete": "Delete"
}
},
"list": {
"title": "Seznam",
"add": "Přidat",
"addPlaceholder": "Přidat nový úkol…",
"empty": "Tento projekt je zatím prázdný.",
"newTaskCta": "Vytvořit nový úkol.",
"editTask": "Upravit úkol"
"title": "List",
"add": "Add",
"addPlaceholder": "Add a new task…",
"empty": "This project is currently empty.",
"newTaskCta": "Create a new task.",
"editTask": "Edit Task"
},
"gantt": {
"title": "Gantt",
"showTasksWithoutDates": "Zobrazit úkoly, které nemají nastavené datum",
"size": "Velikost",
"default": "Výchozí",
"month": "Měsíc",
"day": "Den",
"hour": "Hodina",
"range": "Časové období",
"noDates": "Tento úkol nemá nastaveno žádné datum."
"showTasksWithoutDates": "Show tasks which don't have dates set",
"size": "Size",
"default": "Default",
"month": "Month",
"day": "Day",
"hour": "Hour",
"range": "Date Range",
"noDates": "This task has no dates set."
},
"table": {
"title": "Tabulka",
"columns": "Sloupce"
"title": "Table",
"columns": "Columns"
},
"kanban": {
"title": "Kanban",
"limit": "Limit: {limit}",
"noLimit": "Nenastaveno",
"doneBucket": "Sloupec \"Hotovo\"",
"doneBucketHint": "Všechny úkoly přesunuté do tohoto sloupce budou automaticky označeny jako dokončené.",
"doneBucketHintExtended": "Všechny úkoly přesunuté do sloupce \"Hotovo\" budou označeny jako dokončené automaticky. Všechny úkoly označené jako dokončené jinde sem budou přesunuty také.",
"doneBucketSavedSuccess": "Sloupec \"Hotovo\" byl úspěšně uložen.",
"defaultBucket": "Výchozí sloupec",
"defaultBucketHint": "Při vytváření úkolů bez uvedení sloupce, budou přidány do tohoto sloupce.",
"defaultBucketSavedSuccess": "Výchozí sloupec byl úspěšně uložen.",
"deleteLast": "Nelze odstranit poslední sloupec.",
"addTaskPlaceholder": "Zadejte nový název úkolu…",
"addTask": "Přidat úkol",
"addAnotherTask": "Přidat další úkol",
"addBucket": "Vytvořit nový sloupec",
"addBucketPlaceholder": "Zadejte název nového sloupce…",
"deleteHeaderBucket": "Smazat sloupec",
"deleteBucketText1": "Opravdu chcete smazat tento sloupec?",
"deleteBucketText2": "Toto nesmaže žádné úkoly, ale přesune je do výchozího sloupce.",
"deleteBucketSuccess": "Sloupec byl úspěšně smazán.",
"bucketTitleSavedSuccess": "Název sloupce byl úspěšně uložen.",
"bucketLimitSavedSuccess": "Limit sloupce byl úspěšně uložen.",
"collapse": "Sbalit tento sloupec"
"noLimit": "Not Set",
"doneBucket": "Done bucket",
"doneBucketHint": "All tasks moved into this bucket will automatically marked as done.",
"doneBucketHintExtended": "All tasks moved into the done bucket will be marked as done automatically. All tasks marked as done from elsewhere will be moved as well.",
"doneBucketSavedSuccess": "The done bucket has been saved successfully.",
"defaultBucket": "Default bucket",
"defaultBucketHint": "When creating tasks without specifying a bucket, they will be added to this bucket.",
"defaultBucketSavedSuccess": "The default bucket has been saved successfully.",
"deleteLast": "You cannot remove the last bucket.",
"addTaskPlaceholder": "Enter the new task title…",
"addTask": "Add a task",
"addAnotherTask": "Add another task",
"addBucket": "Create a new bucket",
"addBucketPlaceholder": "Enter the new bucket title…",
"deleteHeaderBucket": "Delete the bucket",
"deleteBucketText1": "Are you sure you want to delete this bucket?",
"deleteBucketText2": "This will not delete any tasks but move them into the default bucket.",
"deleteBucketSuccess": "The bucket has been deleted successfully.",
"bucketTitleSavedSuccess": "The bucket title has been saved successfully.",
"bucketLimitSavedSuccess": "The bucket limit been saved successfully.",
"collapse": "Collapse this bucket"
},
"pseudo": {
"favorites": {
"title": "Oblíbené"
"title": "Favorites"
}
},
"webhooks": {
"title": "Webhooky",
"targetUrl": "Cílová URL",
"targetUrlInvalid": "Zadejte prosím platnou URL adresu.",
"events": "Události",
"eventsHint": "Vyberte všechny události, pro které by tento webhook měl dostávat aktualizace (v rámci aktuálního projektu).",
"mustSelectEvents": "Musíte zvolit alespoň jednu událost.",
"delete": "Smazat tento webhook",
"deleteText": "Opravdu chcete odstranit tento webhook? Externí cíle již nebudou informovány o jeho událostech.",
"deleteSuccess": "Webhook byl úspěšně odstraněn.",
"create": "Vytvořit webhook",
"secret": "Tajný klíč",
"secretHint": "Pokud je zadáno, všechny požadavky na cílovou adresu URL webhooku budou podepsány pomocí HMAC.",
"secretDocs": "Další podrobnosti o používání tajných klíčů naleznete v dokumentaci."
}
},
"filters": {
@ -384,7 +366,7 @@
"title": "Název",
"titlePlaceholder": "Název uloženého filtru přijde sem…",
"description": "Popis",
"descriptionPlaceholder": "Přidejte popis pro tento filtr, stiskněte '/' pro více možností…",
"descriptionPlaceholder": "Popis přijde sem…",
"includeNulls": "Zahrnout úkoly, které nemají nastavenou hodnotu",
"requireAll": "Vyžaduje aby všechny filtry odpovídaly, aby se úkol zobrazil",
"showDoneTasks": "Zobrazit dokončené úkoly",
@ -398,9 +380,9 @@
},
"create": {
"title": "Nový uložený filtr",
"description": "Uložený filtr je virtuální projekt, který se počítá ze sady filtrů pokaždé, když je k němu přistupováno.",
"description": "A saved filter is a virtual project which is computed from a set of filters each time it is accessed.",
"action": "Vytvořit uložený filtr",
"titleRequired": "Uveďte název filtru."
"titleRequired": "Please provide a title for the filter."
},
"delete": {
"header": "Smazat tento uložený filtr",
@ -413,7 +395,7 @@
}
},
"migrate": {
"title": "Import z jiných služeb",
"title": "Import from other services",
"titleService": "Importujte svá data z {name} do Vikunja",
"import": "Importujte svá data do Vikunja",
"description": "Chcete-li začít, klikněte na logo jedné ze služeb třetích stran.",
@ -425,14 +407,12 @@
"alreadyMigrated2": "Import je možný, ale mohl by vytvářet duplicity. Jste si jisti?",
"confirm": "Jsem si jistý, začněte migrovat!",
"importUpload": "Chcete-li importovat data z {name} do Vikunja, klikněte na tlačítko níže pro výběr souboru.",
"upload": "Nahrát soubor",
"migrationStartedWillReciveEmail": "Vikunja nyní importuje vaše seznamy/projekty, úkoly, poznámky, připomenutí a soubory z {service}. Protože to bude chvíli trvat, pošleme vám e-mail až bude hotovo. Toto okno můžete nyní zavřít.",
"migrationInProgress": "Probíhá migrace. Počkejte prosím na její dokončení."
"upload": "Nahrát soubor"
},
"label": {
"title": "Štítky",
"manage": "Spravovat štítky",
"description": "Klikněte na štítek pro jeho úpravu. Můžete upravit všechny štítky, které jste vytvořili, můžete použít všechny štítky, které jsou přiřazeny k úkolu z projektu, do kterého máte přístup.",
"description": "Click on a label to edit it. You can edit all labels you created, you can use all labels which are associated with a task to whose project you have access.",
"newCTA": "Momentálně nemáte žádné štítky.",
"search": "Zadejte hledaný štítek…",
"create": {
@ -443,7 +423,7 @@
},
"edit": {
"header": "Upravit štítek",
"forbidden": "Nemáte oprávnění upravovat tento popisek, protože ho nevlastníte.",
"forbidden": "You are not allowed to edit this label because you don't own it.",
"success": "Štítek byl úspěšně aktualizován."
},
"deleteSuccess": "Štítek byl úspěšně smazán.",
@ -457,7 +437,7 @@
},
"sharing": {
"authenticating": "Ověřování…",
"passwordRequired": "Tento sdílený projekt vyžaduje heslo. Zadejte jej níže:",
"passwordRequired": "This shared project requires a password. Please enter it below:",
"error": "Došlo k chybě.",
"invalidPassword": "Neplatné heslo."
},
@ -498,7 +478,6 @@
"custom": "Vlastní",
"id": "ID",
"created": "Vytvořeno",
"createdBy": "Vytvořil(a) {0}",
"actions": "Akce",
"cannotBeUndone": "Toto nelze vrátit!"
},
@ -517,59 +496,24 @@
"edit": "Upravit",
"done": "Hotovo",
"heading1": "Nadpis 1",
"heading1Tooltip": "Velké záhlaví.",
"heading2": "Nadpis 2",
"heading2Tooltip": "Střední záhlaví.",
"heading3": "Nadpis 3",
"heading3Tooltip": "Menší záhlaví.",
"headingSmaller": "Menší nadpis",
"headingBigger": "Větší nadpis",
"bold": "Tučné",
"italic": "Skloněné",
"strikethrough": "Přeškrtnuté",
"underline": "Podtržení",
"code": "Kód",
"codeTooltip": "Zachytit úryvek kódu.",
"quote": "Citace",
"quoteTooltip": "Zachyťte citaci.",
"bulletList": "Seznam s odrážkami",
"bulletListTooltip": "Vytvořit jednoduchý seznam odrážek.",
"unorderedList": "Nečíslovaný seznam",
"orderedList": "Číslovaný seznam",
"orderedListTooltip": "Vytvořit seznam s číslováním.",
"unorderedList": "Seznam s odrážkami",
"orderedList": "Ordered List",
"cleanBlock": "Čistý blok",
"link": "Odkaz",
"image": "Obrázek",
"imageTooltip": "Nahrát obrázek z vašeho počítače.",
"table": {
"title": "Tabulka",
"insert": "Vložit tabulku",
"addColumnBefore": "Přidat sloupec před",
"addColumnAfter": "Přidat sloupec za",
"deleteColumn": "Smazat sloupec",
"addRowBefore": "Přidat řádek před",
"addRowAfter": "Přidat řádek za",
"deleteRow": "Smazat řádek",
"deleteTable": "Smazat tabulku",
"mergeCells": "Sloučit buňky",
"splitCell": "Rozdělit buňku",
"toggleHeaderColumn": "Přepnout sloupec záhlaví",
"toggleHeaderRow": "Přepnout řádek záhlaví",
"toggleHeaderCell": "Přepnout hlavičku",
"mergeOrSplit": "Sloučit nebo rozdělit",
"fixTables": "Opravit tabulky"
},
"table": "Tabulka",
"horizontalRule": "Vodorovná čára",
"horizontalRuleTooltip": "Rozdělit sekci.",
"sideBySide": "Vedle sebe",
"guide": "Průvodce",
"text": "Text",
"textTooltip": "Stačí začít psát prostý text.",
"taskList": "Seznam úkolů",
"taskListTooltip": "Sledovat úkoly se seznamem úkolů.",
"undo": "Vrátit zpět",
"redo": "Opakovat akci",
"placeholder": "Zadejte nějaký text nebo stiskněte '/' pro zobrazení více možností…"
"guide": "Průvodce"
},
"multiselect": {
"createPlaceholder": "Vytvořit nový",
@ -599,14 +543,14 @@
"canuse": "Můžete použít vzorec pro filtrování podle relativních datumů.",
"learnhow": "Podívejte se, jak to funguje",
"title": "Datumový vzorec",
"intro": "Použijte relativní časové údaje, které budou vyřešeny za běhu po aplikování filtru.",
"intro": "Specify relative dates which are resolved on the fly by Vikunja when applying the filter.",
"expression": "Každý datumový matematický výraz začíná datem ukotvení, které může být buď {0}, nebo datový řetězec končící {1}. Po tomto ukotvení může volitelně následovat jeden nebo více matematických výrazů.",
"similar": "Tyto výrazy jsou podobné výrazům poskytnutým {0} a {1}.",
"add1Day": "Přidat jeden den",
"minus1Day": "Odečíst jeden den",
"roundDay": "Zaokrouhlit dolů na nejbližší den",
"supportedUnits": "Podporované časové jednotky",
"someExamples": "Příklady časových výrazů",
"supportedUnits": "Supported time units",
"someExamples": "Examples of time expressions",
"units": {
"seconds": "Sekundy",
"minutes": "Minuty",
@ -635,7 +579,7 @@
"addReminder": "Přidat novou připomínku…",
"doneSuccess": "Úkol byl úspěšně označen jako dokončený.",
"undoneSuccess": "Úkol byl úspěšně znovu otevřen.",
"undo": "Vrátit zpět",
"undo": "Undo",
"openDetail": "Otevřít zobrazení detailu úkolu",
"checklistTotal": "{checked} z {total} úkolů",
"checklistAllDone": "{total} úkolů",
@ -652,7 +596,7 @@
"chooseDueDate": "Klikněte zde pro nastavení termínu dokončení",
"chooseStartDate": "Klikněte zde pro nastavení počátečního data",
"chooseEndDate": "Klikněte zde pro nastavení data ukončení",
"move": "Přesunout úkol do jiného projektu",
"move": "Move task to a different project",
"done": "Označit úkol jako hotový!",
"undone": "Označit jako znovu otevřené",
"created": "Vytvořeno {0} uživatelem {1}",
@ -660,12 +604,12 @@
"doneAt": "Dokončeno {0}",
"updateSuccess": "Úkol byl úspěšně uložen.",
"deleteSuccess": "Úkol byl úspěšně smazán.",
"belongsToProject": "Tento úkol patří do projektu '{project}'",
"belongsToProject": "This task belongs to project '{project}'",
"due": "Termín {at}",
"closePopup": "Zavřít vyskakovací okno",
"organization": "Organizace",
"organization": "Organization",
"management": "Management",
"dateAndTime": "Datum a čas",
"dateAndTime": "Date and time",
"delete": {
"header": "Smazat tento úkol",
"text1": "Opravdu chcete odstranit tento úkol?",
@ -683,7 +627,7 @@
"percentDone": "Nastavit průběh",
"attachments": "Přidat přílohy",
"relatedTasks": "Přidat vztah",
"moveProject": "Přesunout",
"moveProject": "Move",
"color": "Nastavit barvu",
"delete": "Smazat",
"favorite": "Přidat do oblíbených",
@ -710,15 +654,15 @@
"updated": "Aktualizováno"
},
"subscription": {
"subscribedTaskThroughParentProject": "Zde se nemůžete odhlásit, protože jste přihlášeni k odběru tohoto úkolu prostřednictvím jeho projektu.",
"subscribedProject": "Nyní jste přihlášeni k odběru tohoto projektu a budete dostávat oznámení o změnách.",
"notSubscribedProject": "Nejste přihlášeni k tomuto projektu a nebudete dostávat oznámení o změnách.",
"subscribedTaskThroughParentProject": "You can't unsubscribe here because you are subscribed to this task through its project.",
"subscribedProject": "You are currently subscribed to this project and will receive notifications for changes.",
"notSubscribedProject": "You are not subscribed to this project and won't receive notifications for changes.",
"subscribedTask": "Nyní jste přihlášeni k odběru tohoto úkolu a budete dostávat oznámení o změnách.",
"notSubscribedTask": "Nejste přihlášeni k odběru tohoto úkolu, takže nebudete dostávat upozornění na změny.",
"subscribe": "Odebírat",
"unsubscribe": "Odhlásit odběr",
"subscribeSuccessProject": "Nyní jste přihlášeni k odběru tohoto projektu",
"unsubscribeSuccessProject": "Nyní jste odhlášeni od odběru tohoto projektu",
"subscribeSuccessProject": "You are now subscribed to this project",
"unsubscribeSuccessProject": "You are now unsubscribed to this project",
"subscribeSuccessTask": "Nyní jste přihlášeni k tomuto úkolu",
"unsubscribeSuccessTask": "Nyní jste odhlášeni od tohoto úkolu"
},
@ -743,7 +687,7 @@
"loading": "Načítám komentáře…",
"edited": "upraveno {date}",
"creating": "Vytvářím komentář…",
"placeholder": "Přidejte svůj komentář, stiskněte '/' pro více možností…",
"placeholder": "Přidejte svůj komentář…",
"comment": "Komentář",
"delete": "Smazat tento komentář",
"deleteText1": "Opravdu chcete smazat tento komentář?",
@ -757,7 +701,7 @@
"1week": "1 týden"
},
"description": {
"placeholder": "Zadejte popis, stiskněte '/' pro více možností…",
"placeholder": "Kliknutím sem zadejte popis…",
"empty": "Ještě není k dispozici žádný popis."
},
"assignee": {
@ -792,7 +736,7 @@
"new": "Nový vztah k úkolu",
"searchPlaceholder": "Hledejte nový úkol, který chcete přidat jako související…",
"createPlaceholder": "Přidat toto jako nový související úkol",
"differentProject": "Tento úkol patří do jiného projektu.",
"differentProject": "This task belongs to a different project.",
"noneYet": "Zatím žádné vztahy mezi úkoly.",
"delete": "Odstranit vztah k úloze",
"deleteText1": "Jste si jisti, že chcete odstranit tento vztah úkolu?",
@ -813,20 +757,20 @@
}
},
"reminder": {
"before": "{amount} {unit} před {type}",
"after": "{amount} {unit} po {type}",
"beforeShort": "před",
"afterShort": "po",
"onDueDate": "V termínu",
"onStartDate": "V den zahájení",
"onEndDate": "V den ukončení",
"custom": "Vlastní",
"dateAndTime": "Datum a čas"
"before": "{amount} {unit} before {type}",
"after": "{amount} {unit} after {type}",
"beforeShort": "before",
"afterShort": "after",
"onDueDate": "On the due date",
"onStartDate": "On the start date",
"onEndDate": "On the end date",
"custom": "Custom",
"dateAndTime": "Date and time"
},
"repeat": {
"everyDay": "Každý den",
"everyWeek": "Každý týden",
"every30d": "Každých 30 dní",
"every30d": "Every 30 Days",
"mode": "Režim opakování",
"monthly": "Měsíčně",
"fromCurrentDate": "Od aktuálního data",
@ -840,7 +784,7 @@
"invalidAmount": "Zadejte prosím více než 0."
},
"quickAddMagic": {
"hint": "Používejte magické prefixy pro definování termínů, přiřazených osob a dalších vlastností úkolů.",
"hint": "Use magic prefixes to define due dates, assignees and other task properties.",
"title": "Kouzelné rychlé přidání",
"intro": "Při vytváření úkolu můžete použít speciální klíčová slova pro přímé přidání atributů k nově vytvořenému úkolu. To umožňuje přidat běžně používané atributy k úkolům mnohem rychleji.",
"multiple": "Toto můžete použít několikrát.",
@ -851,10 +795,10 @@
"priority1": "Chcete-li nastavit prioritu úkolu, přidejte číslo 1-5, s prefixem {prefix}.",
"priority2": "Čím vyšší číslo, tím vyšší priorita.",
"assignees": "Chcete-li přímo přiřadit úkol k uživateli, přidejte k úkolu jejich uživatelské jméno s prefixem {prefix}.",
"project1": "Chcete-li nastavit projekt pro zobrazený úkol, zadejte jeho název s předponou {prefix}.",
"project2": "Toto vrátí chybu, pokud projekt neexistuje.",
"project3": "Chcete-li použít mezery, stačí přidat \" nebo ' kolem názvu projektu.",
"project4": "Například: {prefix}\"Projekt s mezerami\".",
"project1": "To set a project for the task to appear in, enter its name prefixed with {prefix}.",
"project2": "This will return an error if the project does not exist.",
"project3": "To use spaces, simply add a \" or ' around the project name.",
"project4": "For example: {prefix}\"Project with spaces\".",
"dateAndTime": "Datum a čas",
"date": "Jakékoliv datum bude použito jako datum dokončení nového úkolu. Můžete použít data v kterémkoli z těchto formátů:",
"dateWeekday": "každý pracovní den použije další datum s tímto datem",
@ -887,19 +831,19 @@
"delete": {
"header": "Smazat tým",
"text1": "Jste si jisti, že chcete smazat tento tým a všechny jeho členy?",
"text2": "Všichni členové týmu ztratí přístup k projektům sdíleným s tímto týmem. NELZE TO VZÍT ZPĚT!",
"text2": "All team members will lose access to projects shared with this team. This CANNOT BE UNDONE!",
"success": "Tým byl úspěšně smazán."
},
"deleteUser": {
"header": "Odebrat uživatele z týmu",
"text1": "Opravdu chcete odebrat tohoto uživatele z týmu?",
"text2": "Ztratí přístup ke všem projektům, k nimž má tento tým přístup. NELZE VZÍT ZPĚT!",
"text2": "They will lose access to all projects this team has access to. This CANNOT BE UNDONE!",
"success": "Uživatel byl úspěšně odstraněn z týmu."
},
"leave": {
"title": "Opustit tým",
"text1": "Opravdu chcete opustit tento tým?",
"text2": "Ztratíte přístup ke všem projektům, k nimž má tento tým přístup. Pokud změníte názor, budete potřebovat správce týmu, aby vás znovu přidal.",
"text2": "You will lose access to all projects this team has access to. If you change your mind you'll need a team admin to add you again.",
"success": "Úspěšně jste opustili tým."
}
},
@ -908,7 +852,7 @@
"namePlaceholder": "Název týmu přijde sem…",
"nameRequired": "Zadejte název.",
"description": "Popis",
"descriptionPlaceholder": "Popište tým, stiskněte '/' pro více možností…",
"descriptionPlaceholder": "Popis týmu přijde sem…",
"admin": "Administrátor",
"member": "Člen"
}
@ -931,20 +875,19 @@
"attachment": "Přidat přílohu k tomuto úkolu",
"related": "Upravit související úkoly tohoto úkolu",
"color": "Změnit barvu tohoto úkolu",
"move": "Přesunout tento úkol do jiného projektu",
"move": "Move this task to another project",
"reminder": "Spravovat připomenutí této úlohy",
"description": "Přepnout úpravy popisu úkolu",
"delete": "Smazat tento úkol",
"priority": "Změnit prioritu tohoto úkolu",
"favorite": "Označit tuto úlohu jako oblíbenou / odebrat oblíbené",
"save": "Uložit aktuální úkol"
"delete": "Delete this task",
"priority": "Change the priority of this task",
"favorite": "Mark this task as favorite / unfavorite"
},
"project": {
"title": "Zobrazení projektu",
"switchToListView": "Přepnout na zobrazení seznamu",
"switchToGanttView": "Přepnout na zobrazení gantt",
"switchToKanbanView": "Přepnout na zobrazení kanbanu",
"switchToTableView": "Přepnout na zobrazení tabulky"
"title": "Project Views",
"switchToListView": "Switch to list view",
"switchToGanttView": "Switch to gantt view",
"switchToKanbanView": "Switch to kanban view",
"switchToTableView": "Switch to table view"
},
"navigation": {
"title": "Navigace",
@ -952,11 +895,11 @@
"upcoming": "Přejít na nadcházející úkoly",
"labels": "Přejít na štítky",
"teams": "Přejít na týmy",
"projects": "Přejít na projekty"
"projects": "Navigate to projects"
}
},
"update": {
"available": "K dispozici je aktualizace!",
"available": "There is an update available!",
"do": "Aktualizovat nyní"
},
"menu": {
@ -967,15 +910,15 @@
"unarchive": "Zrušit archivaci",
"setBackground": "Nastavit pozadí",
"share": "Sdílet",
"newProject": "Nový projekt",
"createProject": "Vytvořit projekt"
"newProject": "New project",
"createProject": "Create project"
},
"apiConfig": {
"url": "Vikunja URL",
"urlPlaceholder": "např. https://localhost:3456",
"change": "změnit",
"use": "Používá se instalace Vikunja v {0}",
"error": "Nelze najít nebo použít instalaci Vikunja na \"{domain}\". Zkontrolujte, zda má URL správný formát a můžete se k ní připojit při přímém přístupu a zkuste to znovu.",
"error": "Could not find or use Vikunja installation at \"{domain}\". Please check if the url has the correct format and you can reach it when accessing it directly and try again.",
"success": "Pomocí instalace Vikunja na \"{domain}\".",
"urlRequired": "Je vyžadována adresa URL."
},
@ -987,26 +930,24 @@
"notification": {
"title": "Oznámení",
"none": "Nemáte žádná oznámení. Mějte příjemný den!",
"explainer": "Upozornění se zobrazí zde, když proběhne akce na projektech nebo úkolech, ke kterým jste se přihlásili.",
"markAllRead": "Označit všechna oznámení za přečtená",
"markAllReadSuccess": "Všechna oznámení byla označena jako přečtená."
"explainer": "Notifications will appear here when actions projects or tasks you subscribed to happen."
},
"quickActions": {
"commands": "Příkazy",
"placeholder": "Napište příkaz nebo vyhledávání…",
"hint": "Můžete použít {project} k omezení vyhledávání na projekt. Kombinujte {project} nebo {label} (štítky) s vyhledávacím dotazem pro hledání úkolu s těmito štítky nebo na tomto projektu. Použijte {assignee} pouze pro hledání týmů.",
"hint": "You can use {project} to limit the search to a project. Combine {project} or {label} (labels) with a search query to search for a task with these labels or on that project. Use {assignee} to only search for teams.",
"tasks": "Úkoly",
"projects": "Projekty",
"projects": "Projects",
"teams": "Týmy",
"labels": "Štítky",
"newProject": "Zadejte název nového projektu…",
"labels": "Labels",
"newProject": "Enter the title of the new project…",
"newTask": "Zadejte název nového úkolu…",
"newTeam": "Zadejte název nového týmu…",
"createTask": "Vytvořit úkol v aktuálním projektu ({title})",
"createProject": "Vytvořit projekt",
"createTask": "Create a task in the current project ({title})",
"createProject": "Create a project",
"cmds": {
"newTask": "Nový úkol",
"newProject": "Nový projekt",
"newProject": "New project",
"newTeam": "Nový tým"
}
},
@ -1037,15 +978,15 @@
"1018": "Nastavení typu avatara uživatele je neplatné.",
"2001": "ID nemůže být prázdné nebo 0.",
"2002": "Některé údaje požadavku byly neplatné.",
"3001": "Projekt neexistuje.",
"3004": "Pro provedení této akce musíte mít oprávnění ke čtení k tomuto projektu.",
"3005": "Název projektu nemůže být prázdný.",
"3006": "Sdílení projektu neexistuje.",
"3007": "Projekt s tímto identifikátorem již existuje.",
"3008": "Projekt je archivován, a proto je přístupný pouze pro čtení. To platí i pro všechny úkoly spojené s tímto projektem.",
"4001": "Text úkolu projektu nemůže být prázdný.",
"4002": "Úkol projektu neexistuje.",
"4003": "Všechny úkoly pro hromadnou úpravu musí patřit do stejného projektu.",
"3001": "The project does not exist.",
"3004": "You need to have read permissions on that project to perform that action.",
"3005": "The project title cannot be empty.",
"3006": "The project share does not exist.",
"3007": "A project with this identifier already exists.",
"3008": "The project is archived and can therefore only be accessed read only. This is also true for all tasks associated with this project.",
"4001": "The project task text cannot be empty.",
"4002": "The project task does not exist.",
"4003": "All bulk editing tasks must belong to the same project.",
"4004": "Při hromadných úpravách úkolů je potřeba alespoň jeden úkol.",
"4005": "Nemáte právo vidět tento úkol.",
"4006": "Nadřazený úkol nelze nastavit jako takový.",
@ -1064,21 +1005,21 @@
"4019": "Neplatná hodnota filtru úkolů.",
"6001": "Název týmu nemůže být prázdný.",
"6002": "Tým neexistuje.",
"6004": "Tým již má k tomuto projektu přístup.",
"6004": "The team already has access to that project.",
"6005": "Uživatel je již členem tohoto týmu.",
"6006": "Nelze odstranit posledního člena týmu.",
"6007": "Tým nemá přístup k seznamu pro provedení této akce.",
"7002": "Uživatel již má přístup k tomuto projektu.",
"7003": "K tomuto projektu nemáte přístup.",
"6007": "The team does not have access to the project to perform that action.",
"7002": "The user already has access to that project.",
"7003": "You do not have access to that project.",
"8001": "Tento štítek již v tomto úkolu existuje.",
"8002": "Štítek neexistuje.",
"8003": "K tomuto štítku nemáte přístup.",
"9001": "Právo je neplatné.",
"10001": "Sloupec neexistuje.",
"10002": "Sloupec nepatří do tohoto projektu.",
"10003": "Poslední sloupec v projektu nelze odstranit.",
"10002": "The bucket does not belong to that project.",
"10003": "You cannot remove the last bucket on a project.",
"10004": "Nemůžete přidat úkol do tohoto sloupce, protože již překročil limit úkolů, které do něj můžete uložit.",
"10005": "V projektu může být pouze jeden sloupec \"Hotovo\".",
"10005": "There can be only one done bucket per project.",
"11001": "Uložený filtr neexistuje.",
"11002": "Uložené filtry nejsou k dispozici pro sdílení odkazů.",
"12001": "Typ předplatného je neplatný.",
@ -1093,13 +1034,13 @@
},
"time": {
"units": {
"seconds": "sekunda|sekund",
"minutes": "minuta|minut",
"hours": "hodina|hodin",
"days": "den|dny",
"weeks": "týden|týdny",
"months": "měsíc|měsíce",
"years": "rok|roky"
"seconds": "second|seconds",
"minutes": "minute|minutes",
"hours": "hour|hours",
"days": "day|days",
"weeks": "week|weeks",
"months": "month|months",
"years": "year|years"
}
}
}

View File

@ -6,7 +6,6 @@
"welcomeEvening": "Godaften {username}!",
"lastViewed": "Sidst vist",
"addToHomeScreen": "Add this app to your home screen for faster access and improved experience.",
"goToOverview": "Go to overview",
"project": {
"importText": "Import your projects and tasks from other services into Vikunja:",
"import": "Import your data into Vikunja"
@ -177,7 +176,6 @@
"title": "Slet din Vikunja konto",
"text1": "The deletion of your account is permanent and cannot be undone. We will delete all your projects, tasks and everything associated with it.",
"text2": "For at fortsætte, skal du indtaste din adgangskode. Du vil modtage en e-mail med yderligere instruktioner.",
"text3": "To proceed, please press the button below. You will receive an email with further instructions.",
"confirm": "Slet min konto",
"requestSuccess": "Anmodningen blev gennemført. Du vil modtage en e-mail med yderligere instruktioner.",
"passwordRequired": "Indtast venligst din adgangskode.",
@ -185,7 +183,6 @@
"scheduled": "Vi sletter din Vikunja-konto {date} ({dateSince}).",
"scheduledCancel": "Klik her for at annullere sletningen af din konto.",
"scheduledCancelText": "For at annullere sletningen af din konto, skal du indtaste din adgangskode nedenfor:",
"scheduledCancelButton": "To cancel the deletion of your account, please press the button below:",
"scheduledCancelConfirm": "Annuller sletningen af min konto",
"scheduledCancelSuccess": "Vi sletter ikke din konto."
},
@ -259,7 +256,7 @@
"identifier": "Project Identifier",
"identifierPlaceholder": "The project identifier goes here…",
"description": "Description",
"descriptionPlaceholder": "Enter a description for this project, hit '/' for more options…",
"descriptionPlaceholder": "The projects description goes here…",
"color": "Color",
"success": "The project was successfully updated."
},
@ -360,21 +357,6 @@
"favorites": {
"title": "Favorites"
}
},
"webhooks": {
"title": "Webhooks",
"targetUrl": "Target URL",
"targetUrlInvalid": "Please provide a valid URL.",
"events": "Events",
"eventsHint": "Select all events this webhook should recieve updates for (within the current project).",
"mustSelectEvents": "You must select at least one event.",
"delete": "Delete this webhook",
"deleteText": "Are you sure you want to delete this webhook? External targets will not be notified of its events anymore.",
"deleteSuccess": "The webhook was successfully deleted.",
"create": "Create webhook",
"secret": "Secret",
"secretHint": "If provided, all requests to the webhook target URL will be signed using HMAC.",
"secretDocs": "Check out the docs for more details about how to use secrets."
}
},
"filters": {
@ -384,7 +366,7 @@
"title": "Titel",
"titlePlaceholder": "Det gemte filters titel skrives her…",
"description": "Beskrivelse",
"descriptionPlaceholder": "Add a description for this filter here, hit '/' for more options…",
"descriptionPlaceholder": "Beskrivelsen skrives her…",
"includeNulls": "Inkluder Opgaver som ikke har en værdi indstillet",
"requireAll": "Kræv at alle filtre er sande for at en opgave kan vises",
"showDoneTasks": "Vis Udførte Opgaver",
@ -425,9 +407,7 @@
"alreadyMigrated2": "Du kan godt importere igen, men kan der kan opstå dubletter. Er du sikker?",
"confirm": "Jeg er sikker, start migreringen nu!",
"importUpload": "For at importere data fra {name} til Vikunja, skal du klikke på knappen nedenfor for at vælge en fil.",
"upload": "Upload fil",
"migrationStartedWillReciveEmail": "Vikunja will now import your lists/projects, tasks, notes, reminders and files from {service}. As this will take a while, we will send you an email once done. You can close this window now.",
"migrationInProgress": "A migration is currently in progress. Please wait until it is done."
"upload": "Upload fil"
},
"label": {
"title": "Etiketter",
@ -498,7 +478,6 @@
"custom": "Brugerdefineret",
"id": "ID",
"created": "Oprettet den",
"createdBy": "Created by {0}",
"actions": "Handlinger",
"cannotBeUndone": "Dette kan ikke fortrydes!"
},
@ -517,59 +496,24 @@
"edit": "Rediger",
"done": "Udfør",
"heading1": "Overskrift 1",
"heading1Tooltip": "Big section heading.",
"heading2": "Overskrift 2",
"heading2Tooltip": "Medium section heading.",
"heading3": "Overskrift 3",
"heading3Tooltip": "Smaller section header.",
"headingSmaller": "Overskrift Mindre",
"headingBigger": "Overskrift Større",
"bold": "Fed",
"italic": "Kursiv",
"strikethrough": "Gennemstreget",
"underline": "Underline",
"code": "Kode",
"codeTooltip": "Capture a code snippet.",
"quote": "Citat",
"quoteTooltip": "Capture a quote.",
"bulletList": "Bullet list",
"bulletListTooltip": "Create a simple bullet list.",
"unorderedList": "Unordered list",
"orderedList": "Ordered list",
"orderedListTooltip": "Create a list with numbering.",
"unorderedList": "Usorteret liste",
"orderedList": "Ordered List",
"cleanBlock": "Ryd Blok",
"link": "Link",
"image": "Billede",
"imageTooltip": "Upload an image from your computer.",
"table": {
"title": "Table",
"insert": "Insert table",
"addColumnBefore": "Add column before",
"addColumnAfter": "Add column after",
"deleteColumn": "Delete column",
"addRowBefore": "Add row before",
"addRowAfter": "Add row after",
"deleteRow": "Delete row",
"deleteTable": "Delete table",
"mergeCells": "Merge cells",
"splitCell": "Split cell",
"toggleHeaderColumn": "Toggle header column",
"toggleHeaderRow": "Toggle header row",
"toggleHeaderCell": "Toggle header cell",
"mergeOrSplit": "Merge or split",
"fixTables": "Fix tables"
},
"table": "Tabel",
"horizontalRule": "Horisontal Linje",
"horizontalRuleTooltip": "Divide a section.",
"sideBySide": "Side Om Side",
"guide": "Vejledning",
"text": "Text",
"textTooltip": "Just start typing with plain text.",
"taskList": "Task list",
"taskListTooltip": "Track tasks with a to-do list.",
"undo": "Undo",
"redo": "Redo",
"placeholder": "Type some text or hit '/' to see more options…"
"guide": "Vejledning"
},
"multiselect": {
"createPlaceholder": "Opret ny",
@ -743,7 +687,7 @@
"loading": "Indlæser kommentarer…",
"edited": "redigeret {date}",
"creating": "Opretter kommentar…",
"placeholder": "Add your comment, hit '/' for more options…",
"placeholder": "Tilføj din kommentar…",
"comment": "Kommentar",
"delete": "Slet denne kommentar",
"deleteText1": "Er du sikker på du vil slette denne kommentar?",
@ -757,7 +701,7 @@
"1week": "1 uge"
},
"description": {
"placeholder": "Enter a description, hit '/' for more options…",
"placeholder": "Klik her for at indtaste en beskrivelse…",
"empty": "Ingen beskrivelse tilgængelig endnu."
},
"assignee": {
@ -908,7 +852,7 @@
"namePlaceholder": "Holdnavnet skrives her…",
"nameRequired": "Angiv venligst et navn.",
"description": "Beskrivelse",
"descriptionPlaceholder": "Describe the team here, hit '/' for more options…",
"descriptionPlaceholder": "Holdets beskrivelse skrives her…",
"admin": "Administrator",
"member": "Medlem"
}
@ -936,8 +880,7 @@
"description": "Slå redigering af opgavebeskrivelse til/fra",
"delete": "Delete this task",
"priority": "Change the priority of this task",
"favorite": "Mark this task as favorite / unfavorite",
"save": "Save the current task"
"favorite": "Mark this task as favorite / unfavorite"
},
"project": {
"title": "Project Views",
@ -987,9 +930,7 @@
"notification": {
"title": "Notifikationer",
"none": "Du har ingen notifikationer. Hav en dejlig dag!",
"explainer": "Notifications will appear here when actions projects or tasks you subscribed to happen.",
"markAllRead": "Mark all notifications as read",
"markAllReadSuccess": "Successfully marked all notifications as read."
"explainer": "Notifications will appear here when actions projects or tasks you subscribed to happen."
},
"quickActions": {
"commands": "Kommandoer",

View File

@ -6,7 +6,6 @@
"welcomeEvening": "Guten Abend, {username}!",
"lastViewed": "Zuletzt angesehen",
"addToHomeScreen": "Füge diese App deinem Startbildschirm hinzu, um schneller darauf zuzugreifen und das Erlebnis zu verbessern.",
"goToOverview": "Zur Übersicht",
"project": {
"importText": "Importiere deine Projekte und Aufgaben aus anderen Diensten in Vikunja:",
"import": "Importiere deine Daten in Vikunja"
@ -177,7 +176,6 @@
"title": "Lösche deinen Vikunja-Account",
"text1": "Das Löschen deines Accounts ist dauerhaft und unwiderruflich. Alle Projekte, Aufgaben und zugehörige Daten werden gelöscht.",
"text2": "Zum Fortfahren gib bitte dein Passwort ein. Du erhältst eine E-Mail mit weiteren Anweisungen.",
"text3": "To proceed, please press the button below. You will receive an email with further instructions.",
"confirm": "Meinen Account löschen",
"requestSuccess": "Die Anfrage war erfolgreich. Du erhältst eine E-Mail mit weiteren Anweisungen.",
"passwordRequired": "Bitte gib dein Passwort ein.",
@ -185,7 +183,6 @@
"scheduled": "Wir werden deinen Vikunja-Account am {date} ({dateSince}) löschen.",
"scheduledCancel": "Um die Löschung deines Accounts abzubrechen, klicke hier.",
"scheduledCancelText": "Um die Löschung deines Accounts abzubrechen, gib bitte dein Passwort unten ein:",
"scheduledCancelButton": "To cancel the deletion of your account, please press the button below:",
"scheduledCancelConfirm": "Löschung meines Accounts abbrechen",
"scheduledCancelSuccess": "Wir werden deinen Account nicht löschen."
},
@ -259,7 +256,7 @@
"identifier": "Projektbezeichner",
"identifierPlaceholder": "Der Projektbezeichner kommt hierhin…",
"description": "Beschreibung",
"descriptionPlaceholder": "Gib eine Beschreibung für dieses Projekt ein, drücke '/' für mehr Optionen…",
"descriptionPlaceholder": "Projektbeschreibung eingeben…",
"color": "Farbe",
"success": "Das Projekt wurde erfolgreich aktualisiert."
},
@ -360,21 +357,6 @@
"favorites": {
"title": "Favoriten"
}
},
"webhooks": {
"title": "Webhooks",
"targetUrl": "Ziel-URL",
"targetUrlInvalid": "Bitte gib eine gültige URL an.",
"events": "Ereignisse",
"eventsHint": "Wähle alle Ereignisse aus, für die dieser Webhook Updates erhalten soll (innerhalb des aktuellen Projekts).",
"mustSelectEvents": "Du musst mindestens ein Ereignis auswählen.",
"delete": "Diesen Webhook löschen",
"deleteText": "Bist du sicher, dass du diesen Webhook löschen möchtest? Externe Ziele werden nicht mehr über Ereignisse benachrichtigt.",
"deleteSuccess": "Der Webhook wurde erfolgreich gelöscht.",
"create": "Webhook erstellen",
"secret": "Schlüssel",
"secretHint": "Wenn angegeben, werden alle Anfragen an die Webhook Ziel-URL mit HMAC signiert.",
"secretDocs": "In der Dokumentation findest du weitere Informationen zum Umgang mit Schlüsseln."
}
},
"filters": {
@ -384,7 +366,7 @@
"title": "Titel",
"titlePlaceholder": "Einen gespeicherten Filternamen eingeben …",
"description": "Beschreibung",
"descriptionPlaceholder": "Gib eine Beschreibung für diesen Filter ein, drücke '/' für mehr Optionen…",
"descriptionPlaceholder": "Eine Beschreibung eingeben …",
"includeNulls": "Aufgaben ohne Werte einbeziehen",
"requireAll": "Alle Filterkriterien müssen erfüllt sein, damit eine Aufgabe angezeigt wird",
"showDoneTasks": "Erledigte Aufgaben anzeigen",
@ -425,9 +407,7 @@
"alreadyMigrated2": "Ein erneutes Importieren ist möglich, kann aber Duplikate erzeugen. Bist du sicher?",
"confirm": "Ich bin sicher, bitte starte mit der Migration!",
"importUpload": "Um Daten von {name} in Vikunja zu importieren, klicke auf die Schaltfläche unten, um eine Datei auszuwählen.",
"upload": "Datei hochladen",
"migrationStartedWillReciveEmail": "Vikunja wird nun deine Listen/Projekte, Aufgaben, Notizen, Erinnerungen und Dateien von {service} importieren. Da dies eine Weile dauern wird, senden wir dir eine E-Mail, sobald der Import abgeschlossen ist. Du kannst dieses Fenster jetzt schließen.",
"migrationInProgress": "Ein Import wird gerade durchgeführt. Bitte warte, bis dieser abgeschlossen ist."
"upload": "Datei hochladen"
},
"label": {
"title": "Labels",
@ -498,7 +478,6 @@
"custom": "Benutzerdefiniert",
"id": "ID",
"created": "Erstellt am",
"createdBy": "Erstellt von {0}",
"actions": "Aktionen",
"cannotBeUndone": "Dies kann nicht rückgängig gemacht werden!"
},
@ -517,59 +496,24 @@
"edit": "Bearbeiten",
"done": "Fertig",
"heading1": "Überschrift 1",
"heading1Tooltip": "Große Überschrift.",
"heading2": "Überschrift 2",
"heading2Tooltip": "Mittlere Überschrift.",
"heading3": "Überschrift 3",
"heading3Tooltip": "Kleine Überschrift.",
"headingSmaller": "Kleinere Überschrift",
"headingBigger": "Grössere Überschrift",
"bold": "Fett",
"italic": "Kursiv",
"strikethrough": "Durchgestrichen",
"underline": "Unterstrichen",
"code": "Code",
"codeTooltip": "Erfasse ein Code-Snippet.",
"quote": "Zitat",
"quoteTooltip": "Erfasse ein Zitat.",
"bulletList": "Stichpunktliste",
"bulletListTooltip": "Erstelle eine einfache Stichpunktliste.",
"unorderedList": "Ungeordnete Liste",
"orderedList": "Geordnete Liste",
"orderedListTooltip": "Erstelle eine Liste mit Nummerierung.",
"cleanBlock": "Formatierung löschen",
"link": "Link",
"image": "Bild",
"imageTooltip": "Lade ein Bild von deinem PC hoch.",
"table": {
"title": "Tabelle",
"insert": "Tabelle einfügen",
"addColumnBefore": "Spalte davor hinzufügen",
"addColumnAfter": "Spalte danach hinzufügen",
"deleteColumn": "Spalte löschen",
"addRowBefore": "Zeile davor hinzufügen",
"addRowAfter": "Zeile danach hinzufügen",
"deleteRow": "Zeile löschen",
"deleteTable": "Tabelle löschen",
"mergeCells": "Zellen verbinden",
"splitCell": "Zelle teilen",
"toggleHeaderColumn": "Headerspalte ein/aus",
"toggleHeaderRow": "Headerzeile ein/aus",
"toggleHeaderCell": "Headerzelle ein/aus",
"mergeOrSplit": "Verbinden oder teilen",
"fixTables": "Tabellen reparieren"
},
"table": "Tabelle",
"horizontalRule": "Horizontaler Strich",
"horizontalRuleTooltip": "Teile einen Bereich.",
"sideBySide": "Nebeneinander",
"guide": "Hilfslinie",
"text": "Text",
"textTooltip": "Einfach einen Text tippen.",
"taskList": "Aufgabenliste",
"taskListTooltip": "Aufgaben mit einer To-do-Liste verfolgen.",
"undo": "Rückgängig",
"redo": "Wiederholen",
"placeholder": "Gib Text ein, drücke '/' für mehr Optionen…"
"guide": "Hilfslinie"
},
"multiselect": {
"createPlaceholder": "Neu erstellen",
@ -743,7 +687,7 @@
"loading": "Kommentare werden geladen …",
"edited": "bearbeitet {date}",
"creating": "Kommentar wird erstellt …",
"placeholder": "Füge deinen Kommentar hinzu, drücke '/' für weitere Optionen…",
"placeholder": "Füge deinen Kommentar hinzu …",
"comment": "Kommentieren",
"delete": "Diesen Kommentar löschen",
"deleteText1": "Bist du sicher, dass du diesen Kommentar löschen willst?",
@ -757,7 +701,7 @@
"1week": "1 Woche"
},
"description": {
"placeholder": "Gib eine Beschreibung ein, drücke '/' für mehr Optionen…",
"placeholder": "Klicke hier, um eine Beschreibung einzugeben …",
"empty": "Noch keine Beschreibung vorhanden."
},
"assignee": {
@ -908,7 +852,7 @@
"namePlaceholder": "Teamname eingeben …",
"nameRequired": "Bitte gib einen Namen an.",
"description": "Beschreibung",
"descriptionPlaceholder": "Gib eine Beschreibung für dieses Team ein, drücke '/' für mehr Optionen…",
"descriptionPlaceholder": "Die Beschreibung des Teams steht hier …",
"admin": "Admin",
"member": "Mitglied"
}
@ -936,8 +880,7 @@
"description": "Aufgabenbeschreibung bearbeiten",
"delete": "Diese Aufgabe löschen",
"priority": "Die Priorität dieser Aufgabe ändern",
"favorite": "Diese Aufgabe zum Favoriten machen / von Favoriten entfernen",
"save": "Save the current task"
"favorite": "Diese Aufgabe zum Favoriten machen / von Favoriten entfernen"
},
"project": {
"title": "Projektansichten",
@ -987,9 +930,7 @@
"notification": {
"title": "Benachrichtigungen",
"none": "Du hast keine Benachrichtigungen. Einen schönen Tag noch!",
"explainer": "Benachrichtigungen werden hier angezeigt, wenn Aktionen für Projekte oder Aufgaben, die du abonniert hast, ausgeführt werden.",
"markAllRead": "Alle Benachrichtigungen als gelesen markieren",
"markAllReadSuccess": "Alle Benachrichtigungen erfolgreich als gelesen markiert."
"explainer": "Benachrichtigungen werden hier angezeigt, wenn Aktionen für Projekte oder Aufgaben, die du abonniert hast, ausgeführt werden."
},
"quickActions": {
"commands": "Befehle",

View File

@ -6,7 +6,6 @@
"welcomeEvening": "Guten Abend, {username}!",
"lastViewed": "Zletscht ahglueget",
"addToHomeScreen": "Füge diese App deinem Startbildschirm hinzu, um schneller darauf zuzugreifen und das Erlebnis zu verbessern.",
"goToOverview": "Zur Übersicht",
"project": {
"importText": "Importiere deine Projekte und Aufgaben aus anderen Diensten in Vikunja:",
"import": "Importiere deine Daten in Vikunja"
@ -177,7 +176,6 @@
"title": "Lösche deinen Vikunja-Account",
"text1": "Das Löschen deines Accounts ist dauerhaft und unwiderruflich. Alle Projekte, Aufgaben und zugehörige Daten werden gelöscht.",
"text2": "Zum Fortfahren gib bitte dein Passwort ein. Du erhältst eine E-Mail mit weiteren Anweisungen.",
"text3": "To proceed, please press the button below. You will receive an email with further instructions.",
"confirm": "Meinen Account löschen",
"requestSuccess": "Die Anfrage war erfolgreich. Du erhältst eine E-Mail mit weiteren Anweisungen.",
"passwordRequired": "Bitte gib dein Passwort ein.",
@ -185,7 +183,6 @@
"scheduled": "Wir werden deinen Vikunja-Account am {date} ({dateSince}) löschen.",
"scheduledCancel": "Um die Löschung deines Accounts abzubrechen, klicke hier.",
"scheduledCancelText": "Um die Löschung deines Accounts abzubrechen, gib bitte dein Passwort unten ein:",
"scheduledCancelButton": "To cancel the deletion of your account, please press the button below:",
"scheduledCancelConfirm": "Löschung meines Accounts abbrechen",
"scheduledCancelSuccess": "Wir werden deinen Account nicht löschen."
},
@ -259,7 +256,7 @@
"identifier": "Projektbezeichner",
"identifierPlaceholder": "Der Projektbezeichner kommt hierhin…",
"description": "Beschreibung",
"descriptionPlaceholder": "Gib eine Beschreibung für dieses Projekt ein, drücke '/' für mehr Optionen…",
"descriptionPlaceholder": "Projektbeschreibung eingeben…",
"color": "Farbe",
"success": "Das Projekt wurde erfolgreich aktualisiert."
},
@ -360,21 +357,6 @@
"favorites": {
"title": "Favoriten"
}
},
"webhooks": {
"title": "Webhooks",
"targetUrl": "Ziel-URL",
"targetUrlInvalid": "Bitte gib eine gültige URL an.",
"events": "Ereignisse",
"eventsHint": "Wähle alle Ereignisse aus, für die dieser Webhook Updates erhalten soll (innerhalb des aktuellen Projekts).",
"mustSelectEvents": "Du musst mindestens ein Ereignis auswählen.",
"delete": "Diesen Webhook löschen",
"deleteText": "Bist du sicher, dass du diesen Webhook löschen möchtest? Externe Ziele werden nicht mehr über Ereignisse benachrichtigt.",
"deleteSuccess": "Der Webhook wurde erfolgreich gelöscht.",
"create": "Webhook erstellen",
"secret": "Schlüssel",
"secretHint": "Wenn angegeben, werden alle Anfragen an die Webhook Ziel-URL mit HMAC signiert.",
"secretDocs": "In der Dokumentation findest du weitere Informationen zum Umgang mit Schlüsseln."
}
},
"filters": {
@ -384,7 +366,7 @@
"title": "Titl",
"titlePlaceholder": "De Name für de g'speicheret Filter chunt da ahne…",
"description": "Beschriibig",
"descriptionPlaceholder": "Gib eine Beschreibung für diesen Filter ein, drücke '/' für mehr Optionen…",
"descriptionPlaceholder": "D'Beschriibig chunt da hane…",
"includeNulls": "Uufgabe ohni Wert iihbezieh",
"requireAll": "Alli Filter mend wahr sii, demits die Uufgab ahzeigt",
"showDoneTasks": "Zeig die fertige Uufgabe",
@ -425,9 +407,7 @@
"alreadyMigrated2": "Es erneuts Importiere isch scho mögli, aber chenti Duplikaat erstelle. Bisch der sicher?",
"confirm": "Ich bin sicher, fang mit de Migration ah!",
"importUpload": "Um Daten von {name} in Vikunja zu importieren, klicke auf die Schaltfläche unten, um eine Datei auszuwählen.",
"upload": "Datei hochladen",
"migrationStartedWillReciveEmail": "Vikunja wird nun deine Listen/Projekte, Aufgaben, Notizen, Erinnerungen und Dateien von {service} importieren. Da dies eine Weile dauern wird, senden wir dir eine E-Mail, sobald der Import abgeschlossen ist. Du kannst dieses Fenster jetzt schließen.",
"migrationInProgress": "Ein Import wird gerade durchgeführt. Bitte warte, bis dieser abgeschlossen ist."
"upload": "Datei hochladen"
},
"label": {
"title": "Labels",
@ -498,7 +478,6 @@
"custom": "Benutzerdefiniert",
"id": "ID",
"created": "Erstellt am",
"createdBy": "Erstellt von {0}",
"actions": "Aktionen",
"cannotBeUndone": "Dies kann nicht rückgängig gemacht werden!"
},
@ -517,59 +496,24 @@
"edit": "Bearbeitä",
"done": "Fertig",
"heading1": "Überschrift 1",
"heading1Tooltip": "Große Überschrift.",
"heading2": "Überschrift 2",
"heading2Tooltip": "Mittlere Überschrift.",
"heading3": "Überschrift 3",
"heading3Tooltip": "Kleine Überschrift.",
"headingSmaller": "Chliini Überschrift",
"headingBigger": "Grösseri Überschrift",
"bold": "Fett",
"italic": "Kursiiv",
"strikethrough": "Duregstriche",
"underline": "Unterstrichen",
"code": "Code",
"codeTooltip": "Erfasse ein Code-Snippet.",
"quote": "Zitaat",
"quoteTooltip": "Erfasse ein Zitat.",
"bulletList": "Stichpunktliste",
"bulletListTooltip": "Erstelle eine einfache Stichpunktliste.",
"unorderedList": "Ungeordnete Liste",
"unorderedList": "Ungordnedi Listä",
"orderedList": "Geordnete Liste",
"orderedListTooltip": "Erstelle eine Liste mit Nummerierung.",
"cleanBlock": "Formatierig Lösche",
"link": "Link",
"image": "Bild",
"imageTooltip": "Lade ein Bild von deinem PC hoch.",
"table": {
"title": "Tabelle",
"insert": "Tabelle einfügen",
"addColumnBefore": "Spalte davor hinzufügen",
"addColumnAfter": "Spalte danach hinzufügen",
"deleteColumn": "Spalte löschen",
"addRowBefore": "Zeile davor hinzufügen",
"addRowAfter": "Zeile danach hinzufügen",
"deleteRow": "Zeile löschen",
"deleteTable": "Tabelle löschen",
"mergeCells": "Zellen verbinden",
"splitCell": "Zelle teilen",
"toggleHeaderColumn": "Headerspalte ein/aus",
"toggleHeaderRow": "Headerzeile ein/aus",
"toggleHeaderCell": "Headerzelle ein/aus",
"mergeOrSplit": "Verbinden oder teilen",
"fixTables": "Tabellen reparieren"
},
"table": "Tabällä",
"horizontalRule": "Horizontalä Strich",
"horizontalRuleTooltip": "Teile einen Bereich.",
"sideBySide": "Nebedenand",
"guide": "Hilfsliniä",
"text": "Text",
"textTooltip": "Einfach einen Text tippen.",
"taskList": "Aufgabenliste",
"taskListTooltip": "Aufgaben mit einer To-do-Liste verfolgen.",
"undo": "Rückgängig",
"redo": "Wiederholen",
"placeholder": "Gib Text ein, drücke '/' für mehr Optionen…"
"guide": "Hilfsliniä"
},
"multiselect": {
"createPlaceholder": "Neu erstelle",
@ -743,7 +687,7 @@
"loading": "Kommentär werded gladä…",
"edited": "beartbeitet am {date}",
"creating": "Kommentar wird erstellt…",
"placeholder": "Füge deinen Kommentar hinzu, drücke '/' für weitere Optionen…",
"placeholder": "Din Kommentar wird hinzuegfüegt…",
"comment": "Kommentar",
"delete": "De Kommentar chüble",
"deleteText1": "Bisch du dir sicher, dass du de Kommentar chüble wetsch?",
@ -757,7 +701,7 @@
"1week": "Ei Wuche"
},
"description": {
"placeholder": "Gib eine Beschreibung ein, drücke '/' für mehr Optionen…",
"placeholder": "Klicke do, um e Beschriibig iihzfüege…",
"empty": "Momentan hets kei Beschriibig."
},
"assignee": {
@ -908,7 +852,7 @@
"namePlaceholder": "Teamname da ahgeh…",
"nameRequired": "Bitte gib en Name an.",
"description": "Beschriibig",
"descriptionPlaceholder": "Gib eine Beschreibung für dieses Team ein, drücke '/' für mehr Optionen…",
"descriptionPlaceholder": "D'Team Beschriibig chunt da ahne…",
"admin": "Chef",
"member": "Mitglied"
}
@ -936,8 +880,7 @@
"description": "Aufgabenbeschreibung bearbeiten",
"delete": "Diese Aufgabe löschen",
"priority": "Die Priorität dieser Aufgabe ändern",
"favorite": "Diese Aufgabe zum Favoriten machen / von Favoriten entfernen",
"save": "Save the current task"
"favorite": "Diese Aufgabe zum Favoriten machen / von Favoriten entfernen"
},
"project": {
"title": "Projektansichten",
@ -987,9 +930,7 @@
"notification": {
"title": "Benachrichtigunge",
"none": "Du hesch kei neui Benachrichtunge. Heb e schös Tägli!",
"explainer": "Benachrichtigungen werden hier angezeigt, wenn Aktionen für Projekte oder Aufgaben, die du abonniert hast, ausgeführt werden.",
"markAllRead": "Alle Benachrichtigungen als gelesen markieren",
"markAllReadSuccess": "Alle Benachrichtigungen erfolgreich als gelesen markiert."
"explainer": "Benachrichtigungen werden hier angezeigt, wenn Aktionen für Projekte oder Aufgaben, die du abonniert hast, ausgeführt werden."
},
"quickActions": {
"commands": "Befehl",

View File

@ -6,7 +6,6 @@
"welcomeEvening": "Good Evening {username}!",
"lastViewed": "Last viewed",
"addToHomeScreen": "Add this app to your home screen for faster access and improved experience.",
"goToOverview": "Go to overview",
"project": {
"importText": "Import your projects and tasks from other services into Vikunja:",
"import": "Import your data into Vikunja"
@ -177,7 +176,6 @@
"title": "Delete your Vikunja Account",
"text1": "The deletion of your account is permanent and cannot be undone. We will delete all your projects, tasks and everything associated with it.",
"text2": "To proceed, please enter your password. You will receive an email with further instructions.",
"text3": "To proceed, please press the button below. You will receive an email with further instructions.",
"confirm": "Delete my account",
"requestSuccess": "The request was successful. You'll receive an email with further instructions.",
"passwordRequired": "Please enter your password.",
@ -185,7 +183,6 @@
"scheduled": "We will delete your Vikunja account at {date} ({dateSince}).",
"scheduledCancel": "To cancel the deletion of your account, click here.",
"scheduledCancelText": "To cancel the deletion of your account, please enter your password below:",
"scheduledCancelButton": "To cancel the deletion of your account, please press the button below:",
"scheduledCancelConfirm": "Cancel the deletion of my account",
"scheduledCancelSuccess": "We will not delete your account."
},
@ -259,7 +256,7 @@
"identifier": "Project Identifier",
"identifierPlaceholder": "The project identifier goes here…",
"description": "Description",
"descriptionPlaceholder": "Enter a description for this project, hit '/' for more options…",
"descriptionPlaceholder": "The projects description goes here…",
"color": "Color",
"success": "The project was successfully updated."
},
@ -360,21 +357,6 @@
"favorites": {
"title": "Favorites"
}
},
"webhooks": {
"title": "Webhooks",
"targetUrl": "Target URL",
"targetUrlInvalid": "Please provide a valid URL.",
"events": "Events",
"eventsHint": "Select all events this webhook should recieve updates for (within the current project).",
"mustSelectEvents": "You must select at least one event.",
"delete": "Delete this webhook",
"deleteText": "Are you sure you want to delete this webhook? External targets will not be notified of its events anymore.",
"deleteSuccess": "The webhook was successfully deleted.",
"create": "Create webhook",
"secret": "Secret",
"secretHint": "If provided, all requests to the webhook target URL will be signed using HMAC.",
"secretDocs": "Check out the docs for more details about how to use secrets."
}
},
"filters": {
@ -384,7 +366,7 @@
"title": "Title",
"titlePlaceholder": "The saved filter title goes here…",
"description": "Description",
"descriptionPlaceholder": "Add a description for this filter here, hit '/' for more options…",
"descriptionPlaceholder": "The description goes here…",
"includeNulls": "Include Tasks which don't have a value set",
"requireAll": "Require all filters to be true for a task to show up",
"showDoneTasks": "Show Done Tasks",
@ -425,9 +407,7 @@
"alreadyMigrated2": "Importing again is possible, but might create duplicates. Are you sure?",
"confirm": "I am sure, please start migrating now!",
"importUpload": "To import data from {name} into Vikunja, click the button below to select a file.",
"upload": "Upload file",
"migrationStartedWillReciveEmail": "Vikunja will now import your lists/projects, tasks, notes, reminders and files from {service}. As this will take a while, we will send you an email once done. You can close this window now.",
"migrationInProgress": "A migration is currently in progress. Please wait until it is done."
"upload": "Upload file"
},
"label": {
"title": "Labels",
@ -498,7 +478,6 @@
"custom": "Custom",
"id": "ID",
"created": "Created at",
"createdBy": "Created by {0}",
"actions": "Actions",
"cannotBeUndone": "This cannot be undone!"
},
@ -517,60 +496,24 @@
"edit": "Edit",
"done": "Done",
"heading1": "Heading 1",
"heading1Tooltip": "Big section heading.",
"heading2": "Heading 2",
"heading2Tooltip": "Medium section heading.",
"heading3": "Heading 3",
"heading3Tooltip": "Smaller section header.",
"headingSmaller": "Heading Smaller",
"headingBigger": "Heading Bigger",
"bold": "Bold",
"italic": "Italic",
"strikethrough": "Strikethrough",
"underline": "Underline",
"code": "Code",
"codeTooltip": "Capture a code snippet.",
"quote": "Quote",
"quoteTooltip": "Capture a quote.",
"bulletList": "Bullet list",
"bulletListTooltip": "Create a simple bullet list.",
"unorderedList": "Unordered list",
"orderedList": "Ordered list",
"orderedListTooltip": "Create a list with numbering.",
"unorderedList": "Unordered List",
"orderedList": "Ordered List",
"cleanBlock": "Clean Block",
"link": "Link",
"image": "Image",
"imageTooltip": "Upload an image from your computer.",
"table": "Table",
"horizontalRule": "Horizontal Rule",
"horizontalRuleTooltip": "Divide a section.",
"sideBySide": "Side By Side",
"guide": "Guide",
"text": "Text",
"textTooltip": "Just start typing with plain text.",
"taskList": "Task list",
"taskListTooltip": "Track tasks with a to-do list.",
"undo": "Undo",
"redo": "Redo",
"placeholder": "Type some text or hit '/' to see more options…",
"table": {
"title": "Table",
"insert": "Insert table",
"addColumnBefore": "Add column before",
"addColumnAfter": "Add column after",
"deleteColumn": "Delete column",
"addRowBefore": "Add row before",
"addRowAfter": "Add row after",
"deleteRow": "Delete row",
"deleteTable": "Delete table",
"mergeCells": "Merge cells",
"splitCell": "Split cell",
"toggleHeaderColumn": "Toggle header column",
"toggleHeaderRow": "Toggle header row",
"toggleHeaderCell": "Toggle header cell",
"mergeOrSplit": "Merge or split",
"fixTables": "Fix tables"
}
"guide": "Guide"
},
"multiselect": {
"createPlaceholder": "Create new",
@ -747,7 +690,7 @@
"loading": "Loading comments…",
"edited": "edited {date}",
"creating": "Creating comment…",
"placeholder": "Add your comment, hit '/' for more options…",
"placeholder": "Add your comment…",
"comment": "Comment",
"delete": "Delete this comment",
"deleteText1": "Are you sure you want to delete this comment?",
@ -761,7 +704,7 @@
"1week": "1 week"
},
"description": {
"placeholder": "Enter a description, hit '/' for more options…",
"placeholder": "Click here to enter a description…",
"empty": "No description available yet."
},
"assignee": {
@ -912,7 +855,7 @@
"namePlaceholder": "The team's name goes here…",
"nameRequired": "Please specify a name.",
"description": "Description",
"descriptionPlaceholder": "Describe the team here, hit '/' for more options…",
"descriptionPlaceholder": "The teams description goes here…",
"admin": "Admin",
"member": "Member"
}
@ -940,8 +883,7 @@
"description": "Toggle editing of the task description",
"delete": "Delete this task",
"priority": "Change the priority of this task",
"favorite": "Mark this task as favorite / unfavorite",
"save": "Save the current task"
"favorite": "Mark this task as favorite / unfavorite"
},
"project": {
"title": "Project Views",
@ -991,9 +933,7 @@
"notification": {
"title": "Notifications",
"none": "You don't have any notifications. Have a nice day!",
"explainer": "Notifications will appear here when actions projects or tasks you subscribed to happen.",
"markAllRead": "Mark all notifications as read",
"markAllReadSuccess": "Successfully marked all notifications as read."
"explainer": "Notifications will appear here when actions projects or tasks you subscribed to happen."
},
"quickActions": {
"commands": "Commands",

View File

@ -6,7 +6,6 @@
"welcomeEvening": "Good Evening {username}!",
"lastViewed": "Last viewed",
"addToHomeScreen": "Add this app to your home screen for faster access and improved experience.",
"goToOverview": "Go to overview",
"project": {
"importText": "Import your projects and tasks from other services into Vikunja:",
"import": "Import your data into Vikunja"
@ -177,7 +176,6 @@
"title": "Delete your Vikunja Account",
"text1": "The deletion of your account is permanent and cannot be undone. We will delete all your projects, tasks and everything associated with it.",
"text2": "To proceed, please enter your password. You will receive an email with further instructions.",
"text3": "To proceed, please press the button below. You will receive an email with further instructions.",
"confirm": "Delete my account",
"requestSuccess": "The request was successful. You'll receive an email with further instructions.",
"passwordRequired": "Please enter your password.",
@ -185,7 +183,6 @@
"scheduled": "We will delete your Vikunja account at {date} ({dateSince}).",
"scheduledCancel": "To cancel the deletion of your account, click here.",
"scheduledCancelText": "To cancel the deletion of your account, please enter your password below:",
"scheduledCancelButton": "To cancel the deletion of your account, please press the button below:",
"scheduledCancelConfirm": "Cancel the deletion of my account",
"scheduledCancelSuccess": "We will not delete your account."
},
@ -259,7 +256,7 @@
"identifier": "Project Identifier",
"identifierPlaceholder": "The project identifier goes here…",
"description": "Description",
"descriptionPlaceholder": "Enter a description for this project, hit '/' for more options…",
"descriptionPlaceholder": "The projects description goes here…",
"color": "Color",
"success": "The project was successfully updated."
},
@ -360,21 +357,6 @@
"favorites": {
"title": "Favorites"
}
},
"webhooks": {
"title": "Webhooks",
"targetUrl": "Target URL",
"targetUrlInvalid": "Please provide a valid URL.",
"events": "Events",
"eventsHint": "Select all events this webhook should recieve updates for (within the current project).",
"mustSelectEvents": "You must select at least one event.",
"delete": "Delete this webhook",
"deleteText": "Are you sure you want to delete this webhook? External targets will not be notified of its events anymore.",
"deleteSuccess": "The webhook was successfully deleted.",
"create": "Create webhook",
"secret": "Secret",
"secretHint": "If provided, all requests to the webhook target URL will be signed using HMAC.",
"secretDocs": "Check out the docs for more details about how to use secrets."
}
},
"filters": {
@ -384,7 +366,7 @@
"title": "Title",
"titlePlaceholder": "The saved filter title goes here…",
"description": "Description",
"descriptionPlaceholder": "Add a description for this filter here, hit '/' for more options…",
"descriptionPlaceholder": "The description goes here…",
"includeNulls": "Include Tasks which don't have a value set",
"requireAll": "Require all filters to be true for a task to show up",
"showDoneTasks": "Show Done Tasks",
@ -425,9 +407,7 @@
"alreadyMigrated2": "Importing again is possible, but might create duplicates. Are you sure?",
"confirm": "I am sure, please start migrating now!",
"importUpload": "To import data from {name} into Vikunja, click the button below to select a file.",
"upload": "Upload file",
"migrationStartedWillReciveEmail": "Vikunja will now import your lists/projects, tasks, notes, reminders and files from {service}. As this will take a while, we will send you an email once done. You can close this window now.",
"migrationInProgress": "A migration is currently in progress. Please wait until it is done."
"upload": "Upload file"
},
"label": {
"title": "Labels",
@ -498,7 +478,6 @@
"custom": "Custom",
"id": "ID",
"created": "Created at",
"createdBy": "Created by {0}",
"actions": "Actions",
"cannotBeUndone": "This cannot be undone!"
},
@ -517,59 +496,24 @@
"edit": "Edit",
"done": "Done",
"heading1": "Heading 1",
"heading1Tooltip": "Big section heading.",
"heading2": "Heading 2",
"heading2Tooltip": "Medium section heading.",
"heading3": "Heading 3",
"heading3Tooltip": "Smaller section header.",
"headingSmaller": "Heading Smaller",
"headingBigger": "Heading Bigger",
"bold": "Bold",
"italic": "Italic",
"strikethrough": "Strikethrough",
"underline": "Underline",
"code": "Code",
"codeTooltip": "Capture a code snippet.",
"quote": "Quote",
"quoteTooltip": "Capture a quote.",
"bulletList": "Bullet list",
"bulletListTooltip": "Create a simple bullet list.",
"unorderedList": "Unordered list",
"orderedList": "Ordered list",
"orderedListTooltip": "Create a list with numbering.",
"unorderedList": "Unordered List",
"orderedList": "Ordered List",
"cleanBlock": "Clean Block",
"link": "Link",
"image": "Image",
"imageTooltip": "Upload an image from your computer.",
"table": {
"title": "Table",
"insert": "Insert table",
"addColumnBefore": "Add column before",
"addColumnAfter": "Add column after",
"deleteColumn": "Delete column",
"addRowBefore": "Add row before",
"addRowAfter": "Add row after",
"deleteRow": "Delete row",
"deleteTable": "Delete table",
"mergeCells": "Merge cells",
"splitCell": "Split cell",
"toggleHeaderColumn": "Toggle header column",
"toggleHeaderRow": "Toggle header row",
"toggleHeaderCell": "Toggle header cell",
"mergeOrSplit": "Merge or split",
"fixTables": "Fix tables"
},
"table": "Table",
"horizontalRule": "Horizontal Rule",
"horizontalRuleTooltip": "Divide a section.",
"sideBySide": "Side By Side",
"guide": "Guide",
"text": "Text",
"textTooltip": "Just start typing with plain text.",
"taskList": "Task list",
"taskListTooltip": "Track tasks with a to-do list.",
"undo": "Undo",
"redo": "Redo",
"placeholder": "Type some text or hit '/' to see more options…"
"guide": "Guide"
},
"multiselect": {
"createPlaceholder": "Create new",
@ -743,7 +687,7 @@
"loading": "Loading comments…",
"edited": "edited {date}",
"creating": "Creating comment…",
"placeholder": "Add your comment, hit '/' for more options…",
"placeholder": "Add your comment…",
"comment": "Comment",
"delete": "Delete this comment",
"deleteText1": "Are you sure you want to delete this comment?",
@ -757,7 +701,7 @@
"1week": "1 week"
},
"description": {
"placeholder": "Enter a description, hit '/' for more options…",
"placeholder": "Click here to enter a description…",
"empty": "No description available yet."
},
"assignee": {
@ -908,7 +852,7 @@
"namePlaceholder": "The team's name goes here…",
"nameRequired": "Please specify a name.",
"description": "Description",
"descriptionPlaceholder": "Describe the team here, hit '/' for more options…",
"descriptionPlaceholder": "The teams description goes here…",
"admin": "Admin",
"member": "Member"
}
@ -936,8 +880,7 @@
"description": "Toggle editing of the task description",
"delete": "Delete this task",
"priority": "Change the priority of this task",
"favorite": "Mark this task as favorite / unfavorite",
"save": "Save the current task"
"favorite": "Mark this task as favorite / unfavorite"
},
"project": {
"title": "Project Views",
@ -987,9 +930,7 @@
"notification": {
"title": "Notifications",
"none": "You don't have any notifications. Have a nice day!",
"explainer": "Notifications will appear here when actions projects or tasks you subscribed to happen.",
"markAllRead": "Mark all notifications as read",
"markAllReadSuccess": "Successfully marked all notifications as read."
"explainer": "Notifications will appear here when actions projects or tasks you subscribed to happen."
},
"quickActions": {
"commands": "Commands",

View File

@ -6,7 +6,6 @@
"welcomeEvening": "¡Buenas Tardes {username}!",
"lastViewed": "Visto por última vez",
"addToHomeScreen": "Añade esta aplicación a tu pantalla de inicio para un acceso más rápido y una experiencia mejorada.",
"goToOverview": "Go to overview",
"project": {
"importText": "Importa tus proyectos y tareas de otros servicios a Vikunja:",
"import": "Importa tus datos a Vikunja"
@ -177,7 +176,6 @@
"title": "Eliminar tu Cuenta de Vikunja",
"text1": "El borrado de tu cuenta es permanente y no puede deshacerse. Borraremos todos tus proyectos, tareas y todo lo que esté asociado con ellos.",
"text2": "Para continuar, por favor, introduce tu contraseña. Recibirás un correo electrónico con más instrucciones.",
"text3": "To proceed, please press the button below. You will receive an email with further instructions.",
"confirm": "Eliminar mi cuenta",
"requestSuccess": "La solicitud ha sido exitosa. Recibirás un correo electrónico con más instrucciones.",
"passwordRequired": "Por favor, introduce tu contraseña.",
@ -185,7 +183,6 @@
"scheduled": "Eliminaremos tu cuenta de Vikunja en {date} ({dateSince}).",
"scheduledCancel": "Para cancelar la eliminación de tu cuenta, haz clic aquí.",
"scheduledCancelText": "Para cancelar la eliminación de tu cuenta, por favor, introduce tu contraseña a continuación:",
"scheduledCancelButton": "To cancel the deletion of your account, please press the button below:",
"scheduledCancelConfirm": "Cancelar la eliminación de mi cuenta",
"scheduledCancelSuccess": "No eliminaremos tu cuenta."
},
@ -259,7 +256,7 @@
"identifier": "Identificador del proyecto",
"identifierPlaceholder": "El identificador del proyecto va aquí…",
"description": "Descripción",
"descriptionPlaceholder": "Enter a description for this project, hit '/' for more options…",
"descriptionPlaceholder": "La descripción del proyecto va aquí…",
"color": "Color",
"success": "El proyecto se ha actualizado con éxito."
},
@ -360,21 +357,6 @@
"favorites": {
"title": "Favoritos"
}
},
"webhooks": {
"title": "Webhooks",
"targetUrl": "Target URL",
"targetUrlInvalid": "Please provide a valid URL.",
"events": "Events",
"eventsHint": "Select all events this webhook should recieve updates for (within the current project).",
"mustSelectEvents": "You must select at least one event.",
"delete": "Delete this webhook",
"deleteText": "Are you sure you want to delete this webhook? External targets will not be notified of its events anymore.",
"deleteSuccess": "The webhook was successfully deleted.",
"create": "Create webhook",
"secret": "Secret",
"secretHint": "If provided, all requests to the webhook target URL will be signed using HMAC.",
"secretDocs": "Check out the docs for more details about how to use secrets."
}
},
"filters": {
@ -384,7 +366,7 @@
"title": "Título",
"titlePlaceholder": "El título del filtro guardado va aquí…",
"description": "Descripción",
"descriptionPlaceholder": "Add a description for this filter here, hit '/' for more options…",
"descriptionPlaceholder": "La descripción va aquí…",
"includeNulls": "Incluye tareas que no tienen un valor establecido",
"requireAll": "Requerir que todos los filtros sean verdaderos para que una tarea se muestre",
"showDoneTasks": "Mostrar tareas completadas",
@ -425,9 +407,7 @@
"alreadyMigrated2": "Importar de nuevo es posible, pero puede crear duplicados. ¿Estás seguro?",
"confirm": "Estoy seguro, ¡por favor empieza a migrar ahora!",
"importUpload": "Para importar datos de {name} a Vikunja, haz clic en el botón de abajo para seleccionar un archivo.",
"upload": "Subir archivo",
"migrationStartedWillReciveEmail": "Vikunja will now import your lists/projects, tasks, notes, reminders and files from {service}. As this will take a while, we will send you an email once done. You can close this window now.",
"migrationInProgress": "A migration is currently in progress. Please wait until it is done."
"upload": "Subir archivo"
},
"label": {
"title": "Etiquetas",
@ -498,7 +478,6 @@
"custom": "Personalizado",
"id": "ID",
"created": "Creado en",
"createdBy": "Created by {0}",
"actions": "Acciones",
"cannotBeUndone": "¡No se puede deshacer!"
},
@ -517,59 +496,24 @@
"edit": "Editar",
"done": "Hecho",
"heading1": "Encabezado 1",
"heading1Tooltip": "Big section heading.",
"heading2": "Encabezado 2",
"heading2Tooltip": "Medium section heading.",
"heading3": "Encabezado 3",
"heading3Tooltip": "Smaller section header.",
"headingSmaller": "Reducir Encabezado",
"headingBigger": "Aumentar Encabezado",
"bold": "Negrita",
"italic": "Cursiva",
"strikethrough": "Tachado",
"underline": "Underline",
"code": "Código",
"codeTooltip": "Capture a code snippet.",
"quote": "Cita",
"quoteTooltip": "Capture a quote.",
"bulletList": "Bullet list",
"bulletListTooltip": "Create a simple bullet list.",
"unorderedList": "Unordered list",
"orderedList": "Ordered list",
"orderedListTooltip": "Create a list with numbering.",
"unorderedList": "Lista no ordenada",
"orderedList": "Lista ordenada",
"cleanBlock": "Borrar Bloque",
"link": "Enlace",
"image": "Imagen",
"imageTooltip": "Upload an image from your computer.",
"table": {
"title": "Table",
"insert": "Insert table",
"addColumnBefore": "Add column before",
"addColumnAfter": "Add column after",
"deleteColumn": "Delete column",
"addRowBefore": "Add row before",
"addRowAfter": "Add row after",
"deleteRow": "Delete row",
"deleteTable": "Delete table",
"mergeCells": "Merge cells",
"splitCell": "Split cell",
"toggleHeaderColumn": "Toggle header column",
"toggleHeaderRow": "Toggle header row",
"toggleHeaderCell": "Toggle header cell",
"mergeOrSplit": "Merge or split",
"fixTables": "Fix tables"
},
"table": "Tabla",
"horizontalRule": "Regla Horizontal",
"horizontalRuleTooltip": "Divide a section.",
"sideBySide": "De Lado a Lado",
"guide": "Guía",
"text": "Text",
"textTooltip": "Just start typing with plain text.",
"taskList": "Task list",
"taskListTooltip": "Track tasks with a to-do list.",
"undo": "Undo",
"redo": "Redo",
"placeholder": "Type some text or hit '/' to see more options…"
"guide": "Guía"
},
"multiselect": {
"createPlaceholder": "Crear nuevo",
@ -743,7 +687,7 @@
"loading": "Cargando comentarios…",
"edited": "editado {date}",
"creating": "Creando comentario…",
"placeholder": "Add your comment, hit '/' for more options…",
"placeholder": "Añade tu comentario…",
"comment": "Comentar",
"delete": "Eliminar este comentario",
"deleteText1": "¿Está seguro que desea eliminar este comentario?",
@ -757,7 +701,7 @@
"1week": "1 semana"
},
"description": {
"placeholder": "Enter a description, hit '/' for more options…",
"placeholder": "Presione aquí para añadir una descripción…",
"empty": "Aún no hay descripción disponible."
},
"assignee": {
@ -908,7 +852,7 @@
"namePlaceholder": "El nombre del equipo va aquí…",
"nameRequired": "Por favor especifica un nombre.",
"description": "Descripción",
"descriptionPlaceholder": "Describe the team here, hit '/' for more options…",
"descriptionPlaceholder": "La descripción del equipo va aquí…",
"admin": "Admin",
"member": "Miembro"
}
@ -936,8 +880,7 @@
"description": "Editar la descripción de la tarea",
"delete": "Eliminar esta tarea",
"priority": "Cambiar la prioridad de esta tarea",
"favorite": "Marcar esta tarea como favorita / no favorita",
"save": "Save the current task"
"favorite": "Marcar esta tarea como favorita / no favorita"
},
"project": {
"title": "Vistas de proyecto",
@ -987,9 +930,7 @@
"notification": {
"title": "Notificaciones",
"none": "No tienes notificaciones. ¡Que tengas un buen día!",
"explainer": "Las notificaciones aparecerán aquí cuando se realicen acciones en proyectos o tareas a las que te hayas suscrito.",
"markAllRead": "Mark all notifications as read",
"markAllReadSuccess": "Successfully marked all notifications as read."
"explainer": "Las notificaciones aparecerán aquí cuando se realicen acciones en proyectos o tareas a las que te hayas suscrito."
},
"quickActions": {
"commands": "Comandos",

View File

@ -6,7 +6,6 @@
"welcomeEvening": "Bonsoir {username} !",
"lastViewed": "Dernière consultation",
"addToHomeScreen": "Ajoutez cette application à votre écran d'accueil pour un accès plus rapide et une meilleure expérience.",
"goToOverview": "Go to overview",
"project": {
"importText": "Importer vos projets et tâches dautres services dans Vikunja :",
"import": "Importer vos données dans Vikunja"
@ -177,7 +176,6 @@
"title": "Supprimer votre compte Vikunja",
"text1": "La suppression de votre compte est définitive et ne peut pas être annulée. Nous supprimerons tous vos projets, tâches et tout ce qui y est associé.",
"text2": "Pour continuer, saisissez votre mot de passe. Vous recevrez un courriel contenant les instructions à suivre.",
"text3": "To proceed, please press the button below. You will receive an email with further instructions.",
"confirm": "Supprimer mon compte",
"requestSuccess": "La requête a abouti. Vous recevrez un courriel avec des instructions à suivre.",
"passwordRequired": "Saisissez votre mot de passe.",
@ -185,7 +183,6 @@
"scheduled": "Nous allons supprimer votre compte Vikunja le {date} ({dateSince}).",
"scheduledCancel": "Pour annuler la suppression de votre compte, cliquez ici.",
"scheduledCancelText": "Pour annuler la suppression de votre compte, saisissez votre mot de passe ci-dessous :",
"scheduledCancelButton": "To cancel the deletion of your account, please press the button below:",
"scheduledCancelConfirm": "Annuler la suppression de mon compte",
"scheduledCancelSuccess": "Nous ne supprimerons pas votre compte."
},
@ -259,7 +256,7 @@
"identifier": "Identifiant de projet",
"identifierPlaceholder": "Saisir ici lidentifiant du projet…",
"description": "Description",
"descriptionPlaceholder": "Enter a description for this project, hit '/' for more options…",
"descriptionPlaceholder": "Saisir ici la description du projet…",
"color": "Couleur",
"success": "Le projet a bien été mis à jour."
},
@ -360,21 +357,6 @@
"favorites": {
"title": "Favoris"
}
},
"webhooks": {
"title": "Webhooks",
"targetUrl": "Target URL",
"targetUrlInvalid": "Please provide a valid URL.",
"events": "Events",
"eventsHint": "Select all events this webhook should recieve updates for (within the current project).",
"mustSelectEvents": "You must select at least one event.",
"delete": "Delete this webhook",
"deleteText": "Are you sure you want to delete this webhook? External targets will not be notified of its events anymore.",
"deleteSuccess": "The webhook was successfully deleted.",
"create": "Create webhook",
"secret": "Secret",
"secretHint": "If provided, all requests to the webhook target URL will be signed using HMAC.",
"secretDocs": "Check out the docs for more details about how to use secrets."
}
},
"filters": {
@ -384,7 +366,7 @@
"title": "Nom",
"titlePlaceholder": "Entre un nom de filtre enregistré…",
"description": "Description",
"descriptionPlaceholder": "Add a description for this filter here, hit '/' for more options…",
"descriptionPlaceholder": "Écris une description…",
"includeNulls": "Inclure les tâches sans valeurs",
"requireAll": "Exiger tous les filtres pour quune tâche saffiche",
"showDoneTasks": "Afficher les tâches terminées",
@ -425,9 +407,7 @@
"alreadyMigrated2": "Importer à nouveau est possible mais peut créer des doublons. Es-tu sûr·e ?",
"confirm": "Je suis sûr·e, commencer à migrer maintenant !",
"importUpload": "Pour importer les données de {name} dans Vikunja, cliquez sur le bouton ci-dessous pour sélectionner un fichier.",
"upload": "Téléverser le fichier",
"migrationStartedWillReciveEmail": "Vikunja will now import your lists/projects, tasks, notes, reminders and files from {service}. As this will take a while, we will send you an email once done. You can close this window now.",
"migrationInProgress": "A migration is currently in progress. Please wait until it is done."
"upload": "Téléverser le fichier"
},
"label": {
"title": "Étiquettes",
@ -498,7 +478,6 @@
"custom": "Personnaliser",
"id": "Identifiant",
"created": "Créé à",
"createdBy": "Created by {0}",
"actions": "Actions",
"cannotBeUndone": "Cette action ne peut pas être annulée !"
},
@ -517,59 +496,24 @@
"edit": "Modifier",
"done": "Terminé",
"heading1": "En-tête 1",
"heading1Tooltip": "Big section heading.",
"heading2": "En-tête 2",
"heading2Tooltip": "Medium section heading.",
"heading3": "En-tête 3",
"heading3Tooltip": "Smaller section header.",
"headingSmaller": "En-tête plus petit",
"headingBigger": "En-tête plus grand",
"bold": "Gras",
"italic": "Italique",
"strikethrough": "Barré",
"underline": "Underline",
"code": "Code",
"codeTooltip": "Capture a code snippet.",
"quote": "Citation",
"quoteTooltip": "Capture a quote.",
"bulletList": "Bullet list",
"bulletListTooltip": "Create a simple bullet list.",
"unorderedList": "Unordered list",
"orderedList": "Ordered list",
"orderedListTooltip": "Create a list with numbering.",
"unorderedList": "Liste non ordonnée",
"orderedList": "Liste ordonnée",
"cleanBlock": "Nettoyer le code",
"link": "Lien",
"image": "Image",
"imageTooltip": "Upload an image from your computer.",
"table": {
"title": "Table",
"insert": "Insert table",
"addColumnBefore": "Add column before",
"addColumnAfter": "Add column after",
"deleteColumn": "Delete column",
"addRowBefore": "Add row before",
"addRowAfter": "Add row after",
"deleteRow": "Delete row",
"deleteTable": "Delete table",
"mergeCells": "Merge cells",
"splitCell": "Split cell",
"toggleHeaderColumn": "Toggle header column",
"toggleHeaderRow": "Toggle header row",
"toggleHeaderCell": "Toggle header cell",
"mergeOrSplit": "Merge or split",
"fixTables": "Fix tables"
},
"table": "Tableau",
"horizontalRule": "Règle horizontale",
"horizontalRuleTooltip": "Divide a section.",
"sideBySide": "Côte à côte",
"guide": "Guide",
"text": "Text",
"textTooltip": "Just start typing with plain text.",
"taskList": "Task list",
"taskListTooltip": "Track tasks with a to-do list.",
"undo": "Undo",
"redo": "Redo",
"placeholder": "Type some text or hit '/' to see more options…"
"guide": "Guide"
},
"multiselect": {
"createPlaceholder": "Créer un nouveau",
@ -743,7 +687,7 @@
"loading": "Chargement des commentaires…",
"edited": "modifié {date}",
"creating": "Création dun commentaire…",
"placeholder": "Add your comment, hit '/' for more options…",
"placeholder": "Ajouter votre commentaire…",
"comment": "Commentaire",
"delete": "Supprimer ce commentaire",
"deleteText1": "Supprimer ce commentaire ?",
@ -757,7 +701,7 @@
"1week": "1 semaine"
},
"description": {
"placeholder": "Enter a description, hit '/' for more options…",
"placeholder": "Cliquez ici pour entrer une description…",
"empty": "Aucune description nest encore disponible."
},
"assignee": {
@ -908,7 +852,7 @@
"namePlaceholder": "Saisir le nom de léquipe…",
"nameRequired": "Indiquer un nom.",
"description": "Description",
"descriptionPlaceholder": "Describe the team here, hit '/' for more options…",
"descriptionPlaceholder": "Saisir la description des équipes…",
"admin": "Admin",
"member": "Membre"
}
@ -936,8 +880,7 @@
"description": "Activer ou désactiver la modification de la description de tâche",
"delete": "Supprimer cette tâche",
"priority": "Changer la priorité de cette tâche",
"favorite": "Marquer cette tâche comme favorite ou non",
"save": "Save the current task"
"favorite": "Marquer cette tâche comme favorite ou non"
},
"project": {
"title": "Vues du projet",
@ -987,9 +930,7 @@
"notification": {
"title": "Notifications",
"none": "Vous navez pas de notification. Passez une bonne journée !",
"explainer": "Les notifications apparaîtront ici lorsque des actions auxquelles vous êtes abonné·e se produisent.",
"markAllRead": "Mark all notifications as read",
"markAllReadSuccess": "Successfully marked all notifications as read."
"explainer": "Les notifications apparaîtront ici lorsque des actions auxquelles vous êtes abonné·e se produisent."
},
"quickActions": {
"commands": "Commandes",

View File

@ -6,16 +6,15 @@
"welcomeEvening": "Jó estét {username}!",
"lastViewed": "Utoljára megtekintve",
"addToHomeScreen": "Adja hozzá ezt az alkalmazást a kezdőképernyőhöz a gyorsabb hozzáférés és a jobb élmény érdekében.",
"goToOverview": "Go to overview",
"project": {
"importText": "Importálja projektjeit és feladatait más szolgáltatásokból a Vikunjába:",
"import": "Importálja adatait a Vikunjába"
}
},
"demo": {
"title": "Ez a példány demo módban van. Ne használja ezt valós adatokhoz!",
"everythingWillBeDeleted": "Minden törlésre kerül rendszeres időközönként!",
"accountWillBeDeleted": "Fiókja törlésre kerül, beleértve az esetlegesen létrehozott projekteket, feladatokat és mellékleteket."
"title": "This instance is in demo mode. Do not use this for real data!",
"everythingWillBeDeleted": "Everything will be deleted in regular intervals!",
"accountWillBeDeleted": "Your account will be deleted, including all projects, tasks and attachments you might create."
},
"404": {
"title": "Nem található",
@ -147,29 +146,29 @@
}
},
"apiTokens": {
"title": "API Tokenek",
"general": "Az API tokenek lehetővé teszik a Vikunja API használatát felhasználói hitelesítő adatok nélkül.",
"apiDocs": "Nézze meg az API dokumentációt",
"createAToken": "Token létrehozása",
"createToken": "Token létrehozása",
"30d": "30 nap",
"60d": "60 nap",
"90d": "90 nap",
"permissionExplanation": "Az engedélyek lehetővé teszik annak hatókörét, hogy egy API Token mire jogosult.",
"titleRequired": "A cím kötelező",
"expired": "Ez a token lejárt {ago}.",
"tokenCreatedSuccess": "Íme az új API tokenje: {token}",
"tokenCreatedNotSeeAgain": "Tárolja el biztonságos helyen, többé nem fogja látni!",
"title": "API Tokens",
"general": "API tokens allow you to use Vikunja's API without user credentials.",
"apiDocs": "Check out the api docs",
"createAToken": "Create a token",
"createToken": "Create token",
"30d": "30 Days",
"60d": "60 Days",
"90d": "90 Days",
"permissionExplanation": "Permissions allow you to scope what an api token is allowed to do.",
"titleRequired": "The title is required",
"expired": "This token has expired {ago}.",
"tokenCreatedSuccess": "Here is your new api token: {token}",
"tokenCreatedNotSeeAgain": "Store it in a secure location, you won't see it again!",
"delete": {
"header": "Token törlése",
"text1": "Biztos benne, hogy törölni akarja ezt a tokent \"{token}\"?",
"text2": "Ezzel megvonja a hozzáférést az összes ezt használó alkalmazáshoz vagy integrációhoz. Ezt nem tudod visszavonni."
"header": "Delete this token",
"text1": "Are you sure you want to delete the token \"{token}\"?",
"text2": "This will revoke access to all applications or integrations using it. You cannot undo this."
},
"attributes": {
"title": "Cím",
"titlePlaceholder": "Adjon meg egy címet, amelyet később felismer",
"expiresAt": "Lejárat ekkor",
"permissions": "Jogosultságok"
"title": "Title",
"titlePlaceholder": "Enter a title you will recognize later",
"expiresAt": "Expires at",
"permissions": "Permissions"
}
}
},
@ -177,7 +176,6 @@
"title": "Törölje Vikunja fiókját",
"text1": "Fiókjának törlése végleges, és nem vonható vissza. Töröljük az összes projektjét, feladatát és minden, ami ehhez kapcsolódik.",
"text2": "A folytatáshoz adja meg jelszavát. Kapni fog egy e-mailt a további utasításokkal.",
"text3": "A folytatáshoz kattintson az alábbi gombra. Kapni fog egy e-mailt a további utasításokkal.",
"confirm": "Fiókom törlése",
"requestSuccess": "A kérés sikeres volt. Kapni fog egy e-mailt a további utasításokkal.",
"passwordRequired": "Kérjük, írja be jelszavát.",
@ -185,7 +183,6 @@
"scheduled": "Vikunja fiókját a következő időpontban töröljük: {date} ({dateSince}).",
"scheduledCancel": "A fiók törlésének megszakításához kattintson ide.",
"scheduledCancelText": "Fiókja törlésének megszakításához adja meg jelszavát alább:",
"scheduledCancelButton": "Fiókja törlésének megszakításához kattintson az alábbi gombra:",
"scheduledCancelConfirm": "Fiókom törlésének megszakítása",
"scheduledCancelSuccess": "Fiókját nem töröljük."
},
@ -259,7 +256,7 @@
"identifier": "Projektazonosító",
"identifierPlaceholder": "Írja be a projekt projektazonosítót...",
"description": "Leírás",
"descriptionPlaceholder": "Enter a description for this project, hit '/' for more options…",
"descriptionPlaceholder": "A leírás ide kerül…",
"color": "Szín",
"success": "A projekt sikeresen frissítve."
},
@ -339,9 +336,9 @@
"doneBucketHint": "Az ebbe a csoportba helyezett összes feladat automatikusan készként lesz megjelölve.",
"doneBucketHintExtended": "A kész csoportba áthelyezett összes feladat automatikusan készként lesz megjelölve. A máshonnan elvégzettként megjelölt összes feladat is átkerül.",
"doneBucketSavedSuccess": "Az elkészült vödör sikeresen elmentve.",
"defaultBucket": "Alapértelmezett vödör",
"defaultBucketHint": "Mikor feladatokat hoz létre a vödör kiválasztása nélkül, a rendszer hozzáadja őket ehhez a vödörhöz.",
"defaultBucketSavedSuccess": "Az alapértelmezett vödör sikeresen elmentve.",
"defaultBucket": "Default bucket",
"defaultBucketHint": "When creating tasks without specifying a bucket, they will be added to this bucket.",
"defaultBucketSavedSuccess": "The default bucket has been saved successfully.",
"deleteLast": "Az utolsó vödröt nem lehet eltávolítani.",
"addTaskPlaceholder": "Adja meg az új feladatcímet…",
"addTask": "Feladat hozzáadása",
@ -360,21 +357,6 @@
"favorites": {
"title": "Kedvencek"
}
},
"webhooks": {
"title": "Webhooks",
"targetUrl": "Target URL",
"targetUrlInvalid": "Please provide a valid URL.",
"events": "Events",
"eventsHint": "Select all events this webhook should recieve updates for (within the current project).",
"mustSelectEvents": "You must select at least one event.",
"delete": "Delete this webhook",
"deleteText": "Are you sure you want to delete this webhook? External targets will not be notified of its events anymore.",
"deleteSuccess": "The webhook was successfully deleted.",
"create": "Create webhook",
"secret": "Secret",
"secretHint": "If provided, all requests to the webhook target URL will be signed using HMAC.",
"secretDocs": "Check out the docs for more details about how to use secrets."
}
},
"filters": {
@ -384,7 +366,7 @@
"title": "Cím",
"titlePlaceholder": "A mentett szűrő címe ide kerül…",
"description": "Leírás",
"descriptionPlaceholder": "Add a description for this filter here, hit '/' for more options…",
"descriptionPlaceholder": "A leírás ide kerül…",
"includeNulls": "Tartalmazza az olyan feladatokat, amelyeknek nincs beállított értéke",
"requireAll": "A feladat megjelenítéséhez minden szűrőnek igaznak kell lennie",
"showDoneTasks": "Elkészült feladatok megjelenítése",
@ -425,9 +407,7 @@
"alreadyMigrated2": "Az újbóli importálás lehetséges, de előfordulhat, hogy ismétlődések keletkeznek. Biztos ebben?",
"confirm": "Biztos vagyok benne, kezdje el a migrációt most!",
"importUpload": "Ha adatokat szeretne importálni a(z) {name} webhelyről a Vikunjába, kattintson az alábbi gombra a fájl kiválasztásához.",
"upload": "Fájl feltöltése",
"migrationStartedWillReciveEmail": "Vikunja will now import your lists/projects, tasks, notes, reminders and files from {service}. As this will take a while, we will send you an email once done. You can close this window now.",
"migrationInProgress": "A migration is currently in progress. Please wait until it is done."
"upload": "Fájl feltöltése"
},
"label": {
"title": "Címkék",
@ -498,7 +478,6 @@
"custom": "Egyéni",
"id": "Azonosító",
"created": "Létrehozva ekkor:",
"createdBy": "Created by {0}",
"actions": "Műveletek",
"cannotBeUndone": "Ezt nem lehet visszavonni!"
},
@ -517,59 +496,24 @@
"edit": "Szerkesztés",
"done": "Befejezve",
"heading1": "Címsor 1",
"heading1Tooltip": "Big section heading.",
"heading2": "Címsor 2",
"heading2Tooltip": "Medium section heading.",
"heading3": "Címsor 3",
"heading3Tooltip": "Smaller section header.",
"headingSmaller": "Kisebb címsor",
"headingBigger": "Nagyobb címsor",
"bold": "Félkövér",
"italic": "Dőlt",
"strikethrough": "Áthúzott",
"underline": "Underline",
"code": "Kód",
"codeTooltip": "Capture a code snippet.",
"quote": "Idézet",
"quoteTooltip": "Capture a quote.",
"bulletList": "Bullet list",
"bulletListTooltip": "Create a simple bullet list.",
"unorderedList": "Unordered list",
"orderedList": "Ordered list",
"orderedListTooltip": "Create a list with numbering.",
"unorderedList": "Rendezetlen lista",
"orderedList": "Rendezett lista",
"cleanBlock": "Blokk kitisztítása",
"link": "Hivatkozás",
"image": "Kép",
"imageTooltip": "Upload an image from your computer.",
"table": {
"title": "Table",
"insert": "Insert table",
"addColumnBefore": "Add column before",
"addColumnAfter": "Add column after",
"deleteColumn": "Delete column",
"addRowBefore": "Add row before",
"addRowAfter": "Add row after",
"deleteRow": "Delete row",
"deleteTable": "Delete table",
"mergeCells": "Merge cells",
"splitCell": "Split cell",
"toggleHeaderColumn": "Toggle header column",
"toggleHeaderRow": "Toggle header row",
"toggleHeaderCell": "Toggle header cell",
"mergeOrSplit": "Merge or split",
"fixTables": "Fix tables"
},
"table": "Táblázat",
"horizontalRule": "Vízszintes vonal",
"horizontalRuleTooltip": "Divide a section.",
"sideBySide": "Egymás mellett",
"guide": "Útmutató",
"text": "Text",
"textTooltip": "Just start typing with plain text.",
"taskList": "Task list",
"taskListTooltip": "Track tasks with a to-do list.",
"undo": "Undo",
"redo": "Redo",
"placeholder": "Type some text or hit '/' to see more options…"
"guide": "Útmutató"
},
"multiselect": {
"createPlaceholder": "Új létrehozása",
@ -663,9 +607,9 @@
"belongsToProject": "Ez a feladat a(z) „{project}” projekthez tartozik",
"due": "Határidő {at}",
"closePopup": "Felugró ablak bezárása",
"organization": "Szervezet",
"management": "Menedzsment",
"dateAndTime": "Dátum és idő",
"organization": "Organization",
"management": "Management",
"dateAndTime": "Date and time",
"delete": {
"header": "Feladat törlése",
"text1": "Biztos törölni akarod ezt a feladatot?",
@ -743,7 +687,7 @@
"loading": "Hozzászólások betöltése…",
"edited": "Szerkesztve: {date}",
"creating": "Hozzászólás létrehozása…",
"placeholder": "Add your comment, hit '/' for more options…",
"placeholder": "Szólj hozzá…",
"comment": "Hozzászólás",
"delete": "Hozzászólás törlése",
"deleteText1": "Biztos benne, hogy törölni akarja ezt a hozzászólást?",
@ -757,7 +701,7 @@
"1week": "1 hét"
},
"description": {
"placeholder": "Enter a description, hit '/' for more options…",
"placeholder": "Kattintson ide a leírás megadásához…",
"empty": "Nem érhető el leírás."
},
"assignee": {
@ -826,7 +770,7 @@
"repeat": {
"everyDay": "Minden nap",
"everyWeek": "Minden héten",
"every30d": "30 naponta",
"every30d": "Every 30 Days",
"mode": "Ismétlés típusa",
"monthly": "Havi",
"fromCurrentDate": "Aktuális dátumtól",
@ -908,7 +852,7 @@
"namePlaceholder": "A csapat nevét ide írja…",
"nameRequired": "Kérjük, adjon meg egy nevet.",
"description": "Leírás",
"descriptionPlaceholder": "Describe the team here, hit '/' for more options…",
"descriptionPlaceholder": "A csapat leírása ide kerül…",
"admin": "Adminisztrátor",
"member": "Tag"
}
@ -936,8 +880,7 @@
"description": "A feladatleírás szerkesztésének váltása",
"delete": "Feladat törlése",
"priority": "Módosítsa ennek a feladatnak a prioritását",
"favorite": "Jelölje meg ezt a feladatot kedvencként / nem kedvencként",
"save": "Mentse el az aktuális feladatot"
"favorite": "Jelölje meg ezt a feladatot kedvencként / nem kedvencként"
},
"project": {
"title": "Projektnézetek",
@ -975,7 +918,7 @@
"urlPlaceholder": "Például: https://localhost:3456",
"change": "csere",
"use": "A Vikunja telepítés használata itt: {0}",
"error": "Nem található, vagy nem használható a Vikunja telepítése a(z) \"{domain}\" címen. Kérjük, ellenőrizze, hogy az url formátuma megfelelő-e, és közvetlenül elérheti-e, majd próbálja újra.",
"error": "Could not find or use Vikunja installation at \"{domain}\". Please check if the url has the correct format and you can reach it when accessing it directly and try again.",
"success": "A Vikunja telepítés használata itt: {domain}",
"urlRequired": "Az URL megadása kötelező."
},
@ -987,9 +930,7 @@
"notification": {
"title": "Értesítések",
"none": "Nincsenek értesítései. Legyen szép napja!",
"explainer": "Az értesítések itt jelennek meg, amikor olyan projektek vagy feladatok történnek, amelyekre feliratkozott.",
"markAllRead": "Mark all notifications as read",
"markAllReadSuccess": "Successfully marked all notifications as read."
"explainer": "Az értesítések itt jelennek meg, amikor olyan projektek vagy feladatok történnek, amelyekre feliratkozott."
},
"quickActions": {
"commands": "Parancsok",

View File

@ -6,7 +6,6 @@
"welcomeEvening": "Buonasera {username}!",
"lastViewed": "Ultima visualizzazione",
"addToHomeScreen": "Aggiungi questa app alla tua schermata iniziale per un accesso più veloce e un'esperienza migliore.",
"goToOverview": "Go to overview",
"project": {
"importText": "Import your projects and tasks from other services into Vikunja:",
"import": "Importa i tuoi dati in Vikunja"
@ -177,7 +176,6 @@
"title": "Elimina il tuo Account Vikunja",
"text1": "The deletion of your account is permanent and cannot be undone. We will delete all your projects, tasks and everything associated with it.",
"text2": "Per continuare, inserisci la tua password. Riceverai un'e-mail con ulteriori istruzioni.",
"text3": "To proceed, please press the button below. You will receive an email with further instructions.",
"confirm": "Elimina il mio profilo",
"requestSuccess": "Richiesta riuscita. Riceverai un'e-mail con ulteriori istruzioni.",
"passwordRequired": "Inserisci la tua password.",
@ -185,7 +183,6 @@
"scheduled": "Elimineremo il tuo account Vikunja il {date} ({dateSince}).",
"scheduledCancel": "Per annullare l'eliminazione del tuo account, clicca qui.",
"scheduledCancelText": "Per annullare l'eliminazione del tuo account, inserisci la password qui sotto:",
"scheduledCancelButton": "To cancel the deletion of your account, please press the button below:",
"scheduledCancelConfirm": "Annulla l'eliminazione del mio account",
"scheduledCancelSuccess": "Non elimineremo il tuo account."
},
@ -259,7 +256,7 @@
"identifier": "Project Identifier",
"identifierPlaceholder": "The project identifier goes here…",
"description": "Descrizione",
"descriptionPlaceholder": "Enter a description for this project, hit '/' for more options…",
"descriptionPlaceholder": "Descrizione del progetto…",
"color": "Colore",
"success": "The project was successfully updated."
},
@ -360,21 +357,6 @@
"favorites": {
"title": "Favorites"
}
},
"webhooks": {
"title": "Webhooks",
"targetUrl": "Target URL",
"targetUrlInvalid": "Please provide a valid URL.",
"events": "Events",
"eventsHint": "Select all events this webhook should recieve updates for (within the current project).",
"mustSelectEvents": "You must select at least one event.",
"delete": "Delete this webhook",
"deleteText": "Are you sure you want to delete this webhook? External targets will not be notified of its events anymore.",
"deleteSuccess": "The webhook was successfully deleted.",
"create": "Create webhook",
"secret": "Secret",
"secretHint": "If provided, all requests to the webhook target URL will be signed using HMAC.",
"secretDocs": "Check out the docs for more details about how to use secrets."
}
},
"filters": {
@ -384,7 +366,7 @@
"title": "Titolo",
"titlePlaceholder": "Il titolo del filtro salvato va qui…",
"description": "Descrizione",
"descriptionPlaceholder": "Add a description for this filter here, hit '/' for more options…",
"descriptionPlaceholder": "La descrizione va qui…",
"includeNulls": "Includi attività che non hanno un valore impostato",
"requireAll": "Tutti i filtri devono essere veri affinché l'attività venga mostrata",
"showDoneTasks": "Mostra Attività Fatte",
@ -425,9 +407,7 @@
"alreadyMigrated2": "Importare di nuovo è possibile, ma potrebbe creare duplicati. Sei sicuro?",
"confirm": "Sono sicuro, per favore inizia adesso la migrazione!",
"importUpload": "Per importare i dati da {name} in Vikunja, fai clic sul pulsante qui sotto per selezionare un file.",
"upload": "Carica file",
"migrationStartedWillReciveEmail": "Vikunja will now import your lists/projects, tasks, notes, reminders and files from {service}. As this will take a while, we will send you an email once done. You can close this window now.",
"migrationInProgress": "A migration is currently in progress. Please wait until it is done."
"upload": "Carica file"
},
"label": {
"title": "Etichette",
@ -498,7 +478,6 @@
"custom": "Personalizzato",
"id": "ID",
"created": "Creato il",
"createdBy": "Created by {0}",
"actions": "Azioni",
"cannotBeUndone": "Questa azione non può essere annullata!"
},
@ -517,59 +496,24 @@
"edit": "Modifica",
"done": "Fatto",
"heading1": "Intestazione 1",
"heading1Tooltip": "Big section heading.",
"heading2": "Intestazione 2",
"heading2Tooltip": "Medium section heading.",
"heading3": "Intestazione 3",
"heading3Tooltip": "Smaller section header.",
"headingSmaller": "Intestazione Più Piccola",
"headingBigger": "Intestazione Più Grande",
"bold": "Grassetto",
"italic": "Corsivo",
"strikethrough": "Barrato",
"underline": "Underline",
"code": "Codice",
"codeTooltip": "Capture a code snippet.",
"quote": "Citazione",
"quoteTooltip": "Capture a quote.",
"bulletList": "Bullet list",
"bulletListTooltip": "Create a simple bullet list.",
"unorderedList": "Unordered list",
"orderedList": "Ordered list",
"orderedListTooltip": "Create a list with numbering.",
"unorderedList": "Elenco puntato",
"orderedList": "Ordered List",
"cleanBlock": "Pulisci Blocco",
"link": "Link",
"image": "Immagine",
"imageTooltip": "Upload an image from your computer.",
"table": {
"title": "Table",
"insert": "Insert table",
"addColumnBefore": "Add column before",
"addColumnAfter": "Add column after",
"deleteColumn": "Delete column",
"addRowBefore": "Add row before",
"addRowAfter": "Add row after",
"deleteRow": "Delete row",
"deleteTable": "Delete table",
"mergeCells": "Merge cells",
"splitCell": "Split cell",
"toggleHeaderColumn": "Toggle header column",
"toggleHeaderRow": "Toggle header row",
"toggleHeaderCell": "Toggle header cell",
"mergeOrSplit": "Merge or split",
"fixTables": "Fix tables"
},
"table": "Tabella",
"horizontalRule": "Divisore Orizzontale",
"horizontalRuleTooltip": "Divide a section.",
"sideBySide": "Affianca",
"guide": "Guida",
"text": "Text",
"textTooltip": "Just start typing with plain text.",
"taskList": "Task list",
"taskListTooltip": "Track tasks with a to-do list.",
"undo": "Undo",
"redo": "Redo",
"placeholder": "Type some text or hit '/' to see more options…"
"guide": "Guida"
},
"multiselect": {
"createPlaceholder": "Crea nuovo",
@ -743,7 +687,7 @@
"loading": "Caricamento commenti…",
"edited": "modificato il {date}",
"creating": "Creazione del commento…",
"placeholder": "Add your comment, hit '/' for more options…",
"placeholder": "Aggiungi un commento…",
"comment": "Commenta",
"delete": "Elimina questo commento",
"deleteText1": "Sei sicuro di voler eliminare questo commento?",
@ -757,7 +701,7 @@
"1week": "1 settimana"
},
"description": {
"placeholder": "Enter a description, hit '/' for more options…",
"placeholder": "Clicca qui per inserire una descrizione…",
"empty": "Nessuna descrizione."
},
"assignee": {
@ -908,7 +852,7 @@
"namePlaceholder": "Il nome del gruppo va qui…",
"nameRequired": "Specifica un nome.",
"description": "Descrizione",
"descriptionPlaceholder": "Describe the team here, hit '/' for more options…",
"descriptionPlaceholder": "La descrizione del gruppo va qui…",
"admin": "Amministratore",
"member": "Membro"
}
@ -936,8 +880,7 @@
"description": "Attiva/Disattiva modifica della descrizione dell'attività",
"delete": "Elimina questa attività",
"priority": "Modifica la priorità di questa attività",
"favorite": "Segna questa attività come preferita o non preferita",
"save": "Save the current task"
"favorite": "Segna questa attività come preferita o non preferita"
},
"project": {
"title": "Project Views",
@ -987,9 +930,7 @@
"notification": {
"title": "Notifiche",
"none": "Nessuna notifica. Buona giornata!",
"explainer": "Notifications will appear here when actions projects or tasks you subscribed to happen.",
"markAllRead": "Mark all notifications as read",
"markAllReadSuccess": "Successfully marked all notifications as read."
"explainer": "Notifications will appear here when actions projects or tasks you subscribed to happen."
},
"quickActions": {
"commands": "Comandi",

View File

@ -6,7 +6,6 @@
"welcomeEvening": "こんばんは、{username}さん",
"lastViewed": "最近の表示",
"addToHomeScreen": "Add this app to your home screen for faster access and improved experience.",
"goToOverview": "概要に移動",
"project": {
"importText": "他のサービスからVikunjaにプロジェクトやタスクをインポートします:",
"import": "Vikunjaへのデータのインポート"
@ -147,26 +146,26 @@
}
},
"apiTokens": {
"title": "APIトークン",
"title": "API Tokens",
"general": "API tokens allow you to use Vikunja's API without user credentials.",
"apiDocs": "Check out the api docs",
"createAToken": "トークンの生成",
"createToken": "トークンの生成",
"30d": "30",
"60d": "60",
"90d": "90",
"createAToken": "Create a token",
"createToken": "Create token",
"30d": "30 Days",
"60d": "60 Days",
"90d": "90 Days",
"permissionExplanation": "Permissions allow you to scope what an api token is allowed to do.",
"titleRequired": "The title is required",
"expired": "This token has expired {ago}.",
"tokenCreatedSuccess": "Here is your new api token: {token}",
"tokenCreatedNotSeeAgain": "このトークンは二度と表示されません。安全な場所に保管してください。",
"tokenCreatedNotSeeAgain": "Store it in a secure location, you won't see it again!",
"delete": {
"header": "トークンの削除",
"header": "Delete this token",
"text1": "Are you sure you want to delete the token \"{token}\"?",
"text2": "This will revoke access to all applications or integrations using it. You cannot undo this."
},
"attributes": {
"title": "トークン名",
"title": "Title",
"titlePlaceholder": "Enter a title you will recognize later",
"expiresAt": "Expires at",
"permissions": "Permissions"
@ -177,7 +176,6 @@
"title": "Vikunjaアカウントの削除",
"text1": "アカウントの削除は永久的なものであり、元に戻すことはできません。あなたのプロジェクト、タスク、それらに関連するすべてのものを削除します。",
"text2": "続行するにはパスワードを入力してください。詳しい案内の記載したメールを送信します。",
"text3": "To proceed, please press the button below. You will receive an email with further instructions.",
"confirm": "アカウントの削除",
"requestSuccess": "リクエストは成功しました。詳しい案内はメールでお知らせします。",
"passwordRequired": "パスワードを入力してください。",
@ -185,7 +183,6 @@
"scheduled": "{date} ({dateSince}) にVikunjaアカウントは削除されます。",
"scheduledCancel": "アカウントの削除を取り消す場合はこちらをご覧ください。",
"scheduledCancelText": "アカウントの削除を取り消すにはパスワードを入力してください:",
"scheduledCancelButton": "To cancel the deletion of your account, please press the button below:",
"scheduledCancelConfirm": "アカウント削除の取り消し",
"scheduledCancelSuccess": "アカウント削除は行われません。"
},
@ -259,7 +256,7 @@
"identifier": "プロジェクトID",
"identifierPlaceholder": "プロジェクトIDを入力…",
"description": "説明",
"descriptionPlaceholder": "Enter a description for this project, hit '/' for more options…",
"descriptionPlaceholder": "プロジェクトの説明を入力…",
"color": "色",
"success": "プロジェクトは正常に更新されました。"
},
@ -335,23 +332,23 @@
"title": "カンバン",
"limit": "Limit: {limit}",
"noLimit": "未設定",
"doneBucket": "バケットを完了",
"doneBucket": "Done bucket",
"doneBucketHint": "All tasks moved into this bucket will automatically marked as done.",
"doneBucketHintExtended": "All tasks moved into the done bucket will be marked as done automatically. All tasks marked as done from elsewhere will be moved as well.",
"doneBucketSavedSuccess": "The done bucket has been saved successfully.",
"defaultBucket": "デフォルトのバケット",
"defaultBucket": "Default bucket",
"defaultBucketHint": "When creating tasks without specifying a bucket, they will be added to this bucket.",
"defaultBucketSavedSuccess": "The default bucket has been saved successfully.",
"deleteLast": "You cannot remove the last bucket.",
"addTaskPlaceholder": "新しいタスク名を入力…",
"addTaskPlaceholder": "Enter the new task title…",
"addTask": "タスクの追加",
"addAnotherTask": "他のタスクを追加",
"addBucket": "新しいバケットの作成",
"addBucketPlaceholder": "新しいバケット名を入力…",
"deleteHeaderBucket": "バケットの削除",
"deleteBucketText1": "このバケットを削除して本当によろしいですか?",
"addBucket": "Create a new bucket",
"addBucketPlaceholder": "Enter the new bucket title…",
"deleteHeaderBucket": "Delete the bucket",
"deleteBucketText1": "Are you sure you want to delete this bucket?",
"deleteBucketText2": "This will not delete any tasks but move them into the default bucket.",
"deleteBucketSuccess": "バケットは正常に削除されました。",
"deleteBucketSuccess": "The bucket has been deleted successfully.",
"bucketTitleSavedSuccess": "The bucket title has been saved successfully.",
"bucketLimitSavedSuccess": "The bucket limit been saved successfully.",
"collapse": "Collapse this bucket"
@ -360,21 +357,6 @@
"favorites": {
"title": "お気に入り"
}
},
"webhooks": {
"title": "Webhook",
"targetUrl": "Target URL",
"targetUrlInvalid": "Please provide a valid URL.",
"events": "Events",
"eventsHint": "Select all events this webhook should recieve updates for (within the current project).",
"mustSelectEvents": "You must select at least one event.",
"delete": "Webhookの削除",
"deleteText": "Are you sure you want to delete this webhook? External targets will not be notified of its events anymore.",
"deleteSuccess": "Webhookは正常に削除されました。",
"create": "Create webhook",
"secret": "Secret",
"secretHint": "If provided, all requests to the webhook target URL will be signed using HMAC.",
"secretDocs": "Check out the docs for more details about how to use secrets."
}
},
"filters": {
@ -384,7 +366,7 @@
"title": "絞り込み条件名",
"titlePlaceholder": "絞り込み条件名を入力…",
"description": "説明",
"descriptionPlaceholder": "Add a description for this filter here, hit '/' for more options…",
"descriptionPlaceholder": "絞り込み条件の説明を入力…",
"includeNulls": "値が設定されていないタスクを含める",
"requireAll": "すべての条件に一致するタスクのみ表示",
"showDoneTasks": "完了したタスクを表示",
@ -425,9 +407,7 @@
"alreadyMigrated2": "再びインポートすることも可能ですが、重複する可能性があります。インポートして本当によろしいですか?",
"confirm": "了解!インポート開始なのだ!",
"importUpload": "{name}からVikunjaにデータをインポートするには、以下のボタンをクリックしてファイルを選択してください。",
"upload": "ファイルのアップロード",
"migrationStartedWillReciveEmail": "Vikunja will now import your lists/projects, tasks, notes, reminders and files from {service}. As this will take a while, we will send you an email once done. You can close this window now.",
"migrationInProgress": "A migration is currently in progress. Please wait until it is done."
"upload": "ファイルのアップロード"
},
"label": {
"title": "ラベル",
@ -498,7 +478,6 @@
"custom": "カスタム",
"id": "ID",
"created": "Created at",
"createdBy": "Created by {0}",
"actions": "Actions",
"cannotBeUndone": "この操作は元に戻せません!"
},
@ -517,59 +496,24 @@
"edit": "編集",
"done": "完了",
"heading1": "見出し1",
"heading1Tooltip": "Big section heading.",
"heading2": "見出し2",
"heading2Tooltip": "Medium section heading.",
"heading3": "見出し3",
"heading3Tooltip": "Smaller section header.",
"headingSmaller": "見出しを小さくする",
"headingBigger": "見出しを大きくする",
"bold": "太字",
"italic": "斜体",
"strikethrough": "打ち消し線",
"underline": "下線",
"code": "コード",
"codeTooltip": "Capture a code snippet.",
"quote": "引用",
"quoteTooltip": "Capture a quote.",
"bulletList": "順序なしリスト",
"bulletListTooltip": "Create a simple bullet list.",
"unorderedList": "順序なしリスト",
"orderedList": "順序付きリスト",
"orderedListTooltip": "Create a list with numbering.",
"cleanBlock": "Clean Block",
"link": "リンク",
"image": "画像",
"imageTooltip": "Upload an image from your computer.",
"table": {
"title": "テーブル",
"insert": "テーブルの挿入",
"addColumnBefore": "Add column before",
"addColumnAfter": "Add column after",
"deleteColumn": "列の削除",
"addRowBefore": "Add row before",
"addRowAfter": "Add row after",
"deleteRow": "行の削除",
"deleteTable": "テーブルの削除",
"mergeCells": "セルの統合",
"splitCell": "セルの分割",
"toggleHeaderColumn": "Toggle header column",
"toggleHeaderRow": "Toggle header row",
"toggleHeaderCell": "Toggle header cell",
"mergeOrSplit": "Merge or split",
"fixTables": "テーブルの修正"
},
"table": "テーブル",
"horizontalRule": "横罫",
"horizontalRuleTooltip": "Divide a section.",
"sideBySide": "Side By Side",
"guide": "説明書",
"text": "テキスト",
"textTooltip": "Just start typing with plain text.",
"taskList": "タスクリスト",
"taskListTooltip": "Track tasks with a to-do list.",
"undo": "元に戻す",
"redo": "やり直す",
"placeholder": "Type some text or hit '/' to see more options…"
"guide": "説明書"
},
"multiselect": {
"createPlaceholder": "新規作成",
@ -665,7 +609,7 @@
"closePopup": "閉じる",
"organization": "Organization",
"management": "Management",
"dateAndTime": "日付と時刻",
"dateAndTime": "Date and time",
"delete": {
"header": "タスクの削除",
"text1": "このタスクを削除して本当によろしいですか?",
@ -743,7 +687,7 @@
"loading": "コメントを読み込み中…",
"edited": "edited {date}",
"creating": "コメントを作成中…",
"placeholder": "Add your comment, hit '/' for more options…",
"placeholder": "コメントを追加…",
"comment": "コメント",
"delete": "コメントの削除",
"deleteText1": "このコメントを削除して本当によろしいですか?",
@ -757,7 +701,7 @@
"1week": "1週間後"
},
"description": {
"placeholder": "Enter a description, hit '/' for more options…",
"placeholder": "説明を入力…",
"empty": "説明文はありません。"
},
"assignee": {
@ -797,7 +741,7 @@
"delete": "関連タスクの削除",
"deleteText1": "この関連タスクを削除して本当によろしいですか?",
"select": "Select a relation kind",
"taskRequired": "タスクを選択するか、新しいタスク名を入力してください。",
"taskRequired": "Please select a task or enter a new task title.",
"kinds": {
"subtask": "サブタスク",
"parenttask": "親タスク",
@ -826,7 +770,7 @@
"repeat": {
"everyDay": "毎日",
"everyWeek": "毎週",
"every30d": "30日ごと",
"every30d": "Every 30 Days",
"mode": "繰り返しモード",
"monthly": "毎月",
"fromCurrentDate": "現在時刻からの間隔",
@ -844,7 +788,7 @@
"title": "Quick Add Magic",
"intro": "When creating a task, you can use special keywords to directly add attributes to the newly created task. This allows to add commonly used attributes to tasks much faster.",
"multiple": "You can use this multiple times.",
"label1": "ラベルを付けるには、ラベル名の前に {prefix} を入力します。",
"label1": "To add a label, simply prefix the name of the label with {prefix}.",
"label2": "Vikunja will first check if the label already exist and create it if not.",
"label3": "To use spaces, simply add a \" or ' around the label name.",
"label4": "For example: {prefix}\"Label with spaces\".",
@ -894,7 +838,7 @@
"header": "Remove a user from the team",
"text1": "Are you sure you want to remove this user from the team?",
"text2": "They will lose access to all projects this team has access to. This CANNOT BE UNDONE!",
"success": "ユーザーは正常にチームから削除されました。"
"success": "The user was successfully deleted from the team."
},
"leave": {
"title": "Leave team",
@ -908,7 +852,7 @@
"namePlaceholder": "The team's name goes here…",
"nameRequired": "Please specify a name.",
"description": "説明",
"descriptionPlaceholder": "Describe the team here, hit '/' for more options…",
"descriptionPlaceholder": "チームの説明を入力…",
"admin": "管理者",
"member": "メンバー"
}
@ -936,8 +880,7 @@
"description": "タスクの説明を編集",
"delete": "タスクを削除",
"priority": "タスクの優先度を設定",
"favorite": "タスクをお気に入りに追加/削除",
"save": "Save the current task"
"favorite": "タスクをお気に入りに追加/削除"
},
"project": {
"title": "プロジェクト",
@ -987,9 +930,7 @@
"notification": {
"title": "通知",
"none": "通知はありません。それではよい一日を!",
"explainer": "購読しているプロジェクトやタスクが変更されると通知されます。",
"markAllRead": "Mark all notifications as read",
"markAllReadSuccess": "Successfully marked all notifications as read."
"explainer": "購読しているプロジェクトやタスクが変更されると通知されます。"
},
"quickActions": {
"commands": "コマンド",
@ -998,7 +939,7 @@
"tasks": "タスク",
"projects": "プロジェクト",
"teams": "チーム",
"labels": "ラベル",
"labels": "Labels",
"newProject": "新しいプロジェクト名を入力…",
"newTask": "新しいタスク名を入力…",
"newTeam": "新しいチーム名を入力…",
@ -1074,12 +1015,12 @@
"8002": "そのラベルは存在しません。",
"8003": "You do not have access to this label.",
"9001": "The right is invalid.",
"10001": "そのバケットは存在しません。",
"10001": "The bucket does not exist.",
"10002": "The bucket does not belong to that project.",
"10003": "You cannot remove the last bucket on a project.",
"10004": "You cannot add the task to this bucket as it already exceeded the limit of tasks it can hold.",
"10005": "There can be only one done bucket per project.",
"11001": "その絞り込み条件は存在しません。",
"11001": "The saved filter does not exist.",
"11002": "絞り込み条件はリンクの共有には使用できません。",
"12001": "The subscription entity type is invalid.",
"12002": "You are already subscribed to the entity itself or a parent entity.",

View File

@ -6,7 +6,6 @@
"welcomeEvening": " 오늘 하루는 어땠나요? {username} 님!",
"lastViewed": "최근에 본 것",
"addToHomeScreen": "더 빠른 액세스와 향상된 경험을 위해 이 앱을 홈 화면에 추가하세요.",
"goToOverview": "Go to overview",
"project": {
"importText": "다른 서비스의 프로젝트 및 작업을 Vikunja로 가져옵니다.",
"import": "데이터를 Vikunja로 가져오기"
@ -177,7 +176,6 @@
"title": "계정 삭제",
"text1": "The deletion of your account is permanent and cannot be undone. We will delete all your projects, tasks and everything associated with it.",
"text2": "To proceed, please enter your password. You will receive an email with further instructions.",
"text3": "To proceed, please press the button below. You will receive an email with further instructions.",
"confirm": "계정을 삭제하시겠습니까?",
"requestSuccess": "The request was successful. You'll receive an email with further instructions.",
"passwordRequired": "비밀번호를 입력하십시오.",
@ -185,7 +183,6 @@
"scheduled": "We will delete your Vikunja account at {date} ({dateSince}).",
"scheduledCancel": "To cancel the deletion of your account, click here.",
"scheduledCancelText": "To cancel the deletion of your account, please enter your password below:",
"scheduledCancelButton": "To cancel the deletion of your account, please press the button below:",
"scheduledCancelConfirm": "Cancel the deletion of my account",
"scheduledCancelSuccess": "We will not delete your account."
},
@ -259,7 +256,7 @@
"identifier": "Project Identifier",
"identifierPlaceholder": "The project identifier goes here…",
"description": "설명",
"descriptionPlaceholder": "Enter a description for this project, hit '/' for more options…",
"descriptionPlaceholder": "프로젝트 상세설명은 여기에…",
"color": "색상",
"success": "프로젝트가 성공적으로 업데이트되었습니다."
},
@ -360,21 +357,6 @@
"favorites": {
"title": "즐겨찾기"
}
},
"webhooks": {
"title": "Webhooks",
"targetUrl": "Target URL",
"targetUrlInvalid": "Please provide a valid URL.",
"events": "Events",
"eventsHint": "Select all events this webhook should recieve updates for (within the current project).",
"mustSelectEvents": "You must select at least one event.",
"delete": "Delete this webhook",
"deleteText": "Are you sure you want to delete this webhook? External targets will not be notified of its events anymore.",
"deleteSuccess": "The webhook was successfully deleted.",
"create": "Create webhook",
"secret": "Secret",
"secretHint": "If provided, all requests to the webhook target URL will be signed using HMAC.",
"secretDocs": "Check out the docs for more details about how to use secrets."
}
},
"filters": {
@ -384,7 +366,7 @@
"title": "제목",
"titlePlaceholder": "The saved filter title goes here…",
"description": "상세정보",
"descriptionPlaceholder": "Add a description for this filter here, hit '/' for more options…",
"descriptionPlaceholder": "The description goes here…",
"includeNulls": "Include Tasks which don't have a value set",
"requireAll": "Require all filters to be true for a task to show up",
"showDoneTasks": "완료한 목록 표시",
@ -425,9 +407,7 @@
"alreadyMigrated2": "Importing again is possible, but might create duplicates. Are you sure?",
"confirm": "I am sure, please start migrating now!",
"importUpload": "To import data from {name} into Vikunja, click the button below to select a file.",
"upload": "Upload file",
"migrationStartedWillReciveEmail": "Vikunja will now import your lists/projects, tasks, notes, reminders and files from {service}. As this will take a while, we will send you an email once done. You can close this window now.",
"migrationInProgress": "A migration is currently in progress. Please wait until it is done."
"upload": "Upload file"
},
"label": {
"title": "Labels",
@ -498,7 +478,6 @@
"custom": "Custom",
"id": "ID",
"created": "Created at",
"createdBy": "Created by {0}",
"actions": "Actions",
"cannotBeUndone": "This cannot be undone!"
},
@ -517,59 +496,24 @@
"edit": "Edit",
"done": "Done",
"heading1": "Heading 1",
"heading1Tooltip": "Big section heading.",
"heading2": "Heading 2",
"heading2Tooltip": "Medium section heading.",
"heading3": "Heading 3",
"heading3Tooltip": "Smaller section header.",
"headingSmaller": "Heading Smaller",
"headingBigger": "Heading Bigger",
"bold": "굵게",
"italic": "Italic",
"strikethrough": "Strikethrough",
"underline": "Underline",
"code": "코드",
"codeTooltip": "Capture a code snippet.",
"quote": "인용",
"quoteTooltip": "Capture a quote.",
"bulletList": "Bullet list",
"bulletListTooltip": "Create a simple bullet list.",
"unorderedList": "Unordered list",
"orderedList": "Ordered list",
"orderedListTooltip": "Create a list with numbering.",
"unorderedList": "Unordered List",
"orderedList": "Ordered List",
"cleanBlock": "블록 지우기",
"link": "링크",
"image": "이미지",
"imageTooltip": "Upload an image from your computer.",
"table": {
"title": "Table",
"insert": "Insert table",
"addColumnBefore": "Add column before",
"addColumnAfter": "Add column after",
"deleteColumn": "Delete column",
"addRowBefore": "Add row before",
"addRowAfter": "Add row after",
"deleteRow": "Delete row",
"deleteTable": "Delete table",
"mergeCells": "Merge cells",
"splitCell": "Split cell",
"toggleHeaderColumn": "Toggle header column",
"toggleHeaderRow": "Toggle header row",
"toggleHeaderCell": "Toggle header cell",
"mergeOrSplit": "Merge or split",
"fixTables": "Fix tables"
},
"table": "표",
"horizontalRule": "Horizontal Rule",
"horizontalRuleTooltip": "Divide a section.",
"sideBySide": "Side By Side",
"guide": "가이드",
"text": "Text",
"textTooltip": "Just start typing with plain text.",
"taskList": "Task list",
"taskListTooltip": "Track tasks with a to-do list.",
"undo": "Undo",
"redo": "Redo",
"placeholder": "Type some text or hit '/' to see more options…"
"guide": "가이드"
},
"multiselect": {
"createPlaceholder": "새로 생성하기",
@ -743,7 +687,7 @@
"loading": "Loading comments…",
"edited": "{date} 에 수정함",
"creating": "의견 작성 중...",
"placeholder": "Add your comment, hit '/' for more options…",
"placeholder": "Add your comment…",
"comment": "의견",
"delete": "의견 삭제",
"deleteText1": "의견을 삭제하시겠습니까?",
@ -757,7 +701,7 @@
"1week": "1 주"
},
"description": {
"placeholder": "Enter a description, hit '/' for more options…",
"placeholder": "설명을 입력하려면 클릭하십시오...",
"empty": "설명이 없습니다."
},
"assignee": {
@ -908,7 +852,7 @@
"namePlaceholder": "The team's name goes here…",
"nameRequired": "Please specify a name.",
"description": "Description",
"descriptionPlaceholder": "Describe the team here, hit '/' for more options…",
"descriptionPlaceholder": "The teams description goes here…",
"admin": "Admin",
"member": "Member"
}
@ -936,8 +880,7 @@
"description": "Toggle editing of the task description",
"delete": "Delete this task",
"priority": "Change the priority of this task",
"favorite": "Mark this task as favorite / unfavorite",
"save": "Save the current task"
"favorite": "Mark this task as favorite / unfavorite"
},
"project": {
"title": "Project Views",
@ -987,9 +930,7 @@
"notification": {
"title": "Notifications",
"none": "You don't have any notifications. Have a nice day!",
"explainer": "Notifications will appear here when actions projects or tasks you subscribed to happen.",
"markAllRead": "Mark all notifications as read",
"markAllReadSuccess": "Successfully marked all notifications as read."
"explainer": "Notifications will appear here when actions projects or tasks you subscribed to happen."
},
"quickActions": {
"commands": "Commands",

View File

@ -6,7 +6,6 @@
"welcomeEvening": "Good Evening {username}!",
"lastViewed": "Laatst bekeken",
"addToHomeScreen": "Add this app to your home screen for faster access and improved experience.",
"goToOverview": "Go to overview",
"project": {
"importText": "Import your projects and tasks from other services into Vikunja:",
"import": "Import your data into Vikunja"
@ -177,7 +176,6 @@
"title": "Verwijder je Vikunja account",
"text1": "The deletion of your account is permanent and cannot be undone. We will delete all your projects, tasks and everything associated with it.",
"text2": "Graag je wachtwoord invullen om verder te gaan. Je zult een e-mail ontvangen met verdere instructies.",
"text3": "To proceed, please press the button below. You will receive an email with further instructions.",
"confirm": "Verwijder mijn account",
"requestSuccess": "Het verzoek was succesvol. Je ontvangt een e-mail met verdere instructies.",
"passwordRequired": "Voer alsjeblieft je wachtwoord in.",
@ -185,7 +183,6 @@
"scheduled": "We zullen je Vikunja account op {date} ({dateSince}) verwijderen.",
"scheduledCancel": "Klik hier om de verwijdering van je account te annuleren.",
"scheduledCancelText": "To cancel the deletion of your account, please enter your password below:",
"scheduledCancelButton": "To cancel the deletion of your account, please press the button below:",
"scheduledCancelConfirm": "Annuleer de verwijdering van mijn account",
"scheduledCancelSuccess": "We zullen je account niet verwijderen."
},
@ -259,7 +256,7 @@
"identifier": "Project Identifier",
"identifierPlaceholder": "The project identifier goes here…",
"description": "Description",
"descriptionPlaceholder": "Enter a description for this project, hit '/' for more options…",
"descriptionPlaceholder": "The projects description goes here…",
"color": "Color",
"success": "The project was successfully updated."
},
@ -360,21 +357,6 @@
"favorites": {
"title": "Favorites"
}
},
"webhooks": {
"title": "Webhooks",
"targetUrl": "Target URL",
"targetUrlInvalid": "Please provide a valid URL.",
"events": "Events",
"eventsHint": "Select all events this webhook should recieve updates for (within the current project).",
"mustSelectEvents": "You must select at least one event.",
"delete": "Delete this webhook",
"deleteText": "Are you sure you want to delete this webhook? External targets will not be notified of its events anymore.",
"deleteSuccess": "The webhook was successfully deleted.",
"create": "Create webhook",
"secret": "Secret",
"secretHint": "If provided, all requests to the webhook target URL will be signed using HMAC.",
"secretDocs": "Check out the docs for more details about how to use secrets."
}
},
"filters": {
@ -384,7 +366,7 @@
"title": "Titel",
"titlePlaceholder": "The saved filter title goes here…",
"description": "Beschrijving",
"descriptionPlaceholder": "Add a description for this filter here, hit '/' for more options…",
"descriptionPlaceholder": "De beschrijving komt hier…",
"includeNulls": "Include Tasks which don't have a value set",
"requireAll": "Require all filters to be true for a task to show up",
"showDoneTasks": "Show Done Tasks",
@ -425,9 +407,7 @@
"alreadyMigrated2": "Importing again is possible, but might create duplicates. Are you sure?",
"confirm": "Ik weet het zeker, begin nu met migreren!",
"importUpload": "To import data from {name} into Vikunja, click the button below to select a file.",
"upload": "Bestand uploaden",
"migrationStartedWillReciveEmail": "Vikunja will now import your lists/projects, tasks, notes, reminders and files from {service}. As this will take a while, we will send you an email once done. You can close this window now.",
"migrationInProgress": "A migration is currently in progress. Please wait until it is done."
"upload": "Bestand uploaden"
},
"label": {
"title": "Labels",
@ -498,7 +478,6 @@
"custom": "Custom",
"id": "ID",
"created": "Created at",
"createdBy": "Created by {0}",
"actions": "Actions",
"cannotBeUndone": "This cannot be undone!"
},
@ -517,59 +496,24 @@
"edit": "Bewerken",
"done": "Voltooid",
"heading1": "Kop 1",
"heading1Tooltip": "Big section heading.",
"heading2": "Kop 2",
"heading2Tooltip": "Medium section heading.",
"heading3": "Kop 3",
"heading3Tooltip": "Smaller section header.",
"headingSmaller": "Heading Smaller",
"headingBigger": "Heading Bigger",
"bold": "Dikgedrukt",
"italic": "Cursief",
"strikethrough": "Doorgestreept",
"underline": "Underline",
"code": "Code",
"codeTooltip": "Capture a code snippet.",
"quote": "Citaat",
"quoteTooltip": "Capture a quote.",
"bulletList": "Bullet list",
"bulletListTooltip": "Create a simple bullet list.",
"unorderedList": "Unordered list",
"orderedList": "Ordered list",
"orderedListTooltip": "Create a list with numbering.",
"unorderedList": "Ongesorteerde lijst",
"orderedList": "Ordered List",
"cleanBlock": "Clean Block",
"link": "Link",
"image": "Afbeelding",
"imageTooltip": "Upload an image from your computer.",
"table": {
"title": "Table",
"insert": "Insert table",
"addColumnBefore": "Add column before",
"addColumnAfter": "Add column after",
"deleteColumn": "Delete column",
"addRowBefore": "Add row before",
"addRowAfter": "Add row after",
"deleteRow": "Delete row",
"deleteTable": "Delete table",
"mergeCells": "Merge cells",
"splitCell": "Split cell",
"toggleHeaderColumn": "Toggle header column",
"toggleHeaderRow": "Toggle header row",
"toggleHeaderCell": "Toggle header cell",
"mergeOrSplit": "Merge or split",
"fixTables": "Fix tables"
},
"table": "Tabel",
"horizontalRule": "Horizontale lijn",
"horizontalRuleTooltip": "Divide a section.",
"sideBySide": "Naast elkaar",
"guide": "Handleiding",
"text": "Text",
"textTooltip": "Just start typing with plain text.",
"taskList": "Task list",
"taskListTooltip": "Track tasks with a to-do list.",
"undo": "Undo",
"redo": "Redo",
"placeholder": "Type some text or hit '/' to see more options…"
"guide": "Handleiding"
},
"multiselect": {
"createPlaceholder": "Nieuwe aanmaken",
@ -743,7 +687,7 @@
"loading": "Bezig met laden van reacties…",
"edited": "edited {date}",
"creating": "Creating comment…",
"placeholder": "Add your comment, hit '/' for more options…",
"placeholder": "Add your comment…",
"comment": "Reactie",
"delete": "Verwijder deze reactie",
"deleteText1": "Weet je zeker dat je deze reactie wilt verwijderen?",
@ -757,7 +701,7 @@
"1week": "1 week"
},
"description": {
"placeholder": "Enter a description, hit '/' for more options…",
"placeholder": "Klik hier om een beschrijving in te voeren…",
"empty": "Nog geen beschrijving beschikbaar."
},
"assignee": {
@ -908,7 +852,7 @@
"namePlaceholder": "The team's name goes here…",
"nameRequired": "Please specify a name.",
"description": "Beschrijving",
"descriptionPlaceholder": "Describe the team here, hit '/' for more options…",
"descriptionPlaceholder": "The teams description goes here…",
"admin": "Beheerder",
"member": "Lid"
}
@ -936,8 +880,7 @@
"description": "Toggle editing of the task description",
"delete": "Delete this task",
"priority": "Change the priority of this task",
"favorite": "Mark this task as favorite / unfavorite",
"save": "Save the current task"
"favorite": "Mark this task as favorite / unfavorite"
},
"project": {
"title": "Project Views",
@ -987,9 +930,7 @@
"notification": {
"title": "Notificaties",
"none": "Je hebt geen meldingen. Fijne dag!",
"explainer": "Notifications will appear here when actions projects or tasks you subscribed to happen.",
"markAllRead": "Mark all notifications as read",
"markAllReadSuccess": "Successfully marked all notifications as read."
"explainer": "Notifications will appear here when actions projects or tasks you subscribed to happen."
},
"quickActions": {
"commands": "Commands",

View File

@ -6,7 +6,6 @@
"welcomeEvening": "God Morgen {username}!",
"lastViewed": "Sist sett",
"addToHomeScreen": "Add this app to your home screen for faster access and improved experience.",
"goToOverview": "Go to overview",
"project": {
"importText": "Import your projects and tasks from other services into Vikunja:",
"import": "Importer dine data til Vikunja"
@ -177,7 +176,6 @@
"title": "Slett kontoen din",
"text1": "The deletion of your account is permanent and cannot be undone. We will delete all your projects, tasks and everything associated with it.",
"text2": "For å fortsette, skriv inn passordet ditt. Du vil motta en e-post med ytterligere instruksjoner.",
"text3": "To proceed, please press the button below. You will receive an email with further instructions.",
"confirm": "Slett min konto",
"requestSuccess": "Forespørselen var vellykket. Du vil motta en e-post med ytterligere instruksjoner.",
"passwordRequired": "Skriv inn ditt passord.",
@ -185,7 +183,6 @@
"scheduled": "Vi vil slette din Vikunja konto den {date} ({dateSince}).",
"scheduledCancel": "For å avbryte slettingen av kontoen din, klikk her.",
"scheduledCancelText": "For å avbryte slettingen av kontoen din, skriv inn passordet under:",
"scheduledCancelButton": "To cancel the deletion of your account, please press the button below:",
"scheduledCancelConfirm": "Avbryt slettingen av kontoen min",
"scheduledCancelSuccess": "Vi vil ikke slette din konto."
},
@ -259,7 +256,7 @@
"identifier": "Prosjekt identifikator",
"identifierPlaceholder": "Prosjektidentifikatoren kommer her…",
"description": "Beskrivelse",
"descriptionPlaceholder": "Enter a description for this project, hit '/' for more options…",
"descriptionPlaceholder": "Beskrivelsen gis her…",
"color": "Farger",
"success": "Prosjektet ble opprettet."
},
@ -360,21 +357,6 @@
"favorites": {
"title": "Favoritter"
}
},
"webhooks": {
"title": "Webhooks",
"targetUrl": "Target URL",
"targetUrlInvalid": "Please provide a valid URL.",
"events": "Events",
"eventsHint": "Select all events this webhook should recieve updates for (within the current project).",
"mustSelectEvents": "You must select at least one event.",
"delete": "Delete this webhook",
"deleteText": "Are you sure you want to delete this webhook? External targets will not be notified of its events anymore.",
"deleteSuccess": "The webhook was successfully deleted.",
"create": "Create webhook",
"secret": "Secret",
"secretHint": "If provided, all requests to the webhook target URL will be signed using HMAC.",
"secretDocs": "Check out the docs for more details about how to use secrets."
}
},
"filters": {
@ -384,7 +366,7 @@
"title": "Tittel",
"titlePlaceholder": "Den lagrede filtertittelen kommer hit…",
"description": "Beskrivelse",
"descriptionPlaceholder": "Add a description for this filter here, hit '/' for more options…",
"descriptionPlaceholder": "Beskrivelsen gis her…",
"includeNulls": "Inkluder oppgaver som ikke har en verdi satt",
"requireAll": "Krev at alle filtre er oppfylt for at en oppgave skal vises",
"showDoneTasks": "Vis utførte oppgaver",
@ -425,9 +407,7 @@
"alreadyMigrated2": "Importering på nytt er mulig, men kan skape duplikater. Er du sikker?",
"confirm": "Jeg er sikker, vennligst begynn å migrere nå!",
"importUpload": "For å importere data fra {name} til Vikunja, klikk på knappen nedenfor for å velge en fil.",
"upload": "Last opp fil",
"migrationStartedWillReciveEmail": "Vikunja will now import your lists/projects, tasks, notes, reminders and files from {service}. As this will take a while, we will send you an email once done. You can close this window now.",
"migrationInProgress": "A migration is currently in progress. Please wait until it is done."
"upload": "Last opp fil"
},
"label": {
"title": "Etiketter",
@ -498,7 +478,6 @@
"custom": "Egendefinert",
"id": "Id",
"created": "Opprettet",
"createdBy": "Created by {0}",
"actions": "Handlinger",
"cannotBeUndone": "Dette kan ikke angres!"
},
@ -517,59 +496,24 @@
"edit": "Edit",
"done": "Ferdig",
"heading1": "Overskrift 1",
"heading1Tooltip": "Big section heading.",
"heading2": "Overskrift 2",
"heading2Tooltip": "Medium section heading.",
"heading3": "Overskrift 3",
"heading3Tooltip": "Smaller section header.",
"headingSmaller": "Overskrift mindre",
"headingBigger": "Overskrift større",
"bold": "Fet",
"italic": "Kursiv",
"strikethrough": "Gjennomstrekning",
"underline": "Underline",
"code": "Kode",
"codeTooltip": "Capture a code snippet.",
"quote": "Sitat",
"quoteTooltip": "Capture a quote.",
"bulletList": "Bullet list",
"bulletListTooltip": "Create a simple bullet list.",
"unorderedList": "Unordered list",
"orderedList": "Ordered list",
"orderedListTooltip": "Create a list with numbering.",
"unorderedList": "Uordnet liste",
"orderedList": "Sortert liste",
"cleanBlock": "Tøm blokk",
"link": "Link",
"image": "Bilde",
"imageTooltip": "Upload an image from your computer.",
"table": {
"title": "Table",
"insert": "Insert table",
"addColumnBefore": "Add column before",
"addColumnAfter": "Add column after",
"deleteColumn": "Delete column",
"addRowBefore": "Add row before",
"addRowAfter": "Add row after",
"deleteRow": "Delete row",
"deleteTable": "Delete table",
"mergeCells": "Merge cells",
"splitCell": "Split cell",
"toggleHeaderColumn": "Toggle header column",
"toggleHeaderRow": "Toggle header row",
"toggleHeaderCell": "Toggle header cell",
"mergeOrSplit": "Merge or split",
"fixTables": "Fix tables"
},
"table": "Tabell",
"horizontalRule": "Vannrett linje",
"horizontalRuleTooltip": "Divide a section.",
"sideBySide": "Side ved side",
"guide": "Guide",
"text": "Text",
"textTooltip": "Just start typing with plain text.",
"taskList": "Task list",
"taskListTooltip": "Track tasks with a to-do list.",
"undo": "Undo",
"redo": "Redo",
"placeholder": "Type some text or hit '/' to see more options…"
"guide": "Guide"
},
"multiselect": {
"createPlaceholder": "Opprett ny",
@ -743,7 +687,7 @@
"loading": "Laster inn kommenterer…",
"edited": "redigert {date}",
"creating": "Lager kommentar…",
"placeholder": "Add your comment, hit '/' for more options…",
"placeholder": "Legg inn din kommentar…",
"comment": "Kommentar",
"delete": "Slett denne kommentaren",
"deleteText1": "Er du sikker på at du vil slette denne kommentaren?",
@ -757,7 +701,7 @@
"1week": "1 uke"
},
"description": {
"placeholder": "Enter a description, hit '/' for more options…",
"placeholder": "Klikk for å legge inn en beskrivelse…",
"empty": "Ingen beskrivelse tilgjengelig."
},
"assignee": {
@ -908,7 +852,7 @@
"namePlaceholder": "Gruppens navn går her…",
"nameRequired": "Angi et navn.",
"description": "Beskrivelse",
"descriptionPlaceholder": "Describe the team here, hit '/' for more options…",
"descriptionPlaceholder": "Beskrivelsen gis her…",
"admin": "Administrator",
"member": "Medlem"
}
@ -936,8 +880,7 @@
"description": "Veksle redigering av oppgavebeskrivelsen",
"delete": "Delete this task",
"priority": "Change the priority of this task",
"favorite": "Mark this task as favorite / unfavorite",
"save": "Save the current task"
"favorite": "Mark this task as favorite / unfavorite"
},
"project": {
"title": "Prosjektvisning",
@ -987,9 +930,7 @@
"notification": {
"title": "Varsler",
"none": "Du har ingen varsler på dette tidspunktet!",
"explainer": "Notifications will appear here when actions projects or tasks you subscribed to happen.",
"markAllRead": "Mark all notifications as read",
"markAllReadSuccess": "Successfully marked all notifications as read."
"explainer": "Notifications will appear here when actions projects or tasks you subscribed to happen."
},
"quickActions": {
"commands": "Kommandoer",

View File

@ -1,21 +1,20 @@
{
"home": {
"welcomeNight": "Dobry wieczór {username}!",
"welcomeMorning": "Dzień dobry {username}!",
"welcomeDay": "Hej {username}!",
"welcomeEvening": "Dobry wieczór {username}!",
"welcomeNight": "Good Night {username}!",
"welcomeMorning": "Good Morning {username}!",
"welcomeDay": "Hi {username}!",
"welcomeEvening": "Good Evening {username}!",
"lastViewed": "Ostatnio oglądane",
"addToHomeScreen": "Dodaj tę aplikację do ekranu głównego, aby uzyskać szybszy dostęp i lepsze wrażenia.",
"goToOverview": "Przejdź do podsumowania",
"addToHomeScreen": "Add this app to your home screen for faster access and improved experience.",
"project": {
"importText": "Importuj swoje projekty i zadania z innych usług do Vikunja:",
"import": "Zaimportuj swoje dane do Vikunja"
"importText": "Import your projects and tasks from other services into Vikunja:",
"import": "Import your data into Vikunja"
}
},
"demo": {
"title": "Ta instancja jest w trybie demo. Nie używaj jej do prawdziwych danych!",
"everythingWillBeDeleted": "Wszystko będzie regularnie usuwane!",
"accountWillBeDeleted": "Twoje konto zostanie usunięte, wraz ze wszystkimi projektami, zadaniami i załącznikami, które możesz utworzyć."
"title": "This instance is in demo mode. Do not use this for real data!",
"everythingWillBeDeleted": "Everything will be deleted in regular intervals!",
"accountWillBeDeleted": "Your account will be deleted, including all projects, tasks and attachments you might create."
},
"404": {
"title": "Nie znaleziono",
@ -82,18 +81,18 @@
"newName": "Nowa nazwa",
"savedSuccess": "Ustawienia zostały pomyślnie zaktualizowane.",
"emailReminders": "Wysyłaj mi przypomnienia o zadaniach przez e-mail",
"overdueReminders": "Wyślij mi podsumowanie moich zaległych zadań codziennie",
"discoverableByName": "Pozwól innym użytkownikom dodać mnie jako członka zespołów lub projektów, gdy szukają mojego imienia",
"discoverableByEmail": "Pozwól innym użytkownikom dodać mnie jako członka drużyn lub projektów podczas wyszukiwania mojego pełnego adresu e-mail",
"overdueReminders": "Send me a summary of my undone overdue tasks every day",
"discoverableByName": "Allow other users to add me as a member to teams or projects when they search for my name",
"discoverableByEmail": "Allow other users to add me as a member to teams or projects when they search for my full email",
"playSoundWhenDone": "Odtwórz dźwięk podczas oznaczania zadań jako ukończonych",
"weekStart": "Tydzień zaczyna się od",
"weekStartSunday": "niedzieli",
"weekStartMonday": "poniedziałku",
"language": "Język",
"defaultProject": "Domyślny projekt",
"defaultProject": "Default Project",
"timezone": "Strefa czasowa",
"overdueTasksRemindersTime": "Czas przypomnienia o zaległych zadaniach na e-mail",
"filterUsedOnOverview": "Zapisany filtr używany na stronie przeglądania"
"overdueTasksRemindersTime": "Overdue tasks reminder email time",
"filterUsedOnOverview": "Saved filter used on the overview page"
},
"totp": {
"title": "Uwierzytelnianie dwuskładnikowe",
@ -147,37 +146,36 @@
}
},
"apiTokens": {
"title": "Tokeny API",
"general": "Tokeny API pozwalają korzystać z API Vikunja bez danych uwierzytelniających użytkownika.",
"apiDocs": "Sprawdź dokumentację API",
"createAToken": "Utwórz token",
"createToken": "Utwórz token",
"30d": "30 dni",
"60d": "60 dni",
"90d": "90 dni",
"permissionExplanation": "Uprawnienia pozwalają określić, co token API ma prawo robić.",
"titleRequired": "Tytuł jest wymagany",
"expired": "Ten token wygasł {ago}.",
"tokenCreatedSuccess": "Oto twój nowy token: {token}",
"tokenCreatedNotSeeAgain": "Przechowuj go w bezpiecznym miejscu, nie zobaczysz go ponownie!",
"title": "API Tokens",
"general": "API tokens allow you to use Vikunja's API without user credentials.",
"apiDocs": "Check out the api docs",
"createAToken": "Create a token",
"createToken": "Create token",
"30d": "30 Days",
"60d": "60 Days",
"90d": "90 Days",
"permissionExplanation": "Permissions allow you to scope what an api token is allowed to do.",
"titleRequired": "The title is required",
"expired": "This token has expired {ago}.",
"tokenCreatedSuccess": "Here is your new api token: {token}",
"tokenCreatedNotSeeAgain": "Store it in a secure location, you won't see it again!",
"delete": {
"header": "Usuń ten token",
"text1": "Czy na pewno chcesz usunąć token \"{token}\"?",
"text2": "Odbierze to dostęp wszystkim aplikacjom lub integracjom, które go używają. Nie można tego cofnąć."
"header": "Delete this token",
"text1": "Are you sure you want to delete the token \"{token}\"?",
"text2": "This will revoke access to all applications or integrations using it. You cannot undo this."
},
"attributes": {
"title": "Tytuł",
"titlePlaceholder": "Wprowadź tytuł, który później rozpoznasz",
"expiresAt": "Wygasa",
"permissions": "Uprawnienia"
"title": "Title",
"titlePlaceholder": "Enter a title you will recognize later",
"expiresAt": "Expires at",
"permissions": "Permissions"
}
}
},
"deletion": {
"title": "Usuń swoje konto Vikunja",
"text1": "Usunięcie Twojego konta jest trwałe i nie można tego cofnąć. Usuniemy wszystkie Twoje projekty, zadania i wszystko, co z nimi powiązane.",
"text1": "The deletion of your account is permanent and cannot be undone. We will delete all your projects, tasks and everything associated with it.",
"text2": "Aby kontynuować, wprowadź swoje hasło. Otrzymasz wiadomość e-mail z dalszymi instrukcjami.",
"text3": "Aby kontynuować, naciśnij poniższy przycisk. Otrzymasz e-mail z dalszymi instrukcjami.",
"confirm": "Usuń moje konto",
"requestSuccess": "Żądanie powiodło się. Otrzymasz wiadomość e-mail z dalszymi instrukcjami.",
"passwordRequired": "Wprowadź hasło.",
@ -185,13 +183,12 @@
"scheduled": "Twoje konto Vikunja zostanie usunięte w dniu {date} ({dateSince}).",
"scheduledCancel": "Aby anulować usunięcie konta, kliknij tutaj.",
"scheduledCancelText": "Aby anulować usunięcie konta, wprowadź poniżej swoje hasło:",
"scheduledCancelButton": "Aby anulować usunięcie konta, naciśnij przycisk poniżej:",
"scheduledCancelConfirm": "Anuluj usunięcie mojego konta",
"scheduledCancelSuccess": "Nie usuniemy Twojego konta."
},
"export": {
"title": "Eksportuj swoje dane Vikunja",
"description": "Możesz zażądać kopii wszystkich swoich danych Vikunja. Obejmuje to sekcje projekty, zadania i wszystko, co z nimi powiązane. Możesz zaimportować te dane do dowolnej instancji Vikunja za pomocą funkcji migracji.",
"description": "You can request a copy of all your Vikunja data. This includes Projects, Tasks and everything associated to them. You can import this data in any Vikunja instance through the migration function.",
"descriptionPasswordRequired": "Wprowadź hasło, aby kontynuować:",
"request": "Generuj kopię moich danych Vikunja",
"success": "Pomyślnie zażądałeś danych Vikunja! Wyślemy Ci e-mail, gdy będą gotowe do pobrania.",
@ -199,182 +196,167 @@
}
},
"project": {
"archivedMessage": "Ten projekt jest zarchiwizowany. Nie można utworzyć lub edytować dla niego nowych zadań.",
"archived": "Zarchiwizowane",
"showArchived": "Pokaż zarchiwizowane",
"title": "Tytuł projektu",
"color": "Kolor",
"projects": "Projekty",
"parent": "Projekt nadrzędny",
"search": "Kliknij, aby wyszukać projekt…",
"searchSelect": "Kliknij lub naciśnij Enter, aby wybrać ten projekt",
"shared": "Projekty udostępnione",
"noDescriptionAvailable": "Brak opisu projektu.",
"inboxTitle": "Własna lista",
"archivedMessage": "This project is archived. It is not possible to create new or edit tasks for it.",
"archived": "Archived",
"showArchived": "Show Archived",
"title": "Project Title",
"color": "Color",
"projects": "Projects",
"parent": "Parent Project",
"search": "Type to search for a project…",
"searchSelect": "Click or press enter to select this project",
"shared": "Shared Projects",
"noDescriptionAvailable": "No project description is available.",
"inboxTitle": "Inbox",
"create": {
"header": "Nowy projekt",
"titlePlaceholder": "Tu wpisz tytuł projektu…",
"addTitleRequired": "Proszę, podaj nazwę.",
"createdSuccess": "Projekt został pomyślnie utworzony.",
"addProjectRequired": "Proszę wybrać projekt lub ustaw domyślny projekt w ustawieniach."
"header": "New project",
"titlePlaceholder": "The project's title goes here…",
"addTitleRequired": "Please specify a title.",
"createdSuccess": "The project was successfully created.",
"addProjectRequired": "Please specify a project or set a default project in the settings."
},
"archive": {
"title": "Archiwizuj \"{project}\"",
"archive": "Zarchiwizuj ten projekt",
"unarchive": "Cofnij archiwizację tego projektu",
"unarchiveText": "Będziesz mógł tworzyć nowe zadania lub edytować je.",
"archiveText": "Nie będziesz mógł edytować tego projektu ani tworzyć nowych zadań, dopóki nie cofniesz archiwizacji.",
"success": "Projekt został pomyślnie zarchiwizowany."
"title": "Archive \"{project}\"",
"archive": "Archive this project",
"unarchive": "Un-Archive this project",
"unarchiveText": "You will be able to create new tasks or edit it.",
"archiveText": "You won't be able to edit this project or create new tasks until you un-archive it.",
"success": "The project was successfully archived."
},
"background": {
"title": "Ustaw tło projektu",
"remove": "Usuń tło",
"upload": "Prześlij tło ze swojego komputera",
"searchPlaceholder": "Szukaj tła…",
"poweredByUnsplash": "Wspierane przez Unsplash",
"loadMore": "Załaduj więcej zdjęć",
"success": "Tło zostało ustawione pomyślnie!",
"removeSuccess": "Tło zostało pomyślnie usunięte!"
"title": "Set project background",
"remove": "Remove Background",
"upload": "Choose a background from your pc",
"searchPlaceholder": "Search for a background…",
"poweredByUnsplash": "Powered by Unsplash",
"loadMore": "Load more photos",
"success": "The background has been set successfully!",
"removeSuccess": "The background has been removed successfully!"
},
"delete": {
"title": "Usuń \"{project}\"",
"header": "Usuń ten projekt",
"text1": "Czy na pewno chcesz usunąć ten projekt i całą jego zawartość?",
"text2": "Dotyczy to wszystkich zadań i tego NIE DA SIĘ COFNĄĆ!",
"success": "Projekt został pomyślnie usunięty.",
"tasksToDelete": "To nieodwracalnie usunie około {count} zadań.",
"noTasksToDelete": "Ten projekt nie zawiera żadnych zadań, więc można go bezpiecznie usunąć."
"title": "Delete \"{project}\"",
"header": "Delete this project",
"text1": "Are you sure you want to delete this project and all of its contents?",
"text2": "This includes all tasks and CANNOT BE UNDONE!",
"success": "The project was successfully deleted.",
"tasksToDelete": "This will irrevocably remove approx. {count} tasks.",
"noTasksToDelete": "This project does not contain any tasks, it should be safe to delete."
},
"duplicate": {
"title": "Duplikuj ten projekt",
"label": "Duplikuj",
"text": "Wybierz projekt nadrzędny, który będzie zawierał zduplikowany projekt:",
"success": "Projekt został pomyślnie zduplikowany."
"title": "Duplicate this project",
"label": "Duplicate",
"text": "Select a parent project which should hold the duplicated project:",
"success": "The project was successfully duplicated."
},
"edit": {
"header": "Edytuj ten projekt",
"title": "Edytuj \"{project}\"",
"titlePlaceholder": "Tutaj wpisz tytuł projektu…",
"identifierTooltip": "Identyfikator projektu może być używany do unikatowej identyfikacji zadania w różnych projektach. Możesz go wyczyścić, aby go wyłączyć.",
"identifier": "Identyfikator projektu",
"identifierPlaceholder": "Tutaj wpisz identyfikator projektu…",
"description": "Opis",
"descriptionPlaceholder": "Wprowadź opis dla tego projektu, naciśnij '/', aby uzyskać więcej opcji…",
"color": "Kolor",
"success": "Projekt został pomyślnie zaktualizowany."
"header": "Edit This Project",
"title": "Edit \"{project}\"",
"titlePlaceholder": "The project title goes here…",
"identifierTooltip": "The project identifier can be used to uniquely identify a task across projects. You can set it to empty to disable it.",
"identifier": "Project Identifier",
"identifierPlaceholder": "The project identifier goes here…",
"description": "Description",
"descriptionPlaceholder": "The projects description goes here…",
"color": "Color",
"success": "The project was successfully updated."
},
"share": {
"header": "Udostępnij ten projekt",
"title": "Udostępnij \"{project}\"",
"share": "Udostępnij",
"header": "Share this project",
"title": "Share \"{project}\"",
"share": "Share",
"links": {
"title": "Udostępnij linki",
"what": "Co to jest udostępnianie linków?",
"explanation": "Udostępnianie linków umożliwia łatwe udostępnianie projektów innym użytkownikom, którzy nie mają konta na Vikunja.",
"create": "Utwórz nowy link do udostępnienia",
"name": "Nazwa: (opcjonalnie)",
"namePlaceholder": "np. Lorem Ipsum",
"nameExplanation": "Wszystkie działania wykonane przez ten link udostępniający będą widoczne pod tą nazwą.",
"password": "Hasło (opcjonalnie)",
"passwordExplanation": "Podczas logowania użytkownik będzie musiał wprowadzić to hasło.",
"noName": "Nie ustawiono nazwy",
"remove": "Usuń link udostępnienia",
"removeText": "Czy na pewno chcesz usunąć ten link? Dostęp do tego projektu za pomocą tego linku udostępnionego nie będzie już możliwy. Nie można tego cofnąć!",
"createSuccess": "Link udostępniający został pomyślnie utworzony.",
"deleteSuccess": "Link udostępniający został pomyślnie usunięty",
"view": "Widok",
"sharedBy": "Udostępnione przez {0}"
"title": "Share Links",
"what": "What is a share link?",
"explanation": "Share Links allow you to easily share a project with other users who don't have an account on Vikunja.",
"create": "Create a new link share",
"name": "Name (optional)",
"namePlaceholder": "e.g. Lorem Ipsum",
"nameExplanation": "All actions done by this link share will show up with the name.",
"password": "Password (optional)",
"passwordExplanation": "When signing in, the user will be required to enter this password.",
"noName": "No name set",
"remove": "Remove a link share",
"removeText": "Are you sure you want to remove this link share? It will no longer be possible to access this project with this link share. This cannot be undone!",
"createSuccess": "The link share was successfully created.",
"deleteSuccess": "The link share was successfully deleted",
"view": "View",
"sharedBy": "Shared by {0}"
},
"userTeam": {
"typeUser": "użytkownik | użytkownicy",
"typeTeam": "zespół | zespoły",
"shared": "Udostępniono tym {type}",
"you": "Ty",
"notShared": "Nie udostępniono jeszcze żadnym {type}.",
"removeHeader": "Usuń {type} z {sharable}",
"removeText": "Czy na pewno chcesz usunąć ten {sharable} z {type}? Nie można tego cofnąć!",
"removeSuccess": "{sharable} został pomyślnie usunięty z {type}.",
"addedSuccess": "{type} został pomyślnie dodany.",
"updatedSuccess": "{type} został pomyślnie zaktualizowany."
"typeUser": "user | users",
"typeTeam": "team | teams",
"shared": "Shared with these {type}",
"you": "You",
"notShared": "Not shared with any {type} yet.",
"removeHeader": "Remove a {type} from the {sharable}",
"removeText": "Are you sure you want to remove this {sharable} from the {type}? This cannot be undone!",
"removeSuccess": "The {sharable} was successfully removed from the {type}.",
"addedSuccess": "The {type} was successfully added.",
"updatedSuccess": "The {type} was successfully added."
},
"right": {
"title": "Uprawnienie",
"read": "Tylko do odczytu",
"readWrite": "Odczyt i zapis",
"admin": "Administrator"
"title": "Permission",
"read": "Read only",
"readWrite": "Read & write",
"admin": "Admin"
},
"attributes": {
"link": "Link",
"delete": "Usuń"
"delete": "Delete"
}
},
"list": {
"title": "Lista",
"add": "Dodaj",
"addPlaceholder": "Dodaj nowe zadanie…",
"empty": "Ten projekt jest obecnie pusty.",
"newTaskCta": "Utwórz nowe zadanie.",
"editTask": "Edytuj zadanie"
"title": "List",
"add": "Add",
"addPlaceholder": "Add a new task…",
"empty": "This project is currently empty.",
"newTaskCta": "Create a new task.",
"editTask": "Edit Task"
},
"gantt": {
"title": "Gantt",
"showTasksWithoutDates": "Pokaż zadania, które nie mają ustawionych dat",
"size": "Rozmiar",
"default": "Domyślnie",
"month": "Miesiąc",
"day": "Dzień",
"hour": "Godzina",
"range": "Zakres dat",
"noDates": "To zadanie nie ma ustawionych dat."
"showTasksWithoutDates": "Show tasks which don't have dates set",
"size": "Size",
"default": "Default",
"month": "Month",
"day": "Day",
"hour": "Hour",
"range": "Date Range",
"noDates": "This task has no dates set."
},
"table": {
"title": "Tabela",
"columns": "Kolumny"
"title": "Table",
"columns": "Columns"
},
"kanban": {
"title": "Kanban",
"limit": "Limit: {limit}",
"noLimit": "Nie ustawiony",
"doneBucket": "Zakończone zadania",
"doneBucketHint": "Wszystkie zadania przeniesione do tej kolumny zostaną automatycznie oznaczone jako zakończone.",
"doneBucketHintExtended": "Wszystkie zadania przeniesione do kolumny zakończonych zostaną automatycznie oznaczone jako zakończone. Wszystkie zadania oznaczone jako zakończone z innych miejsc zostaną przeniesione.",
"doneBucketSavedSuccess": "Kolumna zakończonych zadań została pomyślnie zapisana.",
"defaultBucket": "Domyślna kolumna",
"defaultBucketHint": "Podczas tworzenia zadań bez określania kolumny, zostaną one dodane do tej kolumny.",
"defaultBucketSavedSuccess": "Kolumna zakończonych zadań została pomyślnie zapisana.",
"deleteLast": "Nie możesz usunąć ostatniej kolumny.",
"addTaskPlaceholder": "Wprowadź tytuł nowego zadania…",
"addTask": "Dodaj zadanie",
"addAnotherTask": "Dodaj kolejne zadanie",
"addBucket": "Utwórz nową kolumnę",
"addBucketPlaceholder": "Wprowadź tytuł nowej kolumny…",
"deleteHeaderBucket": "Usuń kolumnę",
"deleteBucketText1": "Czy na pewno chcesz usunąć tę kolumnę?",
"deleteBucketText2": "Nie usunie to żadnych zadań, ale przeniesie je do domyślnej kolumny.",
"deleteBucketSuccess": "Kolumna została pomyślnie usunięta.",
"bucketTitleSavedSuccess": "Tytuł kolumny został pomyślnie zapisany.",
"bucketLimitSavedSuccess": "Limit kolumny został pomyślnie zapisany.",
"collapse": "Zwiń tę kolumnę"
"noLimit": "Not Set",
"doneBucket": "Done bucket",
"doneBucketHint": "All tasks moved into this bucket will automatically marked as done.",
"doneBucketHintExtended": "All tasks moved into the done bucket will be marked as done automatically. All tasks marked as done from elsewhere will be moved as well.",
"doneBucketSavedSuccess": "The done bucket has been saved successfully.",
"defaultBucket": "Default bucket",
"defaultBucketHint": "When creating tasks without specifying a bucket, they will be added to this bucket.",
"defaultBucketSavedSuccess": "The default bucket has been saved successfully.",
"deleteLast": "You cannot remove the last bucket.",
"addTaskPlaceholder": "Enter the new task title…",
"addTask": "Add a task",
"addAnotherTask": "Add another task",
"addBucket": "Create a new bucket",
"addBucketPlaceholder": "Enter the new bucket title…",
"deleteHeaderBucket": "Delete the bucket",
"deleteBucketText1": "Are you sure you want to delete this bucket?",
"deleteBucketText2": "This will not delete any tasks but move them into the default bucket.",
"deleteBucketSuccess": "The bucket has been deleted successfully.",
"bucketTitleSavedSuccess": "The bucket title has been saved successfully.",
"bucketLimitSavedSuccess": "The bucket limit been saved successfully.",
"collapse": "Collapse this bucket"
},
"pseudo": {
"favorites": {
"title": "Ulubione"
"title": "Favorites"
}
},
"webhooks": {
"title": "Webhooki",
"targetUrl": "Docelowy URL",
"targetUrlInvalid": "Podaj prawidłowy adres URL.",
"events": "Eventy",
"eventsHint": "Wybierz wszystkie eventy, dla których webhook powinien otrzymywać aktualizacje (w ramach bieżącego projektu).",
"mustSelectEvents": "Musisz wybrać co najmniej jeden event.",
"delete": "Usuń ten webhook",
"deleteText": "Czy na pewno chcesz usunąć ten webhook? Zewnętrzne adresy nie będą już powiadamiane o jego eventach.",
"deleteSuccess": "Webhook został pomyślnie usunięty.",
"create": "Stwórz webhook",
"secret": "Sekret",
"secretHint": "Jeśli podane, wszystkie żądania do adresu docelowego webhooka zostaną podpisane przy użyciu HMAC.",
"secretDocs": "Sprawdź dokumentację, aby uzyskać więcej informacji na temat korzystania z sekretów."
}
},
"filters": {
@ -384,7 +366,7 @@
"title": "Tytuł",
"titlePlaceholder": "Tu wpisz tytuł filtra stałego…",
"description": "Opis",
"descriptionPlaceholder": "Dodaj tutaj opis dla tego filtra, naciśnij '/' aby uzyskać więcej opcji…",
"descriptionPlaceholder": "Tu wpisz opis…",
"includeNulls": "Uwzględnij zadania, które nie mają ustawionej danej wartości",
"requireAll": "Wymagaj, aby wszystkie filtry były spełnione, aby zadanie się pojawiło",
"showDoneTasks": "Pokaż ukończone zadania",
@ -398,9 +380,9 @@
},
"create": {
"title": "Nowy filtr stały",
"description": "Zapisany filtr to wirtualny projekt, który jest obliczany na podstawie zestawu filtrów za każdym razem, gdy jest dostępny.",
"description": "A saved filter is a virtual project which is computed from a set of filters each time it is accessed.",
"action": "Utwórz nowy filtr stały",
"titleRequired": "Podaj tytuł dla filtra."
"titleRequired": "Please provide a title for the filter."
},
"delete": {
"header": "Usuń ten filtr stały",
@ -413,7 +395,7 @@
}
},
"migrate": {
"title": "Importuj z innych usług",
"title": "Import from other services",
"titleService": "Zaimportuj swoje dane z {name} do Vikunja",
"import": "Zaimportuj swoje dane do Vikunja",
"description": "Aby rozpocząć, kliknij logo jednej z usług zewnętrznych.",
@ -425,14 +407,12 @@
"alreadyMigrated2": "Ponowne importowanie jest możliwe, ale proces ten utworzy duplikaty. Jesteś pewny?",
"confirm": "Jestem pewien, proszę rozpocząć migrację!",
"importUpload": "Aby zaimportować dane z {name} do Vikunja, kliknij przycisk poniżej, aby wybrać plik.",
"upload": "Prześlij plik",
"migrationStartedWillReciveEmail": "Vikunja zaimportuje teraz twoje listy/projekty, zadania, notatki, przypomnienia i pliki z {service}. Ponieważ zajmuje to trochę czasu, wyślemy Ci wiadomość e-mail, gdy skończymy. Możesz teraz zamknąć to okno.",
"migrationInProgress": "Migracja jest w toku. Poczekaj, aż zostanie zakończona."
"upload": "Prześlij plik"
},
"label": {
"title": "Etykiety",
"manage": "Zarządzaj etykietami",
"description": "Kliknij etykietę, aby ją edytować. Możesz edytować wszystkie etykiety, które utworzyłeś, oraz używać wszystkich etykiet, które są powiązane z zadaniem w projekcie, do którego masz dostęp.",
"description": "Click on a label to edit it. You can edit all labels you created, you can use all labels which are associated with a task to whose project you have access.",
"newCTA": "Obecnie nie masz żadnych etykiet.",
"search": "Wpisz, aby wyszukać etykietę…",
"create": {
@ -443,7 +423,7 @@
},
"edit": {
"header": "Edytuj etykietę",
"forbidden": "Nie możesz edytować tej etykiety, ponieważ nie jesteś jej właścicielem.",
"forbidden": "You are not allowed to edit this label because you don't own it.",
"success": "Etykieta została pomyślnie zaktualizowana."
},
"deleteSuccess": "Etykieta została pomyślnie usunięta.",
@ -457,7 +437,7 @@
},
"sharing": {
"authenticating": "Uwierzytelnianie…",
"passwordRequired": "Ten udostępniony projekt wymaga hasła. Proszę, wprowadź je poniżej:",
"passwordRequired": "This shared project requires a password. Please enter it below:",
"error": "Wystąpił błąd.",
"invalidPassword": "Hasło jest nieprawidłowe."
},
@ -498,7 +478,6 @@
"custom": "Własne",
"id": "ID",
"created": "Utworzono",
"createdBy": "Utworzone przez {0}",
"actions": "Akcje",
"cannotBeUndone": "Tego nie da się cofnąć!"
},
@ -517,59 +496,24 @@
"edit": "Edytuj",
"done": "Gotowe",
"heading1": "Nagłówek 1",
"heading1Tooltip": "Nagłówek H1.",
"heading2": "Nagłówek 2",
"heading2Tooltip": "Nagłówek H2.",
"heading3": "Nagłówek 3",
"heading3Tooltip": "Nagłówek H3.",
"headingSmaller": "Nagłówek mniejszy",
"headingBigger": "Nagłówek większy",
"bold": "Pogrubiony",
"italic": "Kursywa",
"strikethrough": "Przekreślony",
"underline": "Podkreślenie",
"code": "Kod",
"codeTooltip": "Dodaj fragment kodu.",
"quote": "Cytat",
"quoteTooltip": "Dodaj cytat.",
"bulletList": "Lista wypunktowana",
"bulletListTooltip": "Utwórz prostą listę wypunktowaną.",
"unorderedList": "Lista nieuporządkowana",
"orderedList": "Lista uporządkowana",
"orderedListTooltip": "Stwórz listę numerowaną.",
"orderedList": "Ordered List",
"cleanBlock": "Wyczyść blok",
"link": "Link",
"image": "Obraz",
"imageTooltip": "Prześlij obraz ze swojego komputera.",
"table": {
"title": "Tabela",
"insert": "Wstaw tabelę",
"addColumnBefore": "Dodaj kolumnę przed",
"addColumnAfter": "Dodaj kolumnę po",
"deleteColumn": "Usuń kolumnę",
"addRowBefore": "Dodaj wiersz przed",
"addRowAfter": "Dodaj wiersz po",
"deleteRow": "Usuń wiersz",
"deleteTable": "Usuń tabelę",
"mergeCells": "Scal komórki",
"splitCell": "Podziel komórkę",
"toggleHeaderColumn": "Przełącz nagłówek kolumny",
"toggleHeaderRow": "Przełącz nagłówek wiersza",
"toggleHeaderCell": "Przełącz nagłówek komórki",
"mergeOrSplit": "Połącz lub podziel",
"fixTables": "Napraw tabele"
},
"table": "Tabela",
"horizontalRule": "Linia pozioma",
"horizontalRuleTooltip": "Podziel sekcję.",
"sideBySide": "Obok siebie",
"guide": "Przewodnik",
"text": "Tekst",
"textTooltip": "Po prostu zacznij pisać.",
"taskList": "Lista zadań",
"taskListTooltip": "Śledź zadania za pomocą listy do zrobienia.",
"undo": "Cofnij",
"redo": "Ponów",
"placeholder": "Wpisz tekst lub naciśnij '/', aby zobaczyć więcej opcji…"
"guide": "Przewodnik"
},
"multiselect": {
"createPlaceholder": "Utwórz nowy",
@ -599,14 +543,14 @@
"canuse": "Możesz użyć kalkulacji dat do względnego filtrowania dat.",
"learnhow": "Sprawdź jak to działa",
"title": "Kalkulacja daty",
"intro": "Określ względne daty, które są pobierane na bieżąco przez Vikunja podczas stosowania filtra.",
"intro": "Specify relative dates which are resolved on the fly by Vikunja when applying the filter.",
"expression": "Każde wyrażenie kalkulacji daty rozpoczyna się datą zakotwiczenia, którą może być {0} lub wyrażeniem daty zakończonym {1}. Po tej dacie zakotwiczenia opcjonalnie może następować jedno lub więcej wyrażeń matematycznych.",
"similar": "Te wyrażenia są podobne do tych dostarczonych przez {0} i {1}.",
"add1Day": "Dodaj jeden dzień",
"minus1Day": "Odejmij jeden dzień",
"roundDay": "Zaokrąglij w dół do najbliższego dnia",
"supportedUnits": "Obsługiwane jednostki czasu",
"someExamples": "Przykłady wyrażeń czasu",
"supportedUnits": "Supported time units",
"someExamples": "Examples of time expressions",
"units": {
"seconds": "Sekundy",
"minutes": "Minuty",
@ -635,7 +579,7 @@
"addReminder": "Dodaj nowe przypomnienie…",
"doneSuccess": "Zadanie zostało pomyślnie oznaczone jako ukończone.",
"undoneSuccess": "Zadanie zostało pomyślnie otwarte ponownie.",
"undo": "Cofnij",
"undo": "Undo",
"openDetail": "Otwórz szczegółowy widok zadania",
"checklistTotal": "{checked} z {total} zadań",
"checklistAllDone": "{total} zadań",
@ -652,7 +596,7 @@
"chooseDueDate": "Kliknij tutaj, aby ustawić termin",
"chooseStartDate": "Kliknij tutaj, aby ustawić datę rozpoczęcia",
"chooseEndDate": "Kliknij tutaj, aby ustawić datę zakończenia",
"move": "Przenieś zadanie do innego projektu",
"move": "Move task to a different project",
"done": "Oznacz zadanie jako ukończone!",
"undone": "Otwórz zadanie ponownie",
"created": "Utworzono {0} przez {1}",
@ -660,12 +604,12 @@
"doneAt": "Ukończone {0}",
"updateSuccess": "Zadanie zostało pomyślnie zapisane.",
"deleteSuccess": "Zadanie zostało pomyślnie usunięte.",
"belongsToProject": "To zadanie należy do projektu '{project}'",
"belongsToProject": "This task belongs to project '{project}'",
"due": "Termin {at}",
"closePopup": "Zamknij okno",
"organization": "Organizacja",
"management": "Zarządzanie",
"dateAndTime": "Data i czas",
"organization": "Organization",
"management": "Management",
"dateAndTime": "Date and time",
"delete": {
"header": "Usuń to zadanie",
"text1": "Czy na pewno chcesz usunąć to zadanie?",
@ -683,7 +627,7 @@
"percentDone": "Ustaw postęp",
"attachments": "Dodaj załączniki",
"relatedTasks": "Dodaj powiązanie",
"moveProject": "Przenieś",
"moveProject": "Move",
"color": "Ustaw kolor",
"delete": "Usuń",
"favorite": "Dodaj do ulubionych",
@ -710,17 +654,17 @@
"updated": "Zaktualizowano"
},
"subscription": {
"subscribedTaskThroughParentProject": "Nie możesz zrezygnować z subskrypcji, ponieważ subskrybujesz to zadanie poprzez jego projekt.",
"subscribedProject": "Jesteś obecnie zapisany do tego projektu i będziesz otrzymywać powiadomienia o zmianach.",
"notSubscribedProject": "Nie jesteś zapisany do tego projektu i nie będziesz otrzymywać powiadomień o zmianach.",
"subscribedTask": "Jesteś obecnie zapisany do tego zadania i będziesz otrzymywać powiadomienia o zmianach.",
"notSubscribedTask": "Nie jesteś zapisany do tego zadania i nie będziesz otrzymywać powiadomień o zmianach.",
"subscribedTaskThroughParentProject": "You can't unsubscribe here because you are subscribed to this task through its project.",
"subscribedProject": "You are currently subscribed to this project and will receive notifications for changes.",
"notSubscribedProject": "You are not subscribed to this project and won't receive notifications for changes.",
"subscribedTask": "You are currently subscribed to this task and will receive notifications for changes.",
"notSubscribedTask": "You are not subscribed to this task and won't receive notifications for changes.",
"subscribe": "Subskrybuj",
"unsubscribe": "Anuluj subskrypcję",
"subscribeSuccessProject": "Jesteś teraz zapisany do tego projektu",
"unsubscribeSuccessProject": "Już nie subskrybujesz tego projektu",
"subscribeSuccessTask": "Jesteś teraz zapisany do tego zadania",
"unsubscribeSuccessTask": "Już nie subskrybujesz tego zadania"
"subscribeSuccessProject": "You are now subscribed to this project",
"unsubscribeSuccessProject": "You are now unsubscribed to this project",
"subscribeSuccessTask": "You are now subscribed to this task",
"unsubscribeSuccessTask": "You are now unsubscribed to this task"
},
"attachment": {
"title": "Załączniki",
@ -733,17 +677,17 @@
"deleteText1": "Czy na pewno chcesz usunąć załącznik {filename}?",
"copyUrl": "Kopiuj URL",
"copyUrlTooltip": "Skopiuj adres URL tego załącznika do użycia w tekście",
"setAsCover": "Ustaw jako okładkę",
"unsetAsCover": "Usuń okładkę",
"successfullyChangedCoverImage": "Obraz okładki został pomyślnie zmieniony.",
"usedAsCover": "Obraz okładki"
"setAsCover": "Make cover",
"unsetAsCover": "Remove cover",
"successfullyChangedCoverImage": "The cover image was successfully changed.",
"usedAsCover": "Cover image"
},
"comment": {
"title": "Komentarze",
"loading": "Ładowanie komentarzy…",
"edited": "edytowane {date}",
"creating": "Tworzenie komentarza…",
"placeholder": "Dodaj swój komentarz, naciśnij '/' aby uzyskać więcej opcji…",
"placeholder": "Dodaj swój komentarz…",
"comment": "Skomentuj",
"delete": "Usuń ten komentarz",
"deleteText1": "Czy na pewno chcesz usunąć ten komentarz?",
@ -757,7 +701,7 @@
"1week": "1 tydzień"
},
"description": {
"placeholder": "Wprowadź opis, naciśnij '/', aby uzyskać więcej opcji…",
"placeholder": "Kliknij tutaj, aby wprowadzić opis…",
"empty": "Nie ma jeszcze opisu."
},
"assignee": {
@ -774,16 +718,16 @@
"removeSuccess": "Etykieta została pomyślnie usunięta.",
"addCreateSuccess": "Etykieta została pomyślnie utworzona i dodana.",
"delete": {
"header": "Usuń tę etykietę",
"text1": "Czy na pewno chcesz usunąć tę etykietę?",
"text2": "Spowoduje to jej usunięcie ze wszystkich zadań i nie będzie można jej przywrócić."
"header": "Delete this label",
"text1": "Are you sure you want to delete this label?",
"text2": "This will remove it from all tasks and cannot be restored."
}
},
"priority": {
"unset": "Nie ustawiony",
"low": "Niski",
"medium": "Średni",
"high": "Wysoki",
"high": "High",
"urgent": "Pilny",
"doNow": "ZRÓB TO TERAZ"
},
@ -792,7 +736,7 @@
"new": "Nowe powiązane zadanie",
"searchPlaceholder": "Wpisz, aby wyszukać zadanie, które chcesz dodać jako powiązane…",
"createPlaceholder": "Dodaj jako nowe powiązane zadanie",
"differentProject": "To zadanie należy do innego projektu.",
"differentProject": "This task belongs to a different project.",
"noneYet": "Nie ma jeszcze powiązanych zadań.",
"delete": "Usuń powiązane zadanie",
"deleteText1": "Czy na pewno chcesz usunąć to powiązane zadanie?",
@ -813,20 +757,20 @@
}
},
"reminder": {
"before": "{amount} {unit} przed {type}",
"after": "{amount} {unit} po {type}",
"beforeShort": "przed",
"afterShort": "po",
"onDueDate": "W terminie",
"onStartDate": "Data rozpoczęcia",
"onEndDate": "Data zakończenia",
"custom": "Własne",
"dateAndTime": "Data i czas"
"before": "{amount} {unit} before {type}",
"after": "{amount} {unit} after {type}",
"beforeShort": "before",
"afterShort": "after",
"onDueDate": "On the due date",
"onStartDate": "On the start date",
"onEndDate": "On the end date",
"custom": "Custom",
"dateAndTime": "Date and time"
},
"repeat": {
"everyDay": "Codziennie",
"everyWeek": "Co tydzień",
"every30d": "Co 30 dni",
"every30d": "Every 30 Days",
"mode": "Tryb powtarzania",
"monthly": "Miesięczny",
"fromCurrentDate": "Od bieżącej daty",
@ -837,24 +781,24 @@
"weeks": "Tygodnie",
"months": "Miesiące",
"years": "Lata",
"invalidAmount": "Wprowadź więcej niż 0."
"invalidAmount": "Please enter more than 0."
},
"quickAddMagic": {
"hint": "Użyj magicznych prefiksów, aby zdefiniować terminy, osoby przypisane i inne właściwości zadania.",
"hint": "Use magic prefixes to define due dates, assignees and other task properties.",
"title": "Quick Add Magic",
"intro": "Podczas tworzenia zadania możesz użyć specjalnych słów kluczowych, aby bezpośrednio dodać atrybuty do nowo utworzonego zadania. Pozwala to na znacznie szybsze dodawanie powszechnie używanych atrybutów do zadań.",
"multiple": "Możesz użyć tego wielokrotnie.",
"label1": "Aby dodać etykietę, po prostu poprzedź nazwę etykiety przedrostkiem {prefix}.",
"label2": "Vikunja najpierw sprawdzi, czy etykieta już istnieje, a jeśli nie, utworzy ją.",
"label3": "Aby użyć spacji, po prostu dodaj \" lub ' wokół nazwy etykiety.",
"label3": "To use spaces, simply add a \" or ' around the label name.",
"label4": "Na przykład: {prefix}\"Etykieta ze spacjami\".",
"priority1": "Aby ustawić priorytet zadania, dodaj liczbę 1-5 poprzedzoną {prefix}.",
"priority2": "Im większa liczba, tym wyższy priorytet.",
"assignees": "Aby bezpośrednio przypisać zadanie użytkownikowi, dodaj nazwę użytkownika poprzedzoną przedrostkiem {prefix} do zadania.",
"project1": "Aby ustawić projekt, w którym ma się pojawić zadanie, wprowadź jego nazwę poprzedzoną {prefix}.",
"project2": "Spowoduje to błąd, jeśli projekt nie istnieje.",
"project3": "Aby użyć spacji, po prostu dodaj \" lub ' wokół nazwy projektu.",
"project4": "Na przykład: {prefix}\"Projekt ze spacjami\".",
"project1": "To set a project for the task to appear in, enter its name prefixed with {prefix}.",
"project2": "This will return an error if the project does not exist.",
"project3": "To use spaces, simply add a \" or ' around the project name.",
"project4": "For example: {prefix}\"Project with spaces\".",
"dateAndTime": "Data i godzina",
"date": "Dowolna data może być użyta jako termin wykonania nowego zadania. Możesz wykorzystać datę w dowolnym z podanych formatów:",
"dateWeekday": "dowolny dzień tygodnia spowoduje wybranie najbliższej daty przypadającej na podany dzień tygodnia",
@ -883,24 +827,24 @@
"userAddedSuccess": "Członek zespołu został pomyślnie dodany.",
"madeMember": "Użytkownik został pomyślnie mianowany członkiem zespołu.",
"madeAdmin": "Członek zespołu został pomyślnie mianowany administratorem.",
"mustSelectUser": "Proszę wybrać użytkownika.",
"mustSelectUser": "Please select a user.",
"delete": {
"header": "Usuń zespół",
"text1": "Czy na pewno chcesz usunąć ten zespół i wszystkich jego członków?",
"text2": "Wszyscy członkowie zespołu stracą dostęp do projektów udostępnionych temu zespołowi. TEGO NIE MOŻNA COFNIĘĆ!",
"text2": "All team members will lose access to projects shared with this team. This CANNOT BE UNDONE!",
"success": "Zespół został pomyślnie usunięty."
},
"deleteUser": {
"header": "Usuń użytkownika z zespołu",
"text1": "Czy na pewno chcesz usunąć tego użytkownika z zespołu?",
"text2": "Straci on dostęp do wszystkich projektów, do których zespół ma dostęp. TEGO NIE MOŻNA COFNIĘĆ!",
"text2": "They will lose access to all projects this team has access to. This CANNOT BE UNDONE!",
"success": "Użytkownik został pomyślnie usunięty z zespołu."
},
"leave": {
"title": "Opuść zespół",
"text1": "Czy na pewno chcesz opuścić ten zespół?",
"text2": "Stracisz dostęp do wszystkich projektów, do których zespół ma dostęp. Jeśli zmienisz zdanie, będziesz potrzebować administratora zespołu, aby cię ponownie dodać.",
"success": "Pomyślnie opuściłeś zespół."
"title": "Leave team",
"text1": "Are you sure you want to leave this team?",
"text2": "You will lose access to all projects this team has access to. If you change your mind you'll need a team admin to add you again.",
"success": "You have successfully left the team."
}
},
"attributes": {
@ -908,7 +852,7 @@
"namePlaceholder": "Tu wpisz nazwę zespołu…",
"nameRequired": "Proszę, podaj nazwę.",
"description": "Opis",
"descriptionPlaceholder": "Opisz tutaj zespół, naciśnij '/' aby uzyskać więcej opcji…",
"descriptionPlaceholder": "Tu wpisz opis drużyny…",
"admin": "Administrator",
"member": "Członek"
}
@ -931,20 +875,19 @@
"attachment": "Dodaj załącznik do tego zadania",
"related": "Zmodyfikuj zadania powiązane z tym zadaniem",
"color": "Zmień kolor tego zadania",
"move": "Przenieś zadanie do innego projektu",
"move": "Move this task to another project",
"reminder": "Zarządzaj przypomnieniami o tym zadaniu",
"description": "Przełącz edycję opisu zadania",
"delete": "Usuń to zadanie",
"priority": "Zmień priorytet tego zadania",
"favorite": "Oznacz to zadanie jako ulubione / nieulubione",
"save": "Zapisz bieżące zadanie"
"description": "Toggle editing of the task description",
"delete": "Delete this task",
"priority": "Change the priority of this task",
"favorite": "Mark this task as favorite / unfavorite"
},
"project": {
"title": "Widoki projektu",
"switchToListView": "Przełącz na widok listy",
"switchToGanttView": "Przełącz na widok Gantta",
"switchToKanbanView": "Przełącz na widok Kanban",
"switchToTableView": "Przełącz na widok tabeli"
"title": "Project Views",
"switchToListView": "Switch to list view",
"switchToGanttView": "Switch to gantt view",
"switchToKanbanView": "Switch to kanban view",
"switchToTableView": "Switch to table view"
},
"navigation": {
"title": "Nawigacja",
@ -952,11 +895,11 @@
"upcoming": "Przejdź do nadchodzących zadań",
"labels": "Przejdź do etykiet",
"teams": "Przejdź do zespołów",
"projects": "Przejdź do projektów"
"projects": "Navigate to projects"
}
},
"update": {
"available": "Dostępna jest aktualizacja!",
"available": "There is an update available!",
"do": "Aktualizuj teraz"
},
"menu": {
@ -967,15 +910,15 @@
"unarchive": "Cofnij archiwizację",
"setBackground": "Ustaw tło",
"share": "Udostępnij",
"newProject": "Nowy projekt",
"createProject": "Utwórz projekt"
"newProject": "New project",
"createProject": "Create project"
},
"apiConfig": {
"url": "URL Vikunji",
"urlPlaceholder": "np. https://localhost:3456",
"change": "zmień",
"use": "Użyj instalacji Vikunji z {0}",
"error": "Nie można znaleźć ani użyć instalacji Vikunja w \"{domain}\". Sprawdź, czy adres URL ma poprawny format i możesz go uzyskać bezpośrednio i spróbować ponownie.",
"error": "Could not find or use Vikunja installation at \"{domain}\". Please check if the url has the correct format and you can reach it when accessing it directly and try again.",
"success": "Używasz instalacji Vikunji z \"{domain}\".",
"urlRequired": "URL jest wymagany."
},
@ -987,26 +930,24 @@
"notification": {
"title": "Powiadomienia",
"none": "Nie masz żadnych powiadomień. Miłego dnia!",
"explainer": "Powiadomienia pojawią się tutaj, gdy zajdą akcje w projektach lub zadaniach, które obserwujesz.",
"markAllRead": "Oznacz wszystkie powiadomienia jako przeczytane",
"markAllReadSuccess": "Pomyślnie zaznaczono wszystkie powiadomienia jako przeczytane."
"explainer": "Notifications will appear here when actions projects or tasks you subscribed to happen."
},
"quickActions": {
"commands": "Polecenia",
"placeholder": "Wpisz polecenie lub wyszukiwaną frazę…",
"hint": "Możesz użyć {project}, aby ograniczyć wyszukiwanie do projektu. Połącz {project} lub {label} (etykiety) z zapytaniem wyszukiwania, aby szukać zadania z tymi etykietami lub w tym projekcie. Użyj {assignee}, aby szukać tylko zespołów.",
"hint": "You can use {project} to limit the search to a project. Combine {project} or {label} (labels) with a search query to search for a task with these labels or on that project. Use {assignee} to only search for teams.",
"tasks": "Zadania",
"projects": "Projekty",
"projects": "Projects",
"teams": "Zespoły",
"labels": "Etykiety",
"newProject": "Wpisz tytuł nowego projektu…",
"labels": "Labels",
"newProject": "Enter the title of the new project…",
"newTask": "Wpisz tytuł nowego zadania…",
"newTeam": "Wpisz nazwę nowego zespołu…",
"createTask": "Utwórz zadanie w bieżącym projekcie ({title})",
"createProject": "Utwórz projekt",
"createTask": "Create a task in the current project ({title})",
"createProject": "Create a project",
"cmds": {
"newTask": "Nowe zadanie",
"newProject": "Nowy projekt",
"newProject": "New project",
"newTeam": "Nowy zespół"
}
},
@ -1037,15 +978,15 @@
"1018": "Ustawienie typu awatara użytkownika jest nieprawidłowe.",
"2001": "ID nie może być puste lub równe 0.",
"2002": "Niektóre dane żądania były nieprawidłowe.",
"3001": "Projekt nie istnieje.",
"3004": "Musisz mieć uprawnienia do odczytu w tym projekcie, aby wykonać tę akcję.",
"3005": "Nazwa projektu nie może być pusta.",
"3006": "Udostępnienie projektu nie istnieje.",
"3007": "Projekt z tym identyfikatorem już istnieje.",
"3008": "Projekt jest zarchiwizowany i dlatego można go tylko przeglądać. To samo dotyczy wszystkich zadań związanych z tym projektem.",
"4001": "Tekst zadania projektu nie może być pusty.",
"4002": "Projekt nie istnieje.",
"4003": "Wszystkie zadania do edycji zbiorczej muszą należeć do tego samego projektu.",
"3001": "The project does not exist.",
"3004": "You need to have read permissions on that project to perform that action.",
"3005": "The project title cannot be empty.",
"3006": "The project share does not exist.",
"3007": "A project with this identifier already exists.",
"3008": "The project is archived and can therefore only be accessed read only. This is also true for all tasks associated with this project.",
"4001": "The project task text cannot be empty.",
"4002": "The project task does not exist.",
"4003": "All bulk editing tasks must belong to the same project.",
"4004": "Potrzebujesz co najmniej jednego zadania do edycji zbiorczej zadań.",
"4005": "Nie masz uprawnień, aby zobaczyć to zadanie.",
"4006": "Zadanie nie może zostać ustawione jako nadrzędne dla samego siebie.",
@ -1064,21 +1005,21 @@
"4019": "Nieprawidłowa wartość filtra zadań.",
"6001": "Nazwa zespołu nie może być pusta.",
"6002": "Zespół nie istnieje.",
"6004": "Zespół już ma dostęp do tego projektu.",
"6004": "The team already has access to that project.",
"6005": "Użytkownik jest już członkiem tego zespołu.",
"6006": "Nie można usunąć ostatniego członka zespołu.",
"6007": "Zespół nie ma dostępu do projektu, aby wykonać tę akcję.",
"7002": "Użytkownik już ma dostęp do tego projektu.",
"7003": "Nie masz dostępu do tego projektu.",
"6007": "The team does not have access to the project to perform that action.",
"7002": "The user already has access to that project.",
"7003": "You do not have access to that project.",
"8001": "Ta etykieta już istnieje w tym zadaniu.",
"8002": "Etykieta nie istnieje.",
"8003": "Nie masz dostępu do tej etykiety.",
"9001": "Nieprawidłowe uprawnienia.",
"10001": "Zasobnik nie istnieje.",
"10002": "Zasobnik nie należy do tego projektu.",
"10003": "Nie można usunąć ostatniego zasobnika w projekcie.",
"10002": "The bucket does not belong to that project.",
"10003": "You cannot remove the last bucket on a project.",
"10004": "Nie możesz dodać zadania do tego zasobnika, ponieważ przekroczyło już limit zadań, które może pomieścić.",
"10005": "W projekcie może być tylko jeden zasobnik zrobiony.",
"10005": "There can be only one done bucket per project.",
"11001": "Filtr stały nie istnieje.",
"11002": "Filtry stałe nie są dostępne dla udostępnionych linków.",
"12001": "Typ subskrypcji jest nieprawidłowy.",
@ -1093,13 +1034,13 @@
},
"time": {
"units": {
"seconds": "sekunda|sekundy",
"minutes": "minuta|minut",
"hours": "godzina|godzin",
"days": "dzień|dni",
"weeks": "tydzień|tygodni",
"months": "miesiąc|miesięcy",
"years": "rok|lat"
"seconds": "second|seconds",
"minutes": "minute|minutes",
"hours": "hour|hours",
"days": "day|days",
"weeks": "week|weeks",
"months": "month|months",
"years": "year|years"
}
}
}

View File

@ -6,7 +6,6 @@
"welcomeEvening": "Boa noite, {username}!",
"lastViewed": "Visto por último",
"addToHomeScreen": "Add this app to your home screen for faster access and improved experience.",
"goToOverview": "Go to overview",
"project": {
"importText": "Import your projects and tasks from other services into Vikunja:",
"import": "Import your data into Vikunja"
@ -177,7 +176,6 @@
"title": "Delete your Vikunja Account",
"text1": "The deletion of your account is permanent and cannot be undone. We will delete all your projects, tasks and everything associated with it.",
"text2": "To proceed, please enter your password. You will receive an email with further instructions.",
"text3": "To proceed, please press the button below. You will receive an email with further instructions.",
"confirm": "Delete my account",
"requestSuccess": "The request was successful. You'll receive an email with further instructions.",
"passwordRequired": "Please enter your password.",
@ -185,7 +183,6 @@
"scheduled": "We will delete your Vikunja account at {date} ({dateSince}).",
"scheduledCancel": "To cancel the deletion of your account, click here.",
"scheduledCancelText": "To cancel the deletion of your account, please enter your password below:",
"scheduledCancelButton": "To cancel the deletion of your account, please press the button below:",
"scheduledCancelConfirm": "Cancel the deletion of my account",
"scheduledCancelSuccess": "We will not delete your account."
},
@ -259,7 +256,7 @@
"identifier": "Project Identifier",
"identifierPlaceholder": "The project identifier goes here…",
"description": "Description",
"descriptionPlaceholder": "Enter a description for this project, hit '/' for more options…",
"descriptionPlaceholder": "The projects description goes here…",
"color": "Color",
"success": "The project was successfully updated."
},
@ -360,21 +357,6 @@
"favorites": {
"title": "Favorites"
}
},
"webhooks": {
"title": "Webhooks",
"targetUrl": "Target URL",
"targetUrlInvalid": "Please provide a valid URL.",
"events": "Events",
"eventsHint": "Select all events this webhook should recieve updates for (within the current project).",
"mustSelectEvents": "You must select at least one event.",
"delete": "Delete this webhook",
"deleteText": "Are you sure you want to delete this webhook? External targets will not be notified of its events anymore.",
"deleteSuccess": "The webhook was successfully deleted.",
"create": "Create webhook",
"secret": "Secret",
"secretHint": "If provided, all requests to the webhook target URL will be signed using HMAC.",
"secretDocs": "Check out the docs for more details about how to use secrets."
}
},
"filters": {
@ -384,7 +366,7 @@
"title": "Título",
"titlePlaceholder": "O título do filtro salvo fica aqui…",
"description": "Descrição",
"descriptionPlaceholder": "Add a description for this filter here, hit '/' for more options…",
"descriptionPlaceholder": "A descrição fica aqui…",
"includeNulls": "Incluir tarefas que não possuem um conjunto de valores",
"requireAll": "Exigir que todos os filtros sejam verdadeiros para uma tarefa ser exibida",
"showDoneTasks": "Mostrar tarefas concluídas",
@ -425,9 +407,7 @@
"alreadyMigrated2": "Importing again is possible, but might create duplicates. Are you sure?",
"confirm": "Tenho certeza, comece a migrar agora, por favor!",
"importUpload": "To import data from {name} into Vikunja, click the button below to select a file.",
"upload": "Enviar arquivo",
"migrationStartedWillReciveEmail": "Vikunja will now import your lists/projects, tasks, notes, reminders and files from {service}. As this will take a while, we will send you an email once done. You can close this window now.",
"migrationInProgress": "A migration is currently in progress. Please wait until it is done."
"upload": "Enviar arquivo"
},
"label": {
"title": "Etiquetas",
@ -498,7 +478,6 @@
"custom": "Custom",
"id": "ID",
"created": "Criado em",
"createdBy": "Created by {0}",
"actions": "Ações",
"cannotBeUndone": "This cannot be undone!"
},
@ -517,59 +496,24 @@
"edit": "Editar",
"done": "Concluído",
"heading1": "Título 1",
"heading1Tooltip": "Big section heading.",
"heading2": "Título 2",
"heading2Tooltip": "Medium section heading.",
"heading3": "Título 3",
"heading3Tooltip": "Smaller section header.",
"headingSmaller": "Heading Smaller",
"headingBigger": "Heading Bigger",
"bold": "Negrito",
"italic": "Itálico",
"strikethrough": "Riscado",
"underline": "Underline",
"code": "Código",
"codeTooltip": "Capture a code snippet.",
"quote": "Citação",
"quoteTooltip": "Capture a quote.",
"bulletList": "Bullet list",
"bulletListTooltip": "Create a simple bullet list.",
"unorderedList": "Unordered list",
"orderedList": "Ordered list",
"orderedListTooltip": "Create a list with numbering.",
"unorderedList": "Lista não ordenada",
"orderedList": "Ordered List",
"cleanBlock": "Clean Block",
"link": "Link",
"image": "Imagem",
"imageTooltip": "Upload an image from your computer.",
"table": {
"title": "Table",
"insert": "Insert table",
"addColumnBefore": "Add column before",
"addColumnAfter": "Add column after",
"deleteColumn": "Delete column",
"addRowBefore": "Add row before",
"addRowAfter": "Add row after",
"deleteRow": "Delete row",
"deleteTable": "Delete table",
"mergeCells": "Merge cells",
"splitCell": "Split cell",
"toggleHeaderColumn": "Toggle header column",
"toggleHeaderRow": "Toggle header row",
"toggleHeaderCell": "Toggle header cell",
"mergeOrSplit": "Merge or split",
"fixTables": "Fix tables"
},
"table": "Tabela",
"horizontalRule": "Linha horizontal",
"horizontalRuleTooltip": "Divide a section.",
"sideBySide": "Lado a Lado",
"guide": "Guide",
"text": "Text",
"textTooltip": "Just start typing with plain text.",
"taskList": "Task list",
"taskListTooltip": "Track tasks with a to-do list.",
"undo": "Undo",
"redo": "Redo",
"placeholder": "Type some text or hit '/' to see more options…"
"guide": "Guide"
},
"multiselect": {
"createPlaceholder": "Criar novo",
@ -743,7 +687,7 @@
"loading": "Loading comments…",
"edited": "edited {date}",
"creating": "Criando comentário…",
"placeholder": "Add your comment, hit '/' for more options…",
"placeholder": "Adicione seu comentário…",
"comment": "Comentário",
"delete": "Apagar este comentário",
"deleteText1": "Tem certeza que deseja apagar este comentário?",
@ -757,7 +701,7 @@
"1week": "1 semana"
},
"description": {
"placeholder": "Enter a description, hit '/' for more options…",
"placeholder": "Clique aqui para inserir uma descrição…",
"empty": "Nenhuma descrição disponível ainda."
},
"assignee": {
@ -908,7 +852,7 @@
"namePlaceholder": "The team's name goes here…",
"nameRequired": "Por favor, especifique um nome.",
"description": "Description",
"descriptionPlaceholder": "Describe the team here, hit '/' for more options…",
"descriptionPlaceholder": "The teams description goes here…",
"admin": "Administrador",
"member": "Membro"
}
@ -936,8 +880,7 @@
"description": "Toggle editing of the task description",
"delete": "Delete this task",
"priority": "Change the priority of this task",
"favorite": "Mark this task as favorite / unfavorite",
"save": "Save the current task"
"favorite": "Mark this task as favorite / unfavorite"
},
"project": {
"title": "Project Views",
@ -987,9 +930,7 @@
"notification": {
"title": "Notificações",
"none": "You don't have any notifications. Have a nice day!",
"explainer": "Notifications will appear here when actions projects or tasks you subscribed to happen.",
"markAllRead": "Mark all notifications as read",
"markAllReadSuccess": "Successfully marked all notifications as read."
"explainer": "Notifications will appear here when actions projects or tasks you subscribed to happen."
},
"quickActions": {
"commands": "Comandos",

View File

@ -6,16 +6,15 @@
"welcomeEvening": "Boa Tarde {username}!",
"lastViewed": "Visto recentemente",
"addToHomeScreen": "Adiciona esta aplicação ao ecrã inicial para um acesso mais rápido e uma melhor experiência.",
"goToOverview": "Ir para a vista geral",
"project": {
"importText": "Importa os teus projetos e tarefas de outros serviços para o Vikunja:",
"import": "Importar os teus dados para o Vikunja"
}
},
"demo": {
"title": "Esta instância está em modo de demonstração. Não a utilizes para dados reais!",
"everythingWillBeDeleted": "Tudo aqui serão eliminados em intervalos regulares!",
"accountWillBeDeleted": "A tua conta será eliminada, incluindo todos os projetos, tarefas e anexos que poderás ter criado."
"title": "This instance is in demo mode. Do not use this for real data!",
"everythingWillBeDeleted": "Everything will be deleted in regular intervals!",
"accountWillBeDeleted": "Your account will be deleted, including all projects, tasks and attachments you might create."
},
"404": {
"title": "Não encontrado",
@ -147,29 +146,29 @@
}
},
"apiTokens": {
"title": "Tokens de API",
"general": "Tokens de API permitem que utilize a API do Vikunja sem as credenciais de utilizador.",
"apiDocs": "Verifica a documentação da API",
"createAToken": "Criar um token",
"createToken": "Criar token",
"30d": "30 Dias",
"60d": "60 Dias",
"90d": "90 Dias",
"permissionExplanation": "As permissões permitem-te definir o âmbito para o qual o token de API pode ser utilizado.",
"titleRequired": "O título é requerido",
"expired": "Este token expirou {ago}.",
"tokenCreatedSuccess": "Aqui está o teu novo token de API: {token}",
"tokenCreatedNotSeeAgain": "Guarda-o num local seguro, não o vais poder visualizar novamente!",
"title": "API Tokens",
"general": "API tokens allow you to use Vikunja's API without user credentials.",
"apiDocs": "Check out the api docs",
"createAToken": "Create a token",
"createToken": "Create token",
"30d": "30 Days",
"60d": "60 Days",
"90d": "90 Days",
"permissionExplanation": "Permissions allow you to scope what an api token is allowed to do.",
"titleRequired": "The title is required",
"expired": "This token has expired {ago}.",
"tokenCreatedSuccess": "Here is your new api token: {token}",
"tokenCreatedNotSeeAgain": "Store it in a secure location, you won't see it again!",
"delete": {
"header": "Eliminar este token",
"text1": "Tens a certeza que pretendes eliminar o token \"{token}\"?",
"text2": "Isto vai revogar o acesso a todos os aplicativos ou integrações que o utilizam. Não é possível anular esta ação."
"header": "Delete this token",
"text1": "Are you sure you want to delete the token \"{token}\"?",
"text2": "This will revoke access to all applications or integrations using it. You cannot undo this."
},
"attributes": {
"title": "Título",
"titlePlaceholder": "Insere um título que reconhecerás mais tarde",
"expiresAt": "Expira a",
"permissions": "Permissões"
"title": "Title",
"titlePlaceholder": "Enter a title you will recognize later",
"expiresAt": "Expires at",
"permissions": "Permissions"
}
}
},
@ -177,7 +176,6 @@
"title": "Eliminar a tua conta Vikunja",
"text1": "A eliminação da tua conta é permanente e não pode ser revertida. Vão ser eliminados todos os teus projetos, tarefas e tudo o que lhes está associado.",
"text2": "Para prosseguires, introduz por favor a tua palavra-passe. Receberás um e-mail com mais instruções.",
"text3": "Para prosseguir, pressiona o botão abaixo. Vais receber um e-mail com mais instruções.",
"confirm": "Eliminar a minha conta",
"requestSuccess": "A solicitação foi bem sucedida. Receberás um e-mail com mais instruções.",
"passwordRequired": "Por favor, insere a tua palavra-passe.",
@ -185,7 +183,6 @@
"scheduled": "Vamos eliminar a tua conta no Vikunja em {date} ({dateSince}).",
"scheduledCancel": "Para cancelar a eliminação da tua conta, clica aqui.",
"scheduledCancelText": "Para cancelares a eliminação da tua conta, introduz a tua palavra-passe abaixo:",
"scheduledCancelButton": "Para cancelares a eliminação da tua conta, pressiona o botão abaixo:",
"scheduledCancelConfirm": "Cancelar a eliminação da minha conta",
"scheduledCancelSuccess": "Não vamos apagar a tua conta."
},
@ -259,7 +256,7 @@
"identifier": "Identificador do Projeto",
"identifierPlaceholder": "O identificador do porjeto será aqui…",
"description": "Descrição",
"descriptionPlaceholder": "Insere uma descrição para este projeto, pressiona '/' para mais opções…",
"descriptionPlaceholder": "A descrição do projeto será aqui…",
"color": "Cor",
"success": "O projeto foi atualizado com sucesso."
},
@ -339,9 +336,9 @@
"doneBucketHint": "Todas as tarefas movidas para este conjunto serão automaticamente marcadas como concluídas.",
"doneBucketHintExtended": "Todas as tarefas movidas para o conjunto concluído serão marcadas automaticamente como concluídas. Todas as tarefas marcadas como concluídas em outro lugar também serão movidas.",
"doneBucketSavedSuccess": "O conjunto concluído foi salvo com sucesso.",
"defaultBucket": "Conjunto padrão",
"defaultBucketHint": "Quando criares tarefas sem especificar um conjunto, elas serão adicionadas a este conjunto.",
"defaultBucketSavedSuccess": "O conjunto padrão foi salvo com sucesso.",
"defaultBucket": "Default bucket",
"defaultBucketHint": "When creating tasks without specifying a bucket, they will be added to this bucket.",
"defaultBucketSavedSuccess": "The default bucket has been saved successfully.",
"deleteLast": "Não podes remover o ultimo conjunto.",
"addTaskPlaceholder": "Introduz o título da nova tarefa…",
"addTask": "Adicionar uma tarefa",
@ -360,21 +357,6 @@
"favorites": {
"title": "Favoritos"
}
},
"webhooks": {
"title": "Webhooks",
"targetUrl": "URL de destino",
"targetUrlInvalid": "Por favor, fornece um URL válido.",
"events": "Eventos",
"eventsHint": "Selecionar todos os eventos para os quais este webhook deve receber atualizações (no projeto atual).",
"mustSelectEvents": "Tens de selecionar pelo menos um evento.",
"delete": "Eliminar este webhook",
"deleteText": "Tens a certeza de que pretendes eliminar este webhook? Os alvos externos deixarão de ser notificados dos seus eventos.",
"deleteSuccess": "O webhook foi eliminada com sucesso.",
"create": "Criar webhook",
"secret": "Segredo",
"secretHint": "Se fornecido, todos os pedidos para o URL de destino do webhook serão assinados utilizando HMAC.",
"secretDocs": "Verifica a documentação para mais detalhes sobre como utilizar segredos."
}
},
"filters": {
@ -384,7 +366,7 @@
"title": "Título",
"titlePlaceholder": "O título do filtro memorizado será aqui…",
"description": "Descrição",
"descriptionPlaceholder": "Insere aqui uma descrição para este filtro, pressiona '/' para mais opções…",
"descriptionPlaceholder": "A descrição será aqui…",
"includeNulls": "Incluir Tarefas que não têm um valor definido",
"requireAll": "Requerer que todos os filtros sejam verdadeiros para que uma tarefa apareça",
"showDoneTasks": "Mostrar Tarefas Concluídas",
@ -425,9 +407,7 @@
"alreadyMigrated2": "É possível importar novamente, mas pode criar duplicados. Tens a certeza?",
"confirm": "Tenho a certeza, por favor comece a migração agora!",
"importUpload": "Para importares dados de {name} para o Vikunja, clica no botão abaixo para selecionar um ficheiro.",
"upload": "Carregar ficheiro",
"migrationStartedWillReciveEmail": "O Vikunja irá agora importar as tuas listas/projetos, tarefas, lembretes e ficheiros a partir de {service}. Como isso vai demorar algum tempo, vamos enviar-te um e-mail após a importação estar concluída. Podes agora fechar esta janela.",
"migrationInProgress": "Uma migração está atualmente em curso. Por favor, aguarda até ela estar concluída."
"upload": "Carregar ficheiro"
},
"label": {
"title": "Etiquetas",
@ -498,7 +478,6 @@
"custom": "Personalizado",
"id": "ID",
"created": "Criado em",
"createdBy": "Criado por {0}",
"actions": "Ações",
"cannotBeUndone": "Isto não pode ser revertido!"
},
@ -517,59 +496,24 @@
"edit": "Editar",
"done": "Concluído",
"heading1": "Cabeçalho 1",
"heading1Tooltip": "Título de secção grande.",
"heading2": "Cabeçalho 2",
"heading2Tooltip": "Título de secção médio.",
"heading3": "Cabeçalho 3",
"heading3Tooltip": "Título de secção pequeno.",
"headingSmaller": "Título Menor",
"headingBigger": "Título Maior",
"bold": "Negrito",
"italic": "Itálico",
"strikethrough": "Rasurado",
"underline": "Sublinhar",
"code": "Código",
"codeTooltip": "Capture um trecho de código.",
"quote": "Citação",
"quoteTooltip": "Capture uma citação.",
"bulletList": "Lista de tópicos",
"bulletListTooltip": "Criar uma lista simples de tópicos.",
"unorderedList": "Lista não ordenada",
"orderedList": "Lista ordenada",
"orderedListTooltip": "Cria uma lista com numeração.",
"unorderedList": "Lista Não Ordenada",
"orderedList": "Lista Ordenada",
"cleanBlock": "Limpar Formatação",
"link": "Link",
"image": "Imagem",
"imageTooltip": "Carregar uma imagem do teu computador.",
"table": {
"title": "Tabela",
"insert": "Inserir tabela",
"addColumnBefore": "Adicionar coluna antes",
"addColumnAfter": "Adicionar coluna depois",
"deleteColumn": "Eliminar coluna",
"addRowBefore": "Adicionar linha antes",
"addRowAfter": "Adicionar linha depois",
"deleteRow": "Eliminar linha",
"deleteTable": "Eliminar tabela",
"mergeCells": "Unir células",
"splitCell": "Dividir célula",
"toggleHeaderColumn": "Alternar coluna de cabeçalho",
"toggleHeaderRow": "Alternar linha de cabeçalho",
"toggleHeaderCell": "Alternar célula de cabeçalho",
"mergeOrSplit": "Unir ou dividir",
"fixTables": "Corrigir tabelas"
},
"table": "Tabela",
"horizontalRule": "Linha Horizontal",
"horizontalRuleTooltip": "Dividir uma secção.",
"sideBySide": "Lado-a-lado",
"guide": "Guia",
"text": "Texto",
"textTooltip": "É só começares a escrever texto sem formatação.",
"taskList": "Lista de tarefas",
"taskListTooltip": "Rastrear tarefas com uma lista a fazer.",
"undo": "Desfazer",
"redo": "Refazer",
"placeholder": "Insere algum texto ou pressiona '/' para ver mais opções…"
"guide": "Guia"
},
"multiselect": {
"createPlaceholder": "Criar novo",
@ -663,9 +607,9 @@
"belongsToProject": "Esta tarefa pertence ao projeto '{project}'",
"due": "Vence {at}",
"closePopup": "Fechar janela",
"organization": "Organização",
"management": "Gestão",
"dateAndTime": "Data e hora",
"organization": "Organization",
"management": "Management",
"dateAndTime": "Date and time",
"delete": {
"header": "Eliminar esta tarefa",
"text1": "Tens a certeza que pretendes eliminar esta tarefa?",
@ -743,7 +687,7 @@
"loading": "A carregar comentários…",
"edited": "editado em {date}",
"creating": "A criar comentário…",
"placeholder": "Adicione o teu comentário, pressiona '/' para mais opções…",
"placeholder": "Adiciona o teu comentário…",
"comment": "Comentário",
"delete": "Eliminar este comentário",
"deleteText1": "Tens a certeza que pretendes eliminar este comentário?",
@ -757,7 +701,7 @@
"1week": "1 semana"
},
"description": {
"placeholder": "Insere uma descrição, pressiona '/' para mais opções…",
"placeholder": "Clica aqui para inserir uma descrição…",
"empty": "Nenhuma descrição ainda disponível."
},
"assignee": {
@ -826,7 +770,7 @@
"repeat": {
"everyDay": "Todos os Dias",
"everyWeek": "Todas as Semanas",
"every30d": "A cada 30 Dias",
"every30d": "Every 30 Days",
"mode": "Modo de repetição",
"monthly": "Mensal",
"fromCurrentDate": "Da Data Atual",
@ -908,7 +852,7 @@
"namePlaceholder": "O nome da equipa será aqui…",
"nameRequired": "Por favor, específica um nome.",
"description": "Descrição",
"descriptionPlaceholder": "Descreve aqui a equipa, pressiona '/' para mais opções…",
"descriptionPlaceholder": "A descrição da equipa será aqui…",
"admin": "Administrador",
"member": "Membro"
}
@ -936,8 +880,7 @@
"description": "Alternar edição da descrição da tarefa",
"delete": "Eliminar esta tarefa",
"priority": "Alterar a prioridade desta tarefa",
"favorite": "Marcar / Desmarcar esta tarefa como favorita",
"save": "Salvar a tarefa atual"
"favorite": "Marcar / Desmarcar esta tarefa como favorita"
},
"project": {
"title": "Vista do Projeto",
@ -975,7 +918,7 @@
"urlPlaceholder": "ex.: https://localhost:3456",
"change": "alterar",
"use": "A utilizar a instalação do Vikunja em {0}",
"error": "Não foi possível encontrar ou utilizar a instalação Vikunja em \"{domain}\". Por favor, verifica se o url tem o formato correto e se consegues aceder-lhe diretamente e tenta novamente.",
"error": "Could not find or use Vikunja installation at \"{domain}\". Please check if the url has the correct format and you can reach it when accessing it directly and try again.",
"success": "A utilizar a instalação do Vikunja em \"{domain}\".",
"urlRequired": "É necessário um url."
},
@ -987,9 +930,7 @@
"notification": {
"title": "Notificações",
"none": "Não tens nenhuma notificação. Tem um bom dia!",
"explainer": "As notificações aparecerão aqui quando ocorrem ações em projetos ou tarefas às quais estejas subscrito.",
"markAllRead": "Marcar todas as notificações como lidas",
"markAllReadSuccess": "Todas as notificações foram marcadas como lidas."
"explainer": "As notificações aparecerão aqui quando ocorrem ações em projetos ou tarefas às quais estejas subscrito."
},
"quickActions": {
"commands": "Comandos",

View File

@ -6,7 +6,6 @@
"welcomeEvening": "Good Evening {username}!",
"lastViewed": "Last viewed",
"addToHomeScreen": "Add this app to your home screen for faster access and improved experience.",
"goToOverview": "Go to overview",
"project": {
"importText": "Import your projects and tasks from other services into Vikunja:",
"import": "Import your data into Vikunja"
@ -177,7 +176,6 @@
"title": "Delete your Vikunja Account",
"text1": "The deletion of your account is permanent and cannot be undone. We will delete all your projects, tasks and everything associated with it.",
"text2": "To proceed, please enter your password. You will receive an email with further instructions.",
"text3": "To proceed, please press the button below. You will receive an email with further instructions.",
"confirm": "Delete my account",
"requestSuccess": "The request was successful. You'll receive an email with further instructions.",
"passwordRequired": "Please enter your password.",
@ -185,7 +183,6 @@
"scheduled": "We will delete your Vikunja account at {date} ({dateSince}).",
"scheduledCancel": "To cancel the deletion of your account, click here.",
"scheduledCancelText": "To cancel the deletion of your account, please enter your password below:",
"scheduledCancelButton": "To cancel the deletion of your account, please press the button below:",
"scheduledCancelConfirm": "Cancel the deletion of my account",
"scheduledCancelSuccess": "We will not delete your account."
},
@ -259,7 +256,7 @@
"identifier": "Project Identifier",
"identifierPlaceholder": "The project identifier goes here…",
"description": "Description",
"descriptionPlaceholder": "Enter a description for this project, hit '/' for more options…",
"descriptionPlaceholder": "The projects description goes here…",
"color": "Color",
"success": "The project was successfully updated."
},
@ -360,21 +357,6 @@
"favorites": {
"title": "Favorites"
}
},
"webhooks": {
"title": "Webhooks",
"targetUrl": "Target URL",
"targetUrlInvalid": "Please provide a valid URL.",
"events": "Events",
"eventsHint": "Select all events this webhook should recieve updates for (within the current project).",
"mustSelectEvents": "You must select at least one event.",
"delete": "Delete this webhook",
"deleteText": "Are you sure you want to delete this webhook? External targets will not be notified of its events anymore.",
"deleteSuccess": "The webhook was successfully deleted.",
"create": "Create webhook",
"secret": "Secret",
"secretHint": "If provided, all requests to the webhook target URL will be signed using HMAC.",
"secretDocs": "Check out the docs for more details about how to use secrets."
}
},
"filters": {
@ -384,7 +366,7 @@
"title": "Title",
"titlePlaceholder": "The saved filter title goes here…",
"description": "Description",
"descriptionPlaceholder": "Add a description for this filter here, hit '/' for more options…",
"descriptionPlaceholder": "The description goes here…",
"includeNulls": "Include Tasks which don't have a value set",
"requireAll": "Require all filters to be true for a task to show up",
"showDoneTasks": "Show Done Tasks",
@ -425,9 +407,7 @@
"alreadyMigrated2": "Importing again is possible, but might create duplicates. Are you sure?",
"confirm": "I am sure, please start migrating now!",
"importUpload": "To import data from {name} into Vikunja, click the button below to select a file.",
"upload": "Upload file",
"migrationStartedWillReciveEmail": "Vikunja will now import your lists/projects, tasks, notes, reminders and files from {service}. As this will take a while, we will send you an email once done. You can close this window now.",
"migrationInProgress": "A migration is currently in progress. Please wait until it is done."
"upload": "Upload file"
},
"label": {
"title": "Labels",
@ -498,7 +478,6 @@
"custom": "Custom",
"id": "ID",
"created": "Created at",
"createdBy": "Created by {0}",
"actions": "Actions",
"cannotBeUndone": "This cannot be undone!"
},
@ -517,59 +496,24 @@
"edit": "Edit",
"done": "Done",
"heading1": "Heading 1",
"heading1Tooltip": "Big section heading.",
"heading2": "Heading 2",
"heading2Tooltip": "Medium section heading.",
"heading3": "Heading 3",
"heading3Tooltip": "Smaller section header.",
"headingSmaller": "Heading Smaller",
"headingBigger": "Heading Bigger",
"bold": "Bold",
"italic": "Italic",
"strikethrough": "Strikethrough",
"underline": "Underline",
"code": "Code",
"codeTooltip": "Capture a code snippet.",
"quote": "Quote",
"quoteTooltip": "Capture a quote.",
"bulletList": "Bullet list",
"bulletListTooltip": "Create a simple bullet list.",
"unorderedList": "Unordered list",
"orderedList": "Ordered list",
"orderedListTooltip": "Create a list with numbering.",
"unorderedList": "Unordered List",
"orderedList": "Ordered List",
"cleanBlock": "Clean Block",
"link": "Link",
"image": "Image",
"imageTooltip": "Upload an image from your computer.",
"table": {
"title": "Table",
"insert": "Insert table",
"addColumnBefore": "Add column before",
"addColumnAfter": "Add column after",
"deleteColumn": "Delete column",
"addRowBefore": "Add row before",
"addRowAfter": "Add row after",
"deleteRow": "Delete row",
"deleteTable": "Delete table",
"mergeCells": "Merge cells",
"splitCell": "Split cell",
"toggleHeaderColumn": "Toggle header column",
"toggleHeaderRow": "Toggle header row",
"toggleHeaderCell": "Toggle header cell",
"mergeOrSplit": "Merge or split",
"fixTables": "Fix tables"
},
"table": "Table",
"horizontalRule": "Horizontal Rule",
"horizontalRuleTooltip": "Divide a section.",
"sideBySide": "Side By Side",
"guide": "Guide",
"text": "Text",
"textTooltip": "Just start typing with plain text.",
"taskList": "Task list",
"taskListTooltip": "Track tasks with a to-do list.",
"undo": "Undo",
"redo": "Redo",
"placeholder": "Type some text or hit '/' to see more options…"
"guide": "Guide"
},
"multiselect": {
"createPlaceholder": "Create new",
@ -743,7 +687,7 @@
"loading": "Loading comments…",
"edited": "edited {date}",
"creating": "Creating comment…",
"placeholder": "Add your comment, hit '/' for more options…",
"placeholder": "Add your comment…",
"comment": "Comment",
"delete": "Delete this comment",
"deleteText1": "Are you sure you want to delete this comment?",
@ -757,7 +701,7 @@
"1week": "1 week"
},
"description": {
"placeholder": "Enter a description, hit '/' for more options…",
"placeholder": "Click here to enter a description…",
"empty": "No description available yet."
},
"assignee": {
@ -908,7 +852,7 @@
"namePlaceholder": "The team's name goes here…",
"nameRequired": "Please specify a name.",
"description": "Description",
"descriptionPlaceholder": "Describe the team here, hit '/' for more options…",
"descriptionPlaceholder": "The teams description goes here…",
"admin": "Admin",
"member": "Member"
}
@ -936,8 +880,7 @@
"description": "Toggle editing of the task description",
"delete": "Delete this task",
"priority": "Change the priority of this task",
"favorite": "Mark this task as favorite / unfavorite",
"save": "Save the current task"
"favorite": "Mark this task as favorite / unfavorite"
},
"project": {
"title": "Project Views",
@ -987,9 +930,7 @@
"notification": {
"title": "Notifications",
"none": "You don't have any notifications. Have a nice day!",
"explainer": "Notifications will appear here when actions projects or tasks you subscribed to happen.",
"markAllRead": "Mark all notifications as read",
"markAllReadSuccess": "Successfully marked all notifications as read."
"explainer": "Notifications will appear here when actions projects or tasks you subscribed to happen."
},
"quickActions": {
"commands": "Commands",

View File

@ -6,16 +6,15 @@
"welcomeEvening": "Добрый вечер, {username}!",
"lastViewed": "Последние просмотренные",
"addToHomeScreen": "Add this app to your home screen for faster access and improved experience.",
"goToOverview": "Go to overview",
"project": {
"importText": "Импортировать проекты и задачи из других сервисов в Vikunja:",
"import": "Импорт данных в Vikunja"
}
},
"demo": {
"title": "Этот сервер находится в демо-режиме. Не используйте его для реальных данных!",
"everythingWillBeDeleted": "Все данные регулярно удаляются!",
"accountWillBeDeleted": "Однажды ваш аккаунт будет удалён вместе со всеми созданными проектами, задачами и вложениями."
"title": "This instance is in demo mode. Do not use this for real data!",
"everythingWillBeDeleted": "Everything will be deleted in regular intervals!",
"accountWillBeDeleted": "Your account will be deleted, including all projects, tasks and attachments you might create."
},
"404": {
"title": "Не найдено",
@ -83,8 +82,8 @@
"savedSuccess": "Настройки обновлены.",
"emailReminders": "Присылать мне напоминания о задачах на e-mail",
"overdueReminders": "Присылать сводку о просроченных задачах каждый день",
"discoverableByName": "Разрешить другим пользователям добавлять меня в состав команд или проектов при поиске моего имени",
"discoverableByEmail": "Разрешить другим пользователям добавлять меня в состав команд или проектов при поиске моего полного email",
"discoverableByName": "Allow other users to add me as a member to teams or projects when they search for my name",
"discoverableByEmail": "Allow other users to add me as a member to teams or projects when they search for my full email",
"playSoundWhenDone": "Проигрывать звук, когда задача помечается завершённой",
"weekStart": "Первый день недели",
"weekStartSunday": "Воскресенье",
@ -93,7 +92,7 @@
"defaultProject": "Проект по умолчанию",
"timezone": "Часовой пояс",
"overdueTasksRemindersTime": "Время напоминания о невыполненных задачах",
"filterUsedOnOverview": "Сохранённый фильтр, используемый на странице обзора"
"filterUsedOnOverview": "Saved filter used on the overview page"
},
"totp": {
"title": "Двухфакторная аутентификация",
@ -147,29 +146,29 @@
}
},
"apiTokens": {
"title": "Токены API",
"general": "Токены API позволяют использовать Vikunja API без использования данных для входа пользователя.",
"apiDocs": "Документация API",
"createAToken": "Создать токен",
"createToken": "Создать токен",
"30d": "30 дней",
"60d": "60 дней",
"90d": "90 дней",
"permissionExplanation": "Разрешения позволяют выбрать, какие действия можно выполнять с использованием этого токена.",
"titleRequired": "Название обязательно",
"expired": "Срок действия этого токена истёк {ago}.",
"tokenCreatedSuccess": "Ваш новый токен: {token}",
"tokenCreatedNotSeeAgain": "Сохраните его в безопасном месте, вы не увидите его снова!",
"title": "API Tokens",
"general": "API tokens allow you to use Vikunja's API without user credentials.",
"apiDocs": "Check out the api docs",
"createAToken": "Create a token",
"createToken": "Create token",
"30d": "30 Days",
"60d": "60 Days",
"90d": "90 Days",
"permissionExplanation": "Permissions allow you to scope what an api token is allowed to do.",
"titleRequired": "The title is required",
"expired": "This token has expired {ago}.",
"tokenCreatedSuccess": "Here is your new api token: {token}",
"tokenCreatedNotSeeAgain": "Store it in a secure location, you won't see it again!",
"delete": {
"header": "Удалить этот токен",
"text1": "Удалить токен «{token}»?",
"text2": "Все приложения или интеграции, использующие его, потеряют доступ. Это действие отменить нельзя."
"header": "Delete this token",
"text1": "Are you sure you want to delete the token \"{token}\"?",
"text2": "This will revoke access to all applications or integrations using it. You cannot undo this."
},
"attributes": {
"title": "Название",
"title": "Title",
"titlePlaceholder": "Enter a title you will recognize later",
"expiresAt": "Срок действия",
"permissions": "Разрешения"
"expiresAt": "Expires at",
"permissions": "Permissions"
}
}
},
@ -177,7 +176,6 @@
"title": "Удалить свой аккаунт VIkunja",
"text1": "Удаление аккаунта необратимо. Мы удалим все ваши проекты, задачи и всё связанное с ними.",
"text2": "Для продолжения введите свой пароль. На почту будет отправлено письмо с дальнейшими инструкциями.",
"text3": "Для продолжения нажмите кнопку внизу. На почту будет отправлено письмо с дальнейшими инструкциями.",
"confirm": "Удалить мой аккаунт",
"requestSuccess": "Запрос успешно выполнен. На почту будет отправлено письмо с дальнейшими инструкциями.",
"passwordRequired": "Введите свой пароль.",
@ -185,7 +183,6 @@
"scheduled": "Мы удалим ваш аккаунт Vikunja {date} ({dateSince}).",
"scheduledCancel": "Что отменить удаление аккаунта, нажмите сюда.",
"scheduledCancelText": "Чтобы отменить удаление аккаунта, введите свой пароль ниже:",
"scheduledCancelButton": "Чтобы отменить удаление аккаунта, нажмите кнопку внизу:",
"scheduledCancelConfirm": "Отменить удаление моего аккаунта",
"scheduledCancelSuccess": "Мы не будем удалять ваш аккаунт."
},
@ -259,8 +256,8 @@
"identifier": "Идентификатор проекта",
"identifierPlaceholder": "Введите идентификатор проекта…",
"description": "Описание",
"descriptionPlaceholder": "Enter a description for this project, hit '/' for more options…",
"color": "Цвет",
"descriptionPlaceholder": "Введите описание проекта…",
"color": "Color",
"success": "Проект успешно обновлён."
},
"share": {
@ -276,7 +273,7 @@
"namePlaceholder": "напр. Lorem Ipsum",
"nameExplanation": "Все действия, выполненные через эту ссылку, будут подписаны этим именем.",
"password": "Пароль (необязательно)",
"passwordExplanation": "Пользователь будет должен ввести пароль для входа.",
"passwordExplanation": "When signing in, the user will be required to enter this password.",
"noName": "Без имени",
"remove": "Удалить ссылку для обмена",
"removeText": "Удалить эту ссылку для обмена? Больше не удастся получить доступ к проекту через эту ссылку. Это действие отменить нельзя!",
@ -339,9 +336,9 @@
"doneBucketHint": "Все задачи, помещённые в эту колонку, автоматически отмечаются как завершённые.",
"doneBucketHintExtended": "Все задачи, перенесённые в колонку завершённых, будут помечены как завершённые. Все задачи, помеченные как завершённые, также будут перемещены в эту колонку.",
"doneBucketSavedSuccess": "Колонка завершённых была успешно сохранена.",
"defaultBucket": "Колонка по умолчанию",
"defaultBucketHint": "При создании задач без указания колонки они будут добавлены в эту колонку.",
"defaultBucketSavedSuccess": "Колонка по умолчанию была успешно сохранена.",
"defaultBucket": "Default bucket",
"defaultBucketHint": "When creating tasks without specifying a bucket, they will be added to this bucket.",
"defaultBucketSavedSuccess": "The default bucket has been saved successfully.",
"deleteLast": "Нельзя удалить последнюю колонку.",
"addTaskPlaceholder": "Введите название задачи…",
"addTask": "Добавить задачу",
@ -360,21 +357,6 @@
"favorites": {
"title": "Избранное"
}
},
"webhooks": {
"title": "Вебхуки",
"targetUrl": "URL обработчика",
"targetUrlInvalid": "Укажите корректный URL.",
"events": "События",
"eventsHint": "Выберите все события, для которых этот вебхук должен получать обновления (в пределах текущего проекта).",
"mustSelectEvents": "Выберите хотя бы одно событие.",
"delete": "Удалить этот вебхук",
"deleteText": "Удалить этот вебхук? Внешние обработчики больше не будет получать события этого вебхука.",
"deleteSuccess": "Вебхук успешно удалён.",
"create": "Создать вебхук",
"secret": "Секрет",
"secretHint": "Если указан, все запросы к URL обработчика будут подписаны с помощью HMAC.",
"secretDocs": "Подробнее об использовании секретов в документации."
}
},
"filters": {
@ -384,7 +366,7 @@
"title": "Название",
"titlePlaceholder": "Введите название сохранённого фильтра…",
"description": "Описание",
"descriptionPlaceholder": "Add a description for this filter here, hit '/' for more options…",
"descriptionPlaceholder": "Введите описание…",
"includeNulls": "Включать задачи, у которых не установлено значение",
"requireAll": "Для отображения задачи требовать истинность всех фильтров",
"showDoneTasks": "Показывать завершённые задачи",
@ -398,7 +380,7 @@
},
"create": {
"title": "Создать сохранённый фильтр",
"description": "Сохранённый фильтр — это виртуальный проект, содержимое которого выбирается с помощью фильтров в момент его просмотра.",
"description": "A saved filter is a virtual project which is computed from a set of filters each time it is accessed.",
"action": "Создать новый сохранённый фильтр",
"titleRequired": "Укажите название фильтра."
},
@ -425,9 +407,7 @@
"alreadyMigrated2": "Повторный импорт возможен, но могут возникнуть дубликаты. Продолжить?",
"confirm": "Я уверен, давай начнём миграцию!",
"importUpload": "Чтобы импортировать данные из {name} в Vikunja, нажмите кнопку ниже для выбора файла.",
"upload": "Загрузить файл",
"migrationStartedWillReciveEmail": "Vikunja will now import your lists/projects, tasks, notes, reminders and files from {service}. As this will take a while, we will send you an email once done. You can close this window now.",
"migrationInProgress": "A migration is currently in progress. Please wait until it is done."
"upload": "Загрузить файл"
},
"label": {
"title": "Метки",
@ -498,7 +478,6 @@
"custom": "Настраиваемый",
"id": "ID",
"created": "Дата создания",
"createdBy": "Created by {0}",
"actions": "Действия",
"cannotBeUndone": "Это действие отменить нельзя!"
},
@ -517,59 +496,24 @@
"edit": "Изменить",
"done": "Готово",
"heading1": "Заголовок 1",
"heading1Tooltip": "Big section heading.",
"heading2": "Заголовок 2",
"heading2Tooltip": "Medium section heading.",
"heading3": "Заголовок 3",
"heading3Tooltip": "Smaller section header.",
"headingSmaller": "Заголовок меньше",
"headingBigger": "Заголовок больше",
"bold": "Жирный",
"italic": "Курсив",
"strikethrough": "Зачёркнутый",
"underline": "Подчёркнутый",
"code": "Код",
"codeTooltip": "Capture a code snippet.",
"quote": "Цитата",
"quoteTooltip": "Capture a quote.",
"bulletList": "Bullet list",
"bulletListTooltip": "Create a simple bullet list.",
"unorderedList": "Unordered list",
"orderedList": "Ordered list",
"orderedListTooltip": "Create a list with numbering.",
"unorderedList": "Маркированный список",
"orderedList": "Нумерованный список",
"cleanBlock": "Очистить блок",
"link": "Ссылка",
"image": "Изображение",
"imageTooltip": "Upload an image from your computer.",
"table": {
"title": "Таблица",
"insert": "Insert table",
"addColumnBefore": "Add column before",
"addColumnAfter": "Add column after",
"deleteColumn": "Delete column",
"addRowBefore": "Add row before",
"addRowAfter": "Add row after",
"deleteRow": "Delete row",
"deleteTable": "Delete table",
"mergeCells": "Merge cells",
"splitCell": "Split cell",
"toggleHeaderColumn": "Toggle header column",
"toggleHeaderRow": "Toggle header row",
"toggleHeaderCell": "Toggle header cell",
"mergeOrSplit": "Merge or split",
"fixTables": "Fix tables"
},
"table": "Таблица",
"horizontalRule": "Разделитель",
"horizontalRuleTooltip": "Divide a section.",
"sideBySide": "Side By Side",
"guide": "Руководство",
"text": "Text",
"textTooltip": "Just start typing with plain text.",
"taskList": "Список задач",
"taskListTooltip": "Track tasks with a to-do list.",
"undo": "Отменить",
"redo": "Вернуть",
"placeholder": "Type some text or hit '/' to see more options…"
"guide": "Руководство"
},
"multiselect": {
"createPlaceholder": "Создать",
@ -605,8 +549,8 @@
"add1Day": "Добавить один день",
"minus1Day": "Вычесть один день",
"roundDay": "Округление вниз до начала дня",
"supportedUnits": "Поддерживаемые единицы времени",
"someExamples": "Примеры выражений",
"supportedUnits": "Supported time units",
"someExamples": "Examples of time expressions",
"units": {
"seconds": "Секунды",
"minutes": "Минуты",
@ -663,9 +607,9 @@
"belongsToProject": "Задача принадлежит проекту «{project}»",
"due": "Истекает {at}",
"closePopup": "Закрыть всплывающее окно",
"organization": "Организация",
"management": "Управление",
"dateAndTime": "Дата и время",
"organization": "Organization",
"management": "Management",
"dateAndTime": "Date and time",
"delete": {
"header": "Удалить задачу",
"text1": "Удалить эту задачу?",
@ -743,7 +687,7 @@
"loading": "Загрузка комментариев…",
"edited": "изменено {date}",
"creating": "Комментируем…",
"placeholder": "Add your comment, hit '/' for more options…",
"placeholder": "Добавить комментарий…",
"comment": "Комментировать",
"delete": "Удалить комментарий",
"deleteText1": "Удалить этот комментарий?",
@ -757,7 +701,7 @@
"1week": "1 неделя"
},
"description": {
"placeholder": "Enter a description, hit '/' for more options…",
"placeholder": "Нажмите сюда для ввода описания…",
"empty": "Описания ещё нет."
},
"assignee": {
@ -826,7 +770,7 @@
"repeat": {
"everyDay": "Каждый день",
"everyWeek": "Каждую неделю",
"every30d": "Каждые 30 дней",
"every30d": "Every 30 Days",
"mode": "Режим повтора",
"monthly": "Ежемесячно",
"fromCurrentDate": "От сегодняшей даты",
@ -908,7 +852,7 @@
"namePlaceholder": "Имя команды здесь…",
"nameRequired": "Пожалуйста, укажите имя.",
"description": "Описание",
"descriptionPlaceholder": "Describe the team here, hit '/' for more options…",
"descriptionPlaceholder": "Описание команды здесь…",
"admin": "Администратор",
"member": "Участник"
}
@ -936,8 +880,7 @@
"description": "Включить изменение описания задачи",
"delete": "Удалить задачу",
"priority": "Изменить приоритет задачи",
"favorite": "Добавить задачу в избранное или удалить из избранного",
"save": "Сохранить текущую задачу"
"favorite": "Mark this task as favorite / unfavorite"
},
"project": {
"title": "Просмотр проекта",
@ -987,9 +930,7 @@
"notification": {
"title": "Уведомления",
"none": "Уведомлений нет. Хорошего дня!",
"explainer": "Здесь появятся уведомления, когда что-нибудь произойдёт с проектами или задачами, на которые вы подписаны.",
"markAllRead": "Отметить всё как прочитанное",
"markAllReadSuccess": "Все уведомления отмечены как прочитанные."
"explainer": "Здесь появятся уведомления, когда что-нибудь произойдёт с проектами или задачами, на которые вы подписаны."
},
"quickActions": {
"commands": "Команды",

View File

@ -6,7 +6,6 @@
"welcomeEvening": "Good Evening {username}!",
"lastViewed": "Last viewed",
"addToHomeScreen": "Add this app to your home screen for faster access and improved experience.",
"goToOverview": "Go to overview",
"project": {
"importText": "Import your projects and tasks from other services into Vikunja:",
"import": "Import your data into Vikunja"
@ -177,7 +176,6 @@
"title": "Delete your Vikunja Account",
"text1": "The deletion of your account is permanent and cannot be undone. We will delete all your projects, tasks and everything associated with it.",
"text2": "To proceed, please enter your password. You will receive an email with further instructions.",
"text3": "To proceed, please press the button below. You will receive an email with further instructions.",
"confirm": "Delete my account",
"requestSuccess": "The request was successful. You'll receive an email with further instructions.",
"passwordRequired": "Please enter your password.",
@ -185,7 +183,6 @@
"scheduled": "We will delete your Vikunja account at {date} ({dateSince}).",
"scheduledCancel": "To cancel the deletion of your account, click here.",
"scheduledCancelText": "To cancel the deletion of your account, please enter your password below:",
"scheduledCancelButton": "To cancel the deletion of your account, please press the button below:",
"scheduledCancelConfirm": "Cancel the deletion of my account",
"scheduledCancelSuccess": "We will not delete your account."
},
@ -259,7 +256,7 @@
"identifier": "Project Identifier",
"identifierPlaceholder": "The project identifier goes here…",
"description": "Description",
"descriptionPlaceholder": "Enter a description for this project, hit '/' for more options…",
"descriptionPlaceholder": "The projects description goes here…",
"color": "Color",
"success": "The project was successfully updated."
},
@ -360,21 +357,6 @@
"favorites": {
"title": "Favorites"
}
},
"webhooks": {
"title": "Webhooks",
"targetUrl": "Target URL",
"targetUrlInvalid": "Please provide a valid URL.",
"events": "Events",
"eventsHint": "Select all events this webhook should recieve updates for (within the current project).",
"mustSelectEvents": "You must select at least one event.",
"delete": "Delete this webhook",
"deleteText": "Are you sure you want to delete this webhook? External targets will not be notified of its events anymore.",
"deleteSuccess": "The webhook was successfully deleted.",
"create": "Create webhook",
"secret": "Secret",
"secretHint": "If provided, all requests to the webhook target URL will be signed using HMAC.",
"secretDocs": "Check out the docs for more details about how to use secrets."
}
},
"filters": {
@ -384,7 +366,7 @@
"title": "Title",
"titlePlaceholder": "The saved filter title goes here…",
"description": "Description",
"descriptionPlaceholder": "Add a description for this filter here, hit '/' for more options…",
"descriptionPlaceholder": "The description goes here…",
"includeNulls": "Include Tasks which don't have a value set",
"requireAll": "Require all filters to be true for a task to show up",
"showDoneTasks": "Show Done Tasks",
@ -425,9 +407,7 @@
"alreadyMigrated2": "Importing again is possible, but might create duplicates. Are you sure?",
"confirm": "I am sure, please start migrating now!",
"importUpload": "To import data from {name} into Vikunja, click the button below to select a file.",
"upload": "Upload file",
"migrationStartedWillReciveEmail": "Vikunja will now import your lists/projects, tasks, notes, reminders and files from {service}. As this will take a while, we will send you an email once done. You can close this window now.",
"migrationInProgress": "A migration is currently in progress. Please wait until it is done."
"upload": "Upload file"
},
"label": {
"title": "Labels",
@ -498,7 +478,6 @@
"custom": "Custom",
"id": "ID",
"created": "Created at",
"createdBy": "Created by {0}",
"actions": "Actions",
"cannotBeUndone": "This cannot be undone!"
},
@ -517,59 +496,24 @@
"edit": "Edit",
"done": "Done",
"heading1": "Heading 1",
"heading1Tooltip": "Big section heading.",
"heading2": "Heading 2",
"heading2Tooltip": "Medium section heading.",
"heading3": "Heading 3",
"heading3Tooltip": "Smaller section header.",
"headingSmaller": "Heading Smaller",
"headingBigger": "Heading Bigger",
"bold": "Bold",
"italic": "Italic",
"strikethrough": "Strikethrough",
"underline": "Underline",
"code": "Code",
"codeTooltip": "Capture a code snippet.",
"quote": "Quote",
"quoteTooltip": "Capture a quote.",
"bulletList": "Bullet list",
"bulletListTooltip": "Create a simple bullet list.",
"unorderedList": "Unordered list",
"orderedList": "Ordered list",
"orderedListTooltip": "Create a list with numbering.",
"unorderedList": "Unordered List",
"orderedList": "Ordered List",
"cleanBlock": "Clean Block",
"link": "Link",
"image": "Image",
"imageTooltip": "Upload an image from your computer.",
"table": {
"title": "Table",
"insert": "Insert table",
"addColumnBefore": "Add column before",
"addColumnAfter": "Add column after",
"deleteColumn": "Delete column",
"addRowBefore": "Add row before",
"addRowAfter": "Add row after",
"deleteRow": "Delete row",
"deleteTable": "Delete table",
"mergeCells": "Merge cells",
"splitCell": "Split cell",
"toggleHeaderColumn": "Toggle header column",
"toggleHeaderRow": "Toggle header row",
"toggleHeaderCell": "Toggle header cell",
"mergeOrSplit": "Merge or split",
"fixTables": "Fix tables"
},
"table": "Table",
"horizontalRule": "Horizontal Rule",
"horizontalRuleTooltip": "Divide a section.",
"sideBySide": "Side By Side",
"guide": "Guide",
"text": "Text",
"textTooltip": "Just start typing with plain text.",
"taskList": "Task list",
"taskListTooltip": "Track tasks with a to-do list.",
"undo": "Undo",
"redo": "Redo",
"placeholder": "Type some text or hit '/' to see more options…"
"guide": "Guide"
},
"multiselect": {
"createPlaceholder": "Create new",
@ -743,7 +687,7 @@
"loading": "Loading comments…",
"edited": "edited {date}",
"creating": "Creating comment…",
"placeholder": "Add your comment, hit '/' for more options…",
"placeholder": "Add your comment…",
"comment": "Comment",
"delete": "Delete this comment",
"deleteText1": "Are you sure you want to delete this comment?",
@ -757,7 +701,7 @@
"1week": "1 week"
},
"description": {
"placeholder": "Enter a description, hit '/' for more options…",
"placeholder": "Click here to enter a description…",
"empty": "No description available yet."
},
"assignee": {
@ -908,7 +852,7 @@
"namePlaceholder": "The team's name goes here…",
"nameRequired": "Please specify a name.",
"description": "Description",
"descriptionPlaceholder": "Describe the team here, hit '/' for more options…",
"descriptionPlaceholder": "The teams description goes here…",
"admin": "Admin",
"member": "Member"
}
@ -936,8 +880,7 @@
"description": "Toggle editing of the task description",
"delete": "Delete this task",
"priority": "Change the priority of this task",
"favorite": "Mark this task as favorite / unfavorite",
"save": "Save the current task"
"favorite": "Mark this task as favorite / unfavorite"
},
"project": {
"title": "Project Views",
@ -987,9 +930,7 @@
"notification": {
"title": "Notifications",
"none": "You don't have any notifications. Have a nice day!",
"explainer": "Notifications will appear here when actions projects or tasks you subscribed to happen.",
"markAllRead": "Mark all notifications as read",
"markAllReadSuccess": "Successfully marked all notifications as read."
"explainer": "Notifications will appear here when actions projects or tasks you subscribed to happen."
},
"quickActions": {
"commands": "Commands",

File diff suppressed because it is too large Load Diff

View File

@ -6,7 +6,6 @@
"welcomeEvening": "Good Evening {username}!",
"lastViewed": "Last viewed",
"addToHomeScreen": "Add this app to your home screen for faster access and improved experience.",
"goToOverview": "Go to overview",
"project": {
"importText": "Import your projects and tasks from other services into Vikunja:",
"import": "Import your data into Vikunja"
@ -177,7 +176,6 @@
"title": "Delete your Vikunja Account",
"text1": "The deletion of your account is permanent and cannot be undone. We will delete all your projects, tasks and everything associated with it.",
"text2": "To proceed, please enter your password. You will receive an email with further instructions.",
"text3": "To proceed, please press the button below. You will receive an email with further instructions.",
"confirm": "Delete my account",
"requestSuccess": "The request was successful. You'll receive an email with further instructions.",
"passwordRequired": "Please enter your password.",
@ -185,7 +183,6 @@
"scheduled": "We will delete your Vikunja account at {date} ({dateSince}).",
"scheduledCancel": "To cancel the deletion of your account, click here.",
"scheduledCancelText": "To cancel the deletion of your account, please enter your password below:",
"scheduledCancelButton": "To cancel the deletion of your account, please press the button below:",
"scheduledCancelConfirm": "Cancel the deletion of my account",
"scheduledCancelSuccess": "We will not delete your account."
},
@ -259,7 +256,7 @@
"identifier": "Project Identifier",
"identifierPlaceholder": "The project identifier goes here…",
"description": "Description",
"descriptionPlaceholder": "Enter a description for this project, hit '/' for more options…",
"descriptionPlaceholder": "The projects description goes here…",
"color": "Color",
"success": "The project was successfully updated."
},
@ -360,21 +357,6 @@
"favorites": {
"title": "Favorites"
}
},
"webhooks": {
"title": "Webhooks",
"targetUrl": "Target URL",
"targetUrlInvalid": "Please provide a valid URL.",
"events": "Events",
"eventsHint": "Select all events this webhook should recieve updates for (within the current project).",
"mustSelectEvents": "You must select at least one event.",
"delete": "Delete this webhook",
"deleteText": "Are you sure you want to delete this webhook? External targets will not be notified of its events anymore.",
"deleteSuccess": "The webhook was successfully deleted.",
"create": "Create webhook",
"secret": "Secret",
"secretHint": "If provided, all requests to the webhook target URL will be signed using HMAC.",
"secretDocs": "Check out the docs for more details about how to use secrets."
}
},
"filters": {
@ -384,7 +366,7 @@
"title": "Title",
"titlePlaceholder": "The saved filter title goes here…",
"description": "Description",
"descriptionPlaceholder": "Add a description for this filter here, hit '/' for more options…",
"descriptionPlaceholder": "The description goes here…",
"includeNulls": "Include Tasks which don't have a value set",
"requireAll": "Require all filters to be true for a task to show up",
"showDoneTasks": "Show Done Tasks",
@ -425,9 +407,7 @@
"alreadyMigrated2": "Importing again is possible, but might create duplicates. Are you sure?",
"confirm": "I am sure, please start migrating now!",
"importUpload": "To import data from {name} into Vikunja, click the button below to select a file.",
"upload": "Upload file",
"migrationStartedWillReciveEmail": "Vikunja will now import your lists/projects, tasks, notes, reminders and files from {service}. As this will take a while, we will send you an email once done. You can close this window now.",
"migrationInProgress": "A migration is currently in progress. Please wait until it is done."
"upload": "Upload file"
},
"label": {
"title": "Labels",
@ -498,7 +478,6 @@
"custom": "Custom",
"id": "ID",
"created": "Created at",
"createdBy": "Created by {0}",
"actions": "Actions",
"cannotBeUndone": "This cannot be undone!"
},
@ -517,59 +496,24 @@
"edit": "Edit",
"done": "Done",
"heading1": "Heading 1",
"heading1Tooltip": "Big section heading.",
"heading2": "Heading 2",
"heading2Tooltip": "Medium section heading.",
"heading3": "Heading 3",
"heading3Tooltip": "Smaller section header.",
"headingSmaller": "Heading Smaller",
"headingBigger": "Heading Bigger",
"bold": "Bold",
"italic": "Italic",
"strikethrough": "Strikethrough",
"underline": "Underline",
"code": "Code",
"codeTooltip": "Capture a code snippet.",
"quote": "Quote",
"quoteTooltip": "Capture a quote.",
"bulletList": "Bullet list",
"bulletListTooltip": "Create a simple bullet list.",
"unorderedList": "Unordered list",
"orderedList": "Ordered list",
"orderedListTooltip": "Create a list with numbering.",
"unorderedList": "Unordered List",
"orderedList": "Ordered List",
"cleanBlock": "Clean Block",
"link": "Link",
"image": "Image",
"imageTooltip": "Upload an image from your computer.",
"table": {
"title": "Table",
"insert": "Insert table",
"addColumnBefore": "Add column before",
"addColumnAfter": "Add column after",
"deleteColumn": "Delete column",
"addRowBefore": "Add row before",
"addRowAfter": "Add row after",
"deleteRow": "Delete row",
"deleteTable": "Delete table",
"mergeCells": "Merge cells",
"splitCell": "Split cell",
"toggleHeaderColumn": "Toggle header column",
"toggleHeaderRow": "Toggle header row",
"toggleHeaderCell": "Toggle header cell",
"mergeOrSplit": "Merge or split",
"fixTables": "Fix tables"
},
"table": "Table",
"horizontalRule": "Horizontal Rule",
"horizontalRuleTooltip": "Divide a section.",
"sideBySide": "Side By Side",
"guide": "Guide",
"text": "Text",
"textTooltip": "Just start typing with plain text.",
"taskList": "Task list",
"taskListTooltip": "Track tasks with a to-do list.",
"undo": "Undo",
"redo": "Redo",
"placeholder": "Type some text or hit '/' to see more options…"
"guide": "Guide"
},
"multiselect": {
"createPlaceholder": "Create new",
@ -743,7 +687,7 @@
"loading": "Loading comments…",
"edited": "edited {date}",
"creating": "Creating comment…",
"placeholder": "Add your comment, hit '/' for more options…",
"placeholder": "Add your comment…",
"comment": "Comment",
"delete": "Delete this comment",
"deleteText1": "Are you sure you want to delete this comment?",
@ -757,7 +701,7 @@
"1week": "1 week"
},
"description": {
"placeholder": "Enter a description, hit '/' for more options…",
"placeholder": "Click here to enter a description…",
"empty": "No description available yet."
},
"assignee": {
@ -908,7 +852,7 @@
"namePlaceholder": "The team's name goes here…",
"nameRequired": "Please specify a name.",
"description": "Description",
"descriptionPlaceholder": "Describe the team here, hit '/' for more options…",
"descriptionPlaceholder": "The teams description goes here…",
"admin": "Admin",
"member": "Member"
}
@ -936,8 +880,7 @@
"description": "Toggle editing of the task description",
"delete": "Delete this task",
"priority": "Change the priority of this task",
"favorite": "Mark this task as favorite / unfavorite",
"save": "Save the current task"
"favorite": "Mark this task as favorite / unfavorite"
},
"project": {
"title": "Project Views",
@ -987,9 +930,7 @@
"notification": {
"title": "Notifications",
"none": "You don't have any notifications. Have a nice day!",
"explainer": "Notifications will appear here when actions projects or tasks you subscribed to happen.",
"markAllRead": "Mark all notifications as read",
"markAllReadSuccess": "Successfully marked all notifications as read."
"explainer": "Notifications will appear here when actions projects or tasks you subscribed to happen."
},
"quickActions": {
"commands": "Commands",

View File

@ -6,7 +6,6 @@
"welcomeEvening": "Godkväll {username}!",
"lastViewed": "Last viewed",
"addToHomeScreen": "Add this app to your home screen for faster access and improved experience.",
"goToOverview": "Go to overview",
"project": {
"importText": "Import your projects and tasks from other services into Vikunja:",
"import": "Importera din data till Vikunja"
@ -174,10 +173,9 @@
}
},
"deletion": {
"title": "Radera ditt Vikunja-konto",
"title": "Delete your Vikunja Account",
"text1": "The deletion of your account is permanent and cannot be undone. We will delete all your projects, tasks and everything associated with it.",
"text2": "To proceed, please enter your password. You will receive an email with further instructions.",
"text3": "För att fortsätta, tryck på knappen nedan. Du kommer att få ett e-postmeddelande med ytterligare instruktioner.",
"confirm": "Radera mitt konto",
"requestSuccess": "The request was successful. You'll receive an email with further instructions.",
"passwordRequired": "Vänligen ange ditt lösenord.",
@ -185,7 +183,6 @@
"scheduled": "We will delete your Vikunja account at {date} ({dateSince}).",
"scheduledCancel": "To cancel the deletion of your account, click here.",
"scheduledCancelText": "To cancel the deletion of your account, please enter your password below:",
"scheduledCancelButton": "To cancel the deletion of your account, please press the button below:",
"scheduledCancelConfirm": "Cancel the deletion of my account",
"scheduledCancelSuccess": "Vi kommer inte radera ditt konto."
},
@ -259,7 +256,7 @@
"identifier": "Project Identifier",
"identifierPlaceholder": "The project identifier goes here…",
"description": "Beskrivning",
"descriptionPlaceholder": "Enter a description for this project, hit '/' for more options…",
"descriptionPlaceholder": "The projects description goes here…",
"color": "Färg",
"success": "The project was successfully updated."
},
@ -360,21 +357,6 @@
"favorites": {
"title": "Favoriter"
}
},
"webhooks": {
"title": "Webhooks",
"targetUrl": "Target URL",
"targetUrlInvalid": "Vänligen ange en giltig URL.",
"events": "Events",
"eventsHint": "Select all events this webhook should recieve updates for (within the current project).",
"mustSelectEvents": "You must select at least one event.",
"delete": "Delete this webhook",
"deleteText": "Are you sure you want to delete this webhook? External targets will not be notified of its events anymore.",
"deleteSuccess": "The webhook was successfully deleted.",
"create": "Create webhook",
"secret": "Secret",
"secretHint": "If provided, all requests to the webhook target URL will be signed using HMAC.",
"secretDocs": "Check out the docs for more details about how to use secrets."
}
},
"filters": {
@ -384,7 +366,7 @@
"title": "Titel",
"titlePlaceholder": "The saved filter title goes here…",
"description": "Beskrivning",
"descriptionPlaceholder": "Add a description for this filter here, hit '/' for more options…",
"descriptionPlaceholder": "The description goes here…",
"includeNulls": "Include Tasks which don't have a value set",
"requireAll": "Require all filters to be true for a task to show up",
"showDoneTasks": "Show Done Tasks",
@ -425,9 +407,7 @@
"alreadyMigrated2": "Importing again is possible, but might create duplicates. Are you sure?",
"confirm": "I am sure, please start migrating now!",
"importUpload": "To import data from {name} into Vikunja, click the button below to select a file.",
"upload": "Ladda upp fil",
"migrationStartedWillReciveEmail": "Vikunja will now import your lists/projects, tasks, notes, reminders and files from {service}. As this will take a while, we will send you an email once done. You can close this window now.",
"migrationInProgress": "A migration is currently in progress. Please wait until it is done."
"upload": "Ladda upp fil"
},
"label": {
"title": "Etiketter",
@ -498,7 +478,6 @@
"custom": "Custom",
"id": "ID",
"created": "Created at",
"createdBy": "Created by {0}",
"actions": "Actions",
"cannotBeUndone": "This cannot be undone!"
},
@ -517,59 +496,24 @@
"edit": "Redigera",
"done": "Done",
"heading1": "Heading 1",
"heading1Tooltip": "Big section heading.",
"heading2": "Heading 2",
"heading2Tooltip": "Medium section heading.",
"heading3": "Heading 3",
"heading3Tooltip": "Smaller section header.",
"headingSmaller": "Heading Smaller",
"headingBigger": "Heading Bigger",
"bold": "Fetstil",
"italic": "Kursiv",
"strikethrough": "Genomstruken",
"underline": "Underline",
"code": "Kod",
"codeTooltip": "Capture a code snippet.",
"quote": "Citat",
"quoteTooltip": "Capture a quote.",
"bulletList": "Bullet list",
"bulletListTooltip": "Create a simple bullet list.",
"unorderedList": "Unordered list",
"orderedList": "Ordered list",
"orderedListTooltip": "Create a list with numbering.",
"unorderedList": "Unordered List",
"orderedList": "Ordered List",
"cleanBlock": "Clean Block",
"link": "Länk",
"image": "Bild",
"imageTooltip": "Upload an image from your computer.",
"table": {
"title": "Tabell",
"insert": "Insert table",
"addColumnBefore": "Lägg till kolumn före",
"addColumnAfter": "Lägg till kolumn efter",
"deleteColumn": "Radera kolumn",
"addRowBefore": "Lägg till rad före",
"addRowAfter": "Lägg till rad efter",
"deleteRow": "Radera rad",
"deleteTable": "Radera tabell",
"mergeCells": "Merge cells",
"splitCell": "Split cell",
"toggleHeaderColumn": "Toggle header column",
"toggleHeaderRow": "Toggle header row",
"toggleHeaderCell": "Toggle header cell",
"mergeOrSplit": "Merge or split",
"fixTables": "Fix tables"
},
"table": "Tabell",
"horizontalRule": "Horizontal Rule",
"horizontalRuleTooltip": "Divide a section.",
"sideBySide": "Side By Side",
"guide": "Guide",
"text": "Text",
"textTooltip": "Just start typing with plain text.",
"taskList": "Task list",
"taskListTooltip": "Track tasks with a to-do list.",
"undo": "Ångra",
"redo": "Redo",
"placeholder": "Type some text or hit '/' to see more options…"
"guide": "Guide"
},
"multiselect": {
"createPlaceholder": "Create new",
@ -681,7 +625,7 @@
"reminders": "Set Reminders",
"repeatAfter": "Set Repeating Interval",
"percentDone": "Set Progress",
"attachments": "Lägg till bilagor",
"attachments": "Add Attachments",
"relatedTasks": "Add Relation",
"moveProject": "Flytta",
"color": "Set Color",
@ -726,10 +670,10 @@
"title": "Bilagor",
"createdBy": "skapad {0} av {1}",
"downloadTooltip": "Download this attachment",
"upload": "Ladda upp bilaga",
"upload": "Upload attachment",
"drop": "Drop files here to upload",
"delete": "Radera bilaga",
"deleteTooltip": "Radera denna bilaga",
"deleteTooltip": "Delete this attachment",
"deleteText1": "Are you sure you want to delete the attachment {filename}?",
"copyUrl": "Kopiera URL",
"copyUrlTooltip": "Copy the url of this attachment for usage in text",
@ -743,7 +687,7 @@
"loading": "Laddar kommentarer…",
"edited": "edited {date}",
"creating": "Creating comment…",
"placeholder": "Add your comment, hit '/' for more options…",
"placeholder": "Skriv din kommentar…",
"comment": "Comment",
"delete": "Delete this comment",
"deleteText1": "Är du säker på att du vill radera denna kommentar?",
@ -757,7 +701,7 @@
"1week": "1 vecka"
},
"description": {
"placeholder": "Enter a description, hit '/' for more options…",
"placeholder": "Klicka här för att ange en beskrivning…",
"empty": "No description available yet."
},
"assignee": {
@ -908,7 +852,7 @@
"namePlaceholder": "The team's name goes here…",
"nameRequired": "Please specify a name.",
"description": "Beskrivning",
"descriptionPlaceholder": "Describe the team here, hit '/' for more options…",
"descriptionPlaceholder": "The teams description goes here…",
"admin": "Admin",
"member": "Medlem"
}
@ -936,8 +880,7 @@
"description": "Toggle editing of the task description",
"delete": "Radera denna uppgift",
"priority": "Change the priority of this task",
"favorite": "Mark this task as favorite / unfavorite",
"save": "Save the current task"
"favorite": "Mark this task as favorite / unfavorite"
},
"project": {
"title": "Project Views",
@ -987,9 +930,7 @@
"notification": {
"title": "Notifications",
"none": "You don't have any notifications. Have a nice day!",
"explainer": "Notifications will appear here when actions projects or tasks you subscribed to happen.",
"markAllRead": "Mark all notifications as read",
"markAllReadSuccess": "Successfully marked all notifications as read."
"explainer": "Notifications will appear here when actions projects or tasks you subscribed to happen."
},
"quickActions": {
"commands": "Kommandon",

View File

@ -6,7 +6,6 @@
"welcomeEvening": "Good Evening {username}!",
"lastViewed": "Last viewed",
"addToHomeScreen": "Add this app to your home screen for faster access and improved experience.",
"goToOverview": "Go to overview",
"project": {
"importText": "Import your projects and tasks from other services into Vikunja:",
"import": "Import your data into Vikunja"
@ -177,7 +176,6 @@
"title": "Delete your Vikunja Account",
"text1": "The deletion of your account is permanent and cannot be undone. We will delete all your projects, tasks and everything associated with it.",
"text2": "To proceed, please enter your password. You will receive an email with further instructions.",
"text3": "To proceed, please press the button below. You will receive an email with further instructions.",
"confirm": "Delete my account",
"requestSuccess": "The request was successful. You'll receive an email with further instructions.",
"passwordRequired": "Please enter your password.",
@ -185,7 +183,6 @@
"scheduled": "We will delete your Vikunja account at {date} ({dateSince}).",
"scheduledCancel": "To cancel the deletion of your account, click here.",
"scheduledCancelText": "To cancel the deletion of your account, please enter your password below:",
"scheduledCancelButton": "To cancel the deletion of your account, please press the button below:",
"scheduledCancelConfirm": "Cancel the deletion of my account",
"scheduledCancelSuccess": "We will not delete your account."
},
@ -259,7 +256,7 @@
"identifier": "Project Identifier",
"identifierPlaceholder": "The project identifier goes here…",
"description": "Description",
"descriptionPlaceholder": "Enter a description for this project, hit '/' for more options…",
"descriptionPlaceholder": "The projects description goes here…",
"color": "Color",
"success": "The project was successfully updated."
},
@ -360,21 +357,6 @@
"favorites": {
"title": "Favorites"
}
},
"webhooks": {
"title": "Webhooks",
"targetUrl": "Target URL",
"targetUrlInvalid": "Please provide a valid URL.",
"events": "Events",
"eventsHint": "Select all events this webhook should recieve updates for (within the current project).",
"mustSelectEvents": "You must select at least one event.",
"delete": "Delete this webhook",
"deleteText": "Are you sure you want to delete this webhook? External targets will not be notified of its events anymore.",
"deleteSuccess": "The webhook was successfully deleted.",
"create": "Create webhook",
"secret": "Secret",
"secretHint": "If provided, all requests to the webhook target URL will be signed using HMAC.",
"secretDocs": "Check out the docs for more details about how to use secrets."
}
},
"filters": {
@ -384,7 +366,7 @@
"title": "Title",
"titlePlaceholder": "The saved filter title goes here…",
"description": "Description",
"descriptionPlaceholder": "Add a description for this filter here, hit '/' for more options…",
"descriptionPlaceholder": "The description goes here…",
"includeNulls": "Include Tasks which don't have a value set",
"requireAll": "Require all filters to be true for a task to show up",
"showDoneTasks": "Show Done Tasks",
@ -425,9 +407,7 @@
"alreadyMigrated2": "Importing again is possible, but might create duplicates. Are you sure?",
"confirm": "I am sure, please start migrating now!",
"importUpload": "To import data from {name} into Vikunja, click the button below to select a file.",
"upload": "Upload file",
"migrationStartedWillReciveEmail": "Vikunja will now import your lists/projects, tasks, notes, reminders and files from {service}. As this will take a while, we will send you an email once done. You can close this window now.",
"migrationInProgress": "A migration is currently in progress. Please wait until it is done."
"upload": "Upload file"
},
"label": {
"title": "Labels",
@ -498,7 +478,6 @@
"custom": "Custom",
"id": "ID",
"created": "Created at",
"createdBy": "Created by {0}",
"actions": "Actions",
"cannotBeUndone": "This cannot be undone!"
},
@ -517,59 +496,24 @@
"edit": "Edit",
"done": "Done",
"heading1": "Heading 1",
"heading1Tooltip": "Big section heading.",
"heading2": "Heading 2",
"heading2Tooltip": "Medium section heading.",
"heading3": "Heading 3",
"heading3Tooltip": "Smaller section header.",
"headingSmaller": "Heading Smaller",
"headingBigger": "Heading Bigger",
"bold": "Bold",
"italic": "Italic",
"strikethrough": "Strikethrough",
"underline": "Underline",
"code": "Code",
"codeTooltip": "Capture a code snippet.",
"quote": "Quote",
"quoteTooltip": "Capture a quote.",
"bulletList": "Bullet list",
"bulletListTooltip": "Create a simple bullet list.",
"unorderedList": "Unordered list",
"orderedList": "Ordered list",
"orderedListTooltip": "Create a list with numbering.",
"unorderedList": "Unordered List",
"orderedList": "Ordered List",
"cleanBlock": "Clean Block",
"link": "Link",
"image": "Image",
"imageTooltip": "Upload an image from your computer.",
"table": {
"title": "Table",
"insert": "Insert table",
"addColumnBefore": "Add column before",
"addColumnAfter": "Add column after",
"deleteColumn": "Delete column",
"addRowBefore": "Add row before",
"addRowAfter": "Add row after",
"deleteRow": "Delete row",
"deleteTable": "Delete table",
"mergeCells": "Merge cells",
"splitCell": "Split cell",
"toggleHeaderColumn": "Toggle header column",
"toggleHeaderRow": "Toggle header row",
"toggleHeaderCell": "Toggle header cell",
"mergeOrSplit": "Merge or split",
"fixTables": "Fix tables"
},
"table": "Table",
"horizontalRule": "Horizontal Rule",
"horizontalRuleTooltip": "Divide a section.",
"sideBySide": "Side By Side",
"guide": "Guide",
"text": "Text",
"textTooltip": "Just start typing with plain text.",
"taskList": "Task list",
"taskListTooltip": "Track tasks with a to-do list.",
"undo": "Undo",
"redo": "Redo",
"placeholder": "Type some text or hit '/' to see more options…"
"guide": "Guide"
},
"multiselect": {
"createPlaceholder": "Create new",
@ -743,7 +687,7 @@
"loading": "Loading comments…",
"edited": "edited {date}",
"creating": "Creating comment…",
"placeholder": "Add your comment, hit '/' for more options…",
"placeholder": "Add your comment…",
"comment": "Comment",
"delete": "Delete this comment",
"deleteText1": "Are you sure you want to delete this comment?",
@ -757,7 +701,7 @@
"1week": "1 week"
},
"description": {
"placeholder": "Enter a description, hit '/' for more options…",
"placeholder": "Click here to enter a description…",
"empty": "No description available yet."
},
"assignee": {
@ -908,7 +852,7 @@
"namePlaceholder": "The team's name goes here…",
"nameRequired": "Please specify a name.",
"description": "Description",
"descriptionPlaceholder": "Describe the team here, hit '/' for more options…",
"descriptionPlaceholder": "The teams description goes here…",
"admin": "Admin",
"member": "Member"
}
@ -936,8 +880,7 @@
"description": "Toggle editing of the task description",
"delete": "Delete this task",
"priority": "Change the priority of this task",
"favorite": "Mark this task as favorite / unfavorite",
"save": "Save the current task"
"favorite": "Mark this task as favorite / unfavorite"
},
"project": {
"title": "Project Views",
@ -987,9 +930,7 @@
"notification": {
"title": "Notifications",
"none": "You don't have any notifications. Have a nice day!",
"explainer": "Notifications will appear here when actions projects or tasks you subscribed to happen.",
"markAllRead": "Mark all notifications as read",
"markAllReadSuccess": "Successfully marked all notifications as read."
"explainer": "Notifications will appear here when actions projects or tasks you subscribed to happen."
},
"quickActions": {
"commands": "Commands",

View File

@ -6,7 +6,6 @@
"welcomeEvening": "Good Evening {username}!",
"lastViewed": "Xem gần đây",
"addToHomeScreen": "Add this app to your home screen for faster access and improved experience.",
"goToOverview": "Go to overview",
"project": {
"importText": "Import your projects and tasks from other services into Vikunja:",
"import": "Import your data into Vikunja"
@ -177,7 +176,6 @@
"title": "Xóa tài khoản của bạn",
"text1": "The deletion of your account is permanent and cannot be undone. We will delete all your projects, tasks and everything associated with it.",
"text2": "Để tiếp tục, vui lòng nhập mật khẩu của bạn. Bạn sẽ nhận được một email hướng dẫn thêm.",
"text3": "To proceed, please press the button below. You will receive an email with further instructions.",
"confirm": "Xóa tài khoản của tôi",
"requestSuccess": "Yêu cầu đã thành công. Bạn sẽ nhận được một email hướng dẫn thêm.",
"passwordRequired": "Vui lòng nhập mật khẩu.",
@ -185,7 +183,6 @@
"scheduled": "Chúng tôi sẽ xóa tài khoản của bạn vào {date} ({dateSince}).",
"scheduledCancel": "Để hủy việc xóa tài khoản của bạn, hãy nhấp vào đây.",
"scheduledCancelText": "Để hủy việc xóa tài khoản, vui lòng nhập mật khẩu của bạn vào ô bên dưới:",
"scheduledCancelButton": "To cancel the deletion of your account, please press the button below:",
"scheduledCancelConfirm": "Hủy lệnh xóa tài khoản",
"scheduledCancelSuccess": "Chúng tôi sẽ không xóa tài khoản của bạn nữa."
},
@ -259,7 +256,7 @@
"identifier": "Project Identifier",
"identifierPlaceholder": "The project identifier goes here…",
"description": "Description",
"descriptionPlaceholder": "Enter a description for this project, hit '/' for more options…",
"descriptionPlaceholder": "The projects description goes here…",
"color": "Color",
"success": "The project was successfully updated."
},
@ -360,21 +357,6 @@
"favorites": {
"title": "Favorites"
}
},
"webhooks": {
"title": "Webhooks",
"targetUrl": "Target URL",
"targetUrlInvalid": "Please provide a valid URL.",
"events": "Events",
"eventsHint": "Select all events this webhook should recieve updates for (within the current project).",
"mustSelectEvents": "You must select at least one event.",
"delete": "Delete this webhook",
"deleteText": "Are you sure you want to delete this webhook? External targets will not be notified of its events anymore.",
"deleteSuccess": "The webhook was successfully deleted.",
"create": "Create webhook",
"secret": "Secret",
"secretHint": "If provided, all requests to the webhook target URL will be signed using HMAC.",
"secretDocs": "Check out the docs for more details about how to use secrets."
}
},
"filters": {
@ -384,7 +366,7 @@
"title": "Tiêu đề",
"titlePlaceholder": "Tiêu đề bộ lọc đã lưu ở đây…",
"description": "Mô tả",
"descriptionPlaceholder": "Add a description for this filter here, hit '/' for more options…",
"descriptionPlaceholder": "Mô tả ở đây…",
"includeNulls": "Bao gồm các Công việc không có bộ giá trị",
"requireAll": "Yêu cầu tất cả các bộ lọc phải đúng để một công việc được hiển thị",
"showDoneTasks": "Hiển thị các công việc đã hoàn thành",
@ -425,9 +407,7 @@
"alreadyMigrated2": "Nhập lại được luôn, nhưng có thể tạo ra các trùng lặp đấy. Bạn chắc chưa?",
"confirm": "Tôi chắc như đinh, hãy bắt đầu di chuyển thôi!",
"importUpload": "Để nhập dữ liệu từ {name} vào Vikunja, hãy nhấp vào nút bên dưới để chọn tệp.",
"upload": "Tải tệp lên",
"migrationStartedWillReciveEmail": "Vikunja will now import your lists/projects, tasks, notes, reminders and files from {service}. As this will take a while, we will send you an email once done. You can close this window now.",
"migrationInProgress": "A migration is currently in progress. Please wait until it is done."
"upload": "Tải tệp lên"
},
"label": {
"title": "Nhãn",
@ -498,7 +478,6 @@
"custom": "Tuỳ chỉnh",
"id": "ID",
"created": "Created at",
"createdBy": "Created by {0}",
"actions": "Actions",
"cannotBeUndone": "This cannot be undone!"
},
@ -517,59 +496,24 @@
"edit": "Chỉnh sửa",
"done": "Hoàn thành",
"heading1": "Tiêu đề 1",
"heading1Tooltip": "Big section heading.",
"heading2": "Tiêu đề 2",
"heading2Tooltip": "Medium section heading.",
"heading3": "Tiêu đề 3",
"heading3Tooltip": "Smaller section header.",
"headingSmaller": "Tiêu đề nhỏ hơn",
"headingBigger": "Tiêu đề lớn hơn",
"bold": "In đậm",
"italic": "In nghiêng",
"strikethrough": "Gạch ngang",
"underline": "Underline",
"code": "Code",
"codeTooltip": "Capture a code snippet.",
"quote": "Trích dẫn",
"quoteTooltip": "Capture a quote.",
"bulletList": "Bullet list",
"bulletListTooltip": "Create a simple bullet list.",
"unorderedList": "Unordered list",
"orderedList": "Ordered list",
"orderedListTooltip": "Create a list with numbering.",
"unorderedList": "Gạch đầu dòng",
"orderedList": "Ordered List",
"cleanBlock": "Làm sạch Khối",
"link": "Liên kết",
"image": "Ảnh",
"imageTooltip": "Upload an image from your computer.",
"table": {
"title": "Table",
"insert": "Insert table",
"addColumnBefore": "Add column before",
"addColumnAfter": "Add column after",
"deleteColumn": "Delete column",
"addRowBefore": "Add row before",
"addRowAfter": "Add row after",
"deleteRow": "Delete row",
"deleteTable": "Delete table",
"mergeCells": "Merge cells",
"splitCell": "Split cell",
"toggleHeaderColumn": "Toggle header column",
"toggleHeaderRow": "Toggle header row",
"toggleHeaderCell": "Toggle header cell",
"mergeOrSplit": "Merge or split",
"fixTables": "Fix tables"
},
"table": "Bảng",
"horizontalRule": "Dòng kẻ ngang",
"horizontalRuleTooltip": "Divide a section.",
"sideBySide": "Chia đôi cửa sổ",
"guide": "Hướng dẫn",
"text": "Text",
"textTooltip": "Just start typing with plain text.",
"taskList": "Task list",
"taskListTooltip": "Track tasks with a to-do list.",
"undo": "Undo",
"redo": "Redo",
"placeholder": "Type some text or hit '/' to see more options…"
"guide": "Hướng dẫn"
},
"multiselect": {
"createPlaceholder": "Tạo mới",
@ -743,7 +687,7 @@
"loading": "Đang tải bình luận…",
"edited": "đã sửa {date}",
"creating": "Đang tạo bình luận…",
"placeholder": "Add your comment, hit '/' for more options…",
"placeholder": "Thêm bình luận của bạn…",
"comment": "Bình luận",
"delete": "Xóa bình luận này",
"deleteText1": "Bạn có chắc muốn xóa bình luận này không?",
@ -757,7 +701,7 @@
"1week": "1 tuần"
},
"description": {
"placeholder": "Enter a description, hit '/' for more options…",
"placeholder": "Nhấp vào đây để nhập mô tả…",
"empty": "Chưa có mô tả."
},
"assignee": {
@ -908,7 +852,7 @@
"namePlaceholder": "Tên của Team ở đây…",
"nameRequired": "Hãy đặt một cái tên.",
"description": "Mô tả",
"descriptionPlaceholder": "Describe the team here, hit '/' for more options…",
"descriptionPlaceholder": "Mô tả Team ở đây…",
"admin": "Quản trị viên",
"member": "Thành viên"
}
@ -936,8 +880,7 @@
"description": "Toggle editing of the task description",
"delete": "Delete this task",
"priority": "Change the priority of this task",
"favorite": "Mark this task as favorite / unfavorite",
"save": "Save the current task"
"favorite": "Mark this task as favorite / unfavorite"
},
"project": {
"title": "Project Views",
@ -987,9 +930,7 @@
"notification": {
"title": "Thông báo",
"none": "Bạn không có thông báo nào. Chúc một ngày tốt lành!",
"explainer": "Notifications will appear here when actions projects or tasks you subscribed to happen.",
"markAllRead": "Mark all notifications as read",
"markAllReadSuccess": "Successfully marked all notifications as read."
"explainer": "Notifications will appear here when actions projects or tasks you subscribed to happen."
},
"quickActions": {
"commands": "Các lệnh",

View File

@ -6,7 +6,6 @@
"welcomeEvening": "中午好,{username}",
"lastViewed": "最近查看",
"addToHomeScreen": "Add this app to your home screen for faster access and improved experience.",
"goToOverview": "Go to overview",
"project": {
"importText": "Import your projects and tasks from other services into Vikunja:",
"import": "Import your data into Vikunja"
@ -177,7 +176,6 @@
"title": "删除您的 Vikunja 帐户",
"text1": "The deletion of your account is permanent and cannot be undone. We will delete all your projects, tasks and everything associated with it.",
"text2": "若要继续,请输入您的密码。您将收到一封包含更多说明的电子邮件。",
"text3": "To proceed, please press the button below. You will receive an email with further instructions.",
"confirm": "删除我的帐户",
"requestSuccess": "请求成功。您将收到一封包含更多说明的电子邮件。",
"passwordRequired": "请输入密码",
@ -185,7 +183,6 @@
"scheduled": "您的 Vikunja帐户将于 {date} ({dateSince}) 完成注销删除。",
"scheduledCancel": "要取消您的帐户删除操作,请单击此处。",
"scheduledCancelText": "若要取消您的帐户删除操作,请在下面输入您的密码:",
"scheduledCancelButton": "To cancel the deletion of your account, please press the button below:",
"scheduledCancelConfirm": "取消删除我的帐户",
"scheduledCancelSuccess": "账户删除操作已撤销"
},
@ -259,7 +256,7 @@
"identifier": "Project Identifier",
"identifierPlaceholder": "The project identifier goes here…",
"description": "Description",
"descriptionPlaceholder": "Enter a description for this project, hit '/' for more options…",
"descriptionPlaceholder": "The projects description goes here…",
"color": "Color",
"success": "The project was successfully updated."
},
@ -360,21 +357,6 @@
"favorites": {
"title": "Favorites"
}
},
"webhooks": {
"title": "Webhooks",
"targetUrl": "Target URL",
"targetUrlInvalid": "Please provide a valid URL.",
"events": "Events",
"eventsHint": "Select all events this webhook should recieve updates for (within the current project).",
"mustSelectEvents": "You must select at least one event.",
"delete": "Delete this webhook",
"deleteText": "Are you sure you want to delete this webhook? External targets will not be notified of its events anymore.",
"deleteSuccess": "The webhook was successfully deleted.",
"create": "Create webhook",
"secret": "Secret",
"secretHint": "If provided, all requests to the webhook target URL will be signed using HMAC.",
"secretDocs": "Check out the docs for more details about how to use secrets."
}
},
"filters": {
@ -384,7 +366,7 @@
"title": "标题",
"titlePlaceholder": "填写筛选器标题",
"description": "描述信息",
"descriptionPlaceholder": "Add a description for this filter here, hit '/' for more options…",
"descriptionPlaceholder": "填写描述详情",
"includeNulls": "包含没有设置值的任务",
"requireAll": "要求所有筛选器为真才能显示任务",
"showDoneTasks": "显示已完成的任务",
@ -425,9 +407,7 @@
"alreadyMigrated2": "可以再次导入,但这可能会造成数据重复。您确定吗?",
"confirm": "我确定, 请立即开始迁移!",
"importUpload": "请点击下面的按钮选择一个文件,将 {name} 的数据导入到 Vikunja",
"upload": "点击上传文件",
"migrationStartedWillReciveEmail": "Vikunja will now import your lists/projects, tasks, notes, reminders and files from {service}. As this will take a while, we will send you an email once done. You can close this window now.",
"migrationInProgress": "A migration is currently in progress. Please wait until it is done."
"upload": "点击上传文件"
},
"label": {
"title": "标签",
@ -498,7 +478,6 @@
"custom": "自定义",
"id": "ID",
"created": "创建于",
"createdBy": "Created by {0}",
"actions": "行为",
"cannotBeUndone": "此操作无法撤消!"
},
@ -517,59 +496,24 @@
"edit": "编辑",
"done": "完成",
"heading1": "一级标题",
"heading1Tooltip": "Big section heading.",
"heading2": "二级标题",
"heading2Tooltip": "Medium section heading.",
"heading3": "三级标题",
"heading3Tooltip": "Smaller section header.",
"headingSmaller": "下一级标题",
"headingBigger": "上一级标题",
"bold": "粗体",
"italic": "斜体",
"strikethrough": "删除线",
"underline": "Underline",
"code": "代码",
"codeTooltip": "Capture a code snippet.",
"quote": "引用",
"quoteTooltip": "Capture a quote.",
"bulletList": "Bullet list",
"bulletListTooltip": "Create a simple bullet list.",
"unorderedList": "Unordered list",
"orderedList": "Ordered list",
"orderedListTooltip": "Create a list with numbering.",
"unorderedList": "无序列表",
"orderedList": "Ordered List",
"cleanBlock": "清除格式",
"link": "链接",
"image": "图片",
"imageTooltip": "Upload an image from your computer.",
"table": {
"title": "Table",
"insert": "Insert table",
"addColumnBefore": "Add column before",
"addColumnAfter": "Add column after",
"deleteColumn": "Delete column",
"addRowBefore": "Add row before",
"addRowAfter": "Add row after",
"deleteRow": "Delete row",
"deleteTable": "Delete table",
"mergeCells": "Merge cells",
"splitCell": "Split cell",
"toggleHeaderColumn": "Toggle header column",
"toggleHeaderRow": "Toggle header row",
"toggleHeaderCell": "Toggle header cell",
"mergeOrSplit": "Merge or split",
"fixTables": "Fix tables"
},
"table": "表格",
"horizontalRule": "水平线",
"horizontalRuleTooltip": "Divide a section.",
"sideBySide": "并排",
"guide": "指南",
"text": "Text",
"textTooltip": "Just start typing with plain text.",
"taskList": "Task list",
"taskListTooltip": "Track tasks with a to-do list.",
"undo": "Undo",
"redo": "Redo",
"placeholder": "Type some text or hit '/' to see more options…"
"guide": "指南"
},
"multiselect": {
"createPlaceholder": "创建新的",
@ -743,7 +687,7 @@
"loading": "正在加载评论…",
"edited": "编辑于 {date}",
"creating": "正在创建评论…",
"placeholder": "Add your comment, hit '/' for more options…",
"placeholder": "添加你的评论......",
"comment": "评论",
"delete": "删除此评论",
"deleteText1": "确实要删除此评论吗?",
@ -757,7 +701,7 @@
"1week": "1周"
},
"description": {
"placeholder": "Enter a description, hit '/' for more options…",
"placeholder": "点击此处输入描述...",
"empty": "尚无描述。"
},
"assignee": {
@ -908,7 +852,7 @@
"namePlaceholder": "团队的名字在这里……",
"nameRequired": "请指定名称。",
"description": "描述信息",
"descriptionPlaceholder": "Describe the team here, hit '/' for more options…",
"descriptionPlaceholder": "团队描述在这里…",
"admin": "管理员",
"member": "成员"
}
@ -936,8 +880,7 @@
"description": "切换编辑时的任务描述",
"delete": "Delete this task",
"priority": "Change the priority of this task",
"favorite": "Mark this task as favorite / unfavorite",
"save": "Save the current task"
"favorite": "Mark this task as favorite / unfavorite"
},
"project": {
"title": "Project Views",
@ -987,9 +930,7 @@
"notification": {
"title": "通知",
"none": "没有任何通知。 祝你今天过得愉快!",
"explainer": "Notifications will appear here when actions projects or tasks you subscribed to happen.",
"markAllRead": "Mark all notifications as read",
"markAllReadSuccess": "Successfully marked all notifications as read."
"explainer": "Notifications will appear here when actions projects or tasks you subscribed to happen."
},
"quickActions": {
"commands": "命令",

View File

@ -6,7 +6,6 @@
"welcomeEvening": "Good Evening {username}!",
"lastViewed": "Last viewed",
"addToHomeScreen": "Add this app to your home screen for faster access and improved experience.",
"goToOverview": "Go to overview",
"project": {
"importText": "Import your projects and tasks from other services into Vikunja:",
"import": "Import your data into Vikunja"
@ -177,7 +176,6 @@
"title": "Delete your Vikunja Account",
"text1": "The deletion of your account is permanent and cannot be undone. We will delete all your projects, tasks and everything associated with it.",
"text2": "To proceed, please enter your password. You will receive an email with further instructions.",
"text3": "To proceed, please press the button below. You will receive an email with further instructions.",
"confirm": "Delete my account",
"requestSuccess": "The request was successful. You'll receive an email with further instructions.",
"passwordRequired": "Please enter your password.",
@ -185,7 +183,6 @@
"scheduled": "We will delete your Vikunja account at {date} ({dateSince}).",
"scheduledCancel": "To cancel the deletion of your account, click here.",
"scheduledCancelText": "To cancel the deletion of your account, please enter your password below:",
"scheduledCancelButton": "To cancel the deletion of your account, please press the button below:",
"scheduledCancelConfirm": "Cancel the deletion of my account",
"scheduledCancelSuccess": "We will not delete your account."
},
@ -259,7 +256,7 @@
"identifier": "Project Identifier",
"identifierPlaceholder": "The project identifier goes here…",
"description": "Description",
"descriptionPlaceholder": "Enter a description for this project, hit '/' for more options…",
"descriptionPlaceholder": "The projects description goes here…",
"color": "Color",
"success": "The project was successfully updated."
},
@ -360,21 +357,6 @@
"favorites": {
"title": "Favorites"
}
},
"webhooks": {
"title": "Webhooks",
"targetUrl": "Target URL",
"targetUrlInvalid": "Please provide a valid URL.",
"events": "Events",
"eventsHint": "Select all events this webhook should recieve updates for (within the current project).",
"mustSelectEvents": "You must select at least one event.",
"delete": "Delete this webhook",
"deleteText": "Are you sure you want to delete this webhook? External targets will not be notified of its events anymore.",
"deleteSuccess": "The webhook was successfully deleted.",
"create": "Create webhook",
"secret": "Secret",
"secretHint": "If provided, all requests to the webhook target URL will be signed using HMAC.",
"secretDocs": "Check out the docs for more details about how to use secrets."
}
},
"filters": {
@ -384,7 +366,7 @@
"title": "Title",
"titlePlaceholder": "The saved filter title goes here…",
"description": "Description",
"descriptionPlaceholder": "Add a description for this filter here, hit '/' for more options…",
"descriptionPlaceholder": "The description goes here…",
"includeNulls": "Include Tasks which don't have a value set",
"requireAll": "Require all filters to be true for a task to show up",
"showDoneTasks": "Show Done Tasks",
@ -425,9 +407,7 @@
"alreadyMigrated2": "Importing again is possible, but might create duplicates. Are you sure?",
"confirm": "I am sure, please start migrating now!",
"importUpload": "To import data from {name} into Vikunja, click the button below to select a file.",
"upload": "Upload file",
"migrationStartedWillReciveEmail": "Vikunja will now import your lists/projects, tasks, notes, reminders and files from {service}. As this will take a while, we will send you an email once done. You can close this window now.",
"migrationInProgress": "A migration is currently in progress. Please wait until it is done."
"upload": "Upload file"
},
"label": {
"title": "Labels",
@ -498,7 +478,6 @@
"custom": "Custom",
"id": "ID",
"created": "Created at",
"createdBy": "Created by {0}",
"actions": "Actions",
"cannotBeUndone": "This cannot be undone!"
},
@ -517,59 +496,24 @@
"edit": "Edit",
"done": "Done",
"heading1": "Heading 1",
"heading1Tooltip": "Big section heading.",
"heading2": "Heading 2",
"heading2Tooltip": "Medium section heading.",
"heading3": "Heading 3",
"heading3Tooltip": "Smaller section header.",
"headingSmaller": "Heading Smaller",
"headingBigger": "Heading Bigger",
"bold": "Bold",
"italic": "Italic",
"strikethrough": "Strikethrough",
"underline": "Underline",
"code": "Code",
"codeTooltip": "Capture a code snippet.",
"quote": "Quote",
"quoteTooltip": "Capture a quote.",
"bulletList": "Bullet list",
"bulletListTooltip": "Create a simple bullet list.",
"unorderedList": "Unordered list",
"orderedList": "Ordered list",
"orderedListTooltip": "Create a list with numbering.",
"unorderedList": "Unordered List",
"orderedList": "Ordered List",
"cleanBlock": "Clean Block",
"link": "Link",
"image": "Image",
"imageTooltip": "Upload an image from your computer.",
"table": {
"title": "Table",
"insert": "Insert table",
"addColumnBefore": "Add column before",
"addColumnAfter": "Add column after",
"deleteColumn": "Delete column",
"addRowBefore": "Add row before",
"addRowAfter": "Add row after",
"deleteRow": "Delete row",
"deleteTable": "Delete table",
"mergeCells": "Merge cells",
"splitCell": "Split cell",
"toggleHeaderColumn": "Toggle header column",
"toggleHeaderRow": "Toggle header row",
"toggleHeaderCell": "Toggle header cell",
"mergeOrSplit": "Merge or split",
"fixTables": "Fix tables"
},
"table": "Table",
"horizontalRule": "Horizontal Rule",
"horizontalRuleTooltip": "Divide a section.",
"sideBySide": "Side By Side",
"guide": "Guide",
"text": "Text",
"textTooltip": "Just start typing with plain text.",
"taskList": "Task list",
"taskListTooltip": "Track tasks with a to-do list.",
"undo": "Undo",
"redo": "Redo",
"placeholder": "Type some text or hit '/' to see more options…"
"guide": "Guide"
},
"multiselect": {
"createPlaceholder": "Create new",
@ -743,7 +687,7 @@
"loading": "Loading comments…",
"edited": "edited {date}",
"creating": "Creating comment…",
"placeholder": "Add your comment, hit '/' for more options…",
"placeholder": "Add your comment…",
"comment": "Comment",
"delete": "Delete this comment",
"deleteText1": "Are you sure you want to delete this comment?",
@ -757,7 +701,7 @@
"1week": "1 week"
},
"description": {
"placeholder": "Enter a description, hit '/' for more options…",
"placeholder": "Click here to enter a description…",
"empty": "No description available yet."
},
"assignee": {
@ -908,7 +852,7 @@
"namePlaceholder": "The team's name goes here…",
"nameRequired": "Please specify a name.",
"description": "Description",
"descriptionPlaceholder": "Describe the team here, hit '/' for more options…",
"descriptionPlaceholder": "The teams description goes here…",
"admin": "Admin",
"member": "Member"
}
@ -936,8 +880,7 @@
"description": "Toggle editing of the task description",
"delete": "Delete this task",
"priority": "Change the priority of this task",
"favorite": "Mark this task as favorite / unfavorite",
"save": "Save the current task"
"favorite": "Mark this task as favorite / unfavorite"
},
"project": {
"title": "Project Views",
@ -987,9 +930,7 @@
"notification": {
"title": "Notifications",
"none": "You don't have any notifications. Have a nice day!",
"explainer": "Notifications will appear here when actions projects or tasks you subscribed to happen.",
"markAllRead": "Mark all notifications as read",
"markAllReadSuccess": "Successfully marked all notifications as read."
"explainer": "Notifications will appear here when actions projects or tasks you subscribed to happen."
},
"quickActions": {
"commands": "Commands",

View File

@ -18,7 +18,7 @@ export interface IUserSettings extends IAbstract {
discoverableByName: boolean
discoverableByEmail: boolean
overdueTasksRemindersEnabled: boolean
overdueTasksRemindersTime: string | Date
overdueTasksRemindersTime: any
defaultProjectId: undefined | IProject['id']
weekStart: 0 | 1 | 2 | 3 | 4 | 5 | 6
timezone: string

View File

@ -1,14 +0,0 @@
import type {IAbstract} from './IAbstract'
import type {IUser} from '@/modelTypes/IUser'
export interface IWebhook extends IAbstract {
id: number
projectId: number
secret: string
targetUrl: string
events: string[]
createdBy: IUser
created: Date
updated: Date
}

View File

@ -52,7 +52,7 @@ export function getTaskIdentifier(task: ITask | null | undefined): string {
}
if (task.identifier === '') {
return `#${task.index}`
return `#${task.identifier}`
}
return task.identifier

View File

@ -1,25 +0,0 @@
import AbstractModel from '@/models/abstractModel'
import type {IWebhook} from '@/modelTypes/IWebhook'
import UserModel from '@/models/user'
export default class WebhookModel extends AbstractModel<IWebhook> implements IWebhook {
id = 0
projectId = 0
secret = ''
targetUrl = ''
events = []
createdBy = null
created: Date
updated: Date
constructor(data: Partial<IWebhook> = {}) {
super()
this.assignData(data)
this.createdBy = new UserModel(this.createdBy)
this.created = new Date(this.created)
this.updated = new Date(this.updated)
}
}

View File

@ -37,11 +37,7 @@ const MigrationHandlerComponent = () => import('@/views/migrate/MigrationHandler
const ProjectList = () => import('@/views/project/ProjectList.vue')
const ProjectGantt = () => import('@/views/project/ProjectGantt.vue')
const ProjectTable = () => import('@/views/project/ProjectTable.vue')
// If we load the component async, using it as a backdrop view will not work. Instead, everything explodes
// with an error from the core saying "Cannot read properties of undefined (reading 'parentNode')"
// Of course, with no clear indicator of where the problem comes from.
// const ProjectKanban = () => import('@/views/project/ProjectKanban.vue')
import ProjectKanban from '@/views/project/ProjectKanban.vue'
const ProjectKanban = () => import('@/views/project/ProjectKanban.vue')
const ProjectInfo = () => import('@/views/project/ProjectInfo.vue')
// Project Settings
@ -50,7 +46,6 @@ const ProjectSettingEdit = () => import('@/views/project/settings/edit.vue')
const ProjectSettingBackground = () => import('@/views/project/settings/background.vue')
const ProjectSettingDuplicate = () => import('@/views/project/settings/duplicate.vue')
const ProjectSettingShare = () => import('@/views/project/settings/share.vue')
const ProjectSettingWebhooks = () => import('@/views/project/settings/webhooks.vue')
const ProjectSettingDelete = () => import('@/views/project/settings/delete.vue')
const ProjectSettingArchive = () => import('@/views/project/settings/archive.vue')
@ -291,14 +286,6 @@ const router = createRouter({
showAsModal: true,
},
},
{
path: '/projects/:projectId/settings/webhooks',
name: 'project.settings.webhooks',
component: ProjectSettingWebhooks,
meta: {
showAsModal: true,
},
},
{
path: '/projects/:projectId/settings/delete',
name: 'project.settings.delete',

View File

@ -15,16 +15,8 @@ export default class NotificationService extends AbstractService<INotification>
}
beforeUpdate(model) {
if (!model) {
return model
}
model.created = new Date(model.created).toISOString()
model.readAt = new Date(model.readAt).toISOString()
return model
}
async markAllRead() {
return this.post('/notifications', false)
}
}

View File

@ -1,29 +0,0 @@
import AbstractService from '@/services/abstractService'
import type {IWebhook} from '@/modelTypes/IWebhook'
import WebhookModel from '@/models/webhook'
export default class WebhookService extends AbstractService<IWebhook> {
constructor() {
super({
getAll: '/projects/{projectId}/webhooks',
create: '/projects/{projectId}/webhooks',
update: '/projects/{projectId}/webhooks/{id}',
delete: '/projects/{projectId}/webhooks/{id}',
})
}
modelFactory(data) {
return new WebhookModel(data)
}
async getAvailableEvents(): Promise<string[]> {
const cancel = this.setLoading()
try {
const response = await this.http.get('/webhooks/events')
return response.data
} finally {
cancel()
}
}
}

View File

@ -226,20 +226,15 @@ export const useAuthStore = defineStore('auth', () => {
const jwt = getToken()
let isAuthenticated = false
if (jwt) {
try {
const base64 = jwt
.split('.')[1]
.replace('-', '+')
.replace('_', '/')
const info = new UserModel(JSON.parse(atob(base64)))
const ts = Math.round((new Date()).getTime() / MILLISECONDS_A_SECOND)
isAuthenticated = info.exp >= ts
// Settings should only be loaded from the api request, not via the jwt
setUser(info, false)
} catch (e) {
logout()
}
const base64 = jwt
.split('.')[1]
.replace('-', '+')
.replace('_', '/')
const info = new UserModel(JSON.parse(atob(base64)))
const ts = Math.round((new Date()).getTime() / MILLISECONDS_A_SECOND)
isAuthenticated = info.exp >= ts
// Settings should only be loaded from the api request, not via the jwt
setUser(info, false)
if (isAuthenticated) {
await refreshUserInfo()
@ -297,14 +292,11 @@ export const useAuthStore = defineStore('auth', () => {
return newUser
} catch (e) {
if(e?.response?.status === 401 ||
e?.response?.data?.message === 'missing, malformed, expired or otherwise invalid token provided') {
await logout()
if(e?.response?.data?.message === 'invalid or expired jwt') {
logout()
return
}
console.log('continuerd')
const cause = {e}
if (typeof e?.response?.data?.message !== 'undefined') {

View File

@ -37,5 +37,3 @@ $navbar-padding: 2rem;
$vikunja-nav-color: var(--grey-700);
$vikunja-nav-selected-width: 0.4rem;
$close-button-min-space: 84px;

View File

@ -31,6 +31,7 @@
<editor
:class="{ 'disabled': filterService.loading}"
:disabled="filterService.loading"
:preview-is-default="false"
id="description"
:placeholder="$t('filters.attributes.descriptionPlaceholder')"
v-model="filter.description"

View File

@ -32,6 +32,7 @@
v-model="filter.description"
:class="{ 'disabled': filterService.loading}"
:disabled="filterService.loading"
:preview-is-default="false"
id="description"
:placeholder="$t('filters.attributes.descriptionPlaceholder')"
/>

View File

@ -58,6 +58,7 @@
<label class="label">{{ $t('label.attributes.description') }}</label>
<div class="control">
<editor
:preview-is-default="false"
:placeholder="$t('label.attributes.description')"
v-if="editorActive"
v-model="labelEditLabel.description"

View File

@ -3,7 +3,7 @@
<h1>{{ $t('migrate.titleService', {name: migrator.name}) }}</h1>
<p>{{ $t('migrate.descriptionDo') }}</p>
<template v-if="message === '' && lastMigrationFinishedAt === null">
<template v-if="message === '' && lastMigrationDate === null">
<template v-if="isMigrating === false">
<template v-if="migrator.isFileMigrator">
<p>{{ $t('migrate.importUpload', {name: migrator.name}) }}</p>
@ -46,35 +46,21 @@
<p>{{ $t('migrate.inProgress') }}</p>
</div>
</template>
<div v-else-if="lastMigrationStartedAt && lastMigrationFinishedAt === null">
<div v-else-if="lastMigrationDate">
<p>
{{ $t('migrate.migrationInProgress') }}
</p>
<x-button :to="{name: 'home'}">{{ $t('home.goToOverview') }}</x-button>
</div>
<div v-else-if="lastMigrationFinishedAt">
<p>
{{
$t('migrate.alreadyMigrated1', {name: migrator.name, date: formatDateLong(lastMigrationFinishedAt)})
}}<br/>
{{ $t('migrate.alreadyMigrated1', {name: migrator.name, date: formatDateLong(lastMigrationDate)}) }}<br/>
{{ $t('migrate.alreadyMigrated2') }}
</p>
<div class="buttons">
<x-button @click="migrate">{{ $t('migrate.confirm') }}</x-button>
<x-button :to="{name: 'home'}" variant="tertiary" class="has-text-danger">
{{ $t('misc.cancel') }}
</x-button>
<x-button :to="{name: 'home'}" variant="tertiary" class="has-text-danger">{{ $t('misc.cancel') }}</x-button>
</div>
</div>
<div v-else>
<Message class="mb-4" v-if="migrator.isFileMigrator">
<Message class="mb-4">
{{ message }}
</Message>
<Message class="mb-4" v-else>
{{ $t('migrate.migrationStartedWillReciveEmail', {service: migrator.name}) }}
</Message>
<x-button :to="{name: 'home'}">{{ $t('home.goToOverview') }}</x-button>
<x-button :to="{name: 'home'}">{{ $t('misc.refresh') }}</x-button>
</div>
</div>
</template>
@ -96,13 +82,13 @@ import {useI18n} from 'vue-i18n'
import Logo from '@/assets/logo.svg?component'
import Message from '@/components/misc/message.vue'
import AbstractMigrationService, {type MigrationConfig} from '@/services/migrator/abstractMigration'
import AbstractMigrationService, { type MigrationConfig } from '@/services/migrator/abstractMigration'
import AbstractMigrationFileService from '@/services/migrator/abstractMigrationFile'
import {formatDateLong} from '@/helpers/time/formatDate'
import {parseDateOrNull} from '@/helpers/parseDateOrNull'
import {MIGRATORS, Migrator} from './migrators'
import {MIGRATORS} from './migrators'
import {useTitle} from '@/composables/useTitle'
import {useProjectStore} from '@/stores/projects'
@ -118,12 +104,11 @@ const {t} = useI18n({useScope: 'global'})
const progressDotsCount = ref(PROGRESS_DOTS_COUNT)
const authUrl = ref('')
const isMigrating = ref(false)
const lastMigrationFinishedAt = ref<Date | null>(null)
const lastMigrationStartedAt = ref<Date | null>(null)
const lastMigrationDate = ref<Date | null>(null)
const message = ref('')
const migratorAuthCode = ref('')
const migrator = computed<Migrator>(() => MIGRATORS[props.service])
const migrator = computed(() => MIGRATORS[props.service])
const migrationService = shallowReactive(new AbstractMigrationService(migrator.value.id))
const migrationFileService = shallowReactive(new AbstractMigrationFileService(migrator.value.id))
@ -145,32 +130,23 @@ async function initMigration() {
if (!migratorAuthCode.value) {
return
}
const {startedAt, finishedAt} = await migrationService.getStatus()
if (startedAt) {
lastMigrationStartedAt.value = parseDateOrNull(startedAt)
}
if (finishedAt) {
lastMigrationFinishedAt.value = parseDateOrNull(finishedAt)
if (lastMigrationFinishedAt.value) {
const {time} = await migrationService.getStatus()
if (time) {
lastMigrationDate.value = parseDateOrNull(time)
if (lastMigrationDate.value) {
return
}
}
if (lastMigrationStartedAt.value && lastMigrationFinishedAt.value === null) {
// Migration already in progress
return
}
await migrate()
}
initMigration()
const uploadInput = ref<HTMLInputElement | null>(null)
async function migrate() {
isMigrating.value = true
lastMigrationFinishedAt.value = null
lastMigrationDate.value = null
message.value = ''
let migrationConfig: MigrationConfig | File = {code: migratorAuthCode.value}

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