Merge branch 'main' into feature/vue3-modals-with-router-4
This commit is contained in:
commit
423195155e
19 changed files with 1038 additions and 905 deletions
|
@ -1,4 +1,4 @@
|
||||||
import faker from 'faker'
|
import faker from '@faker-js/faker'
|
||||||
import {Factory} from '../support/factory'
|
import {Factory} from '../support/factory'
|
||||||
import {formatISO} from 'date-fns'
|
import {formatISO} from 'date-fns'
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import faker from 'faker'
|
import faker from '@faker-js/faker'
|
||||||
|
|
||||||
import {Factory} from '../support/factory'
|
import {Factory} from '../support/factory'
|
||||||
import {formatISO} from 'date-fns'
|
import {formatISO} from 'date-fns'
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import {Factory} from '../support/factory'
|
import {Factory} from '../support/factory'
|
||||||
import {formatISO} from "date-fns"
|
import {formatISO} from "date-fns"
|
||||||
import faker from 'faker'
|
import faker from '@faker-js/faker'
|
||||||
|
|
||||||
export class LinkShareFactory extends Factory {
|
export class LinkShareFactory extends Factory {
|
||||||
static table = 'link_shares'
|
static table = 'link_shares'
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import {Factory} from '../support/factory'
|
import {Factory} from '../support/factory'
|
||||||
import {formatISO} from "date-fns"
|
import {formatISO} from "date-fns"
|
||||||
import faker from 'faker'
|
import faker from '@faker-js/faker'
|
||||||
|
|
||||||
export class ListFactory extends Factory {
|
export class ListFactory extends Factory {
|
||||||
static table = 'lists'
|
static table = 'lists'
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import faker from 'faker'
|
import faker from '@faker-js/faker'
|
||||||
import {Factory} from '../support/factory'
|
import {Factory} from '../support/factory'
|
||||||
import {formatISO} from 'date-fns'
|
import {formatISO} from 'date-fns'
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import faker from 'faker'
|
import faker from '@faker-js/faker'
|
||||||
import {Factory} from '../support/factory'
|
import {Factory} from '../support/factory'
|
||||||
import {formatISO} from 'date-fns'
|
import {formatISO} from 'date-fns'
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import faker from 'faker'
|
import faker from '@faker-js/faker'
|
||||||
|
|
||||||
import {Factory} from '../support/factory'
|
import {Factory} from '../support/factory'
|
||||||
import {formatISO} from "date-fns"
|
import {formatISO} from "date-fns"
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import faker from 'faker'
|
import faker from '@faker-js/faker'
|
||||||
import {Factory} from '../support/factory'
|
import {Factory} from '../support/factory'
|
||||||
import {formatISO} from 'date-fns'
|
import {formatISO} from 'date-fns'
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import faker from 'faker'
|
import faker from '@faker-js/faker'
|
||||||
|
|
||||||
import {Factory} from '../support/factory'
|
import {Factory} from '../support/factory'
|
||||||
import {formatISO} from "date-fns"
|
import {formatISO} from "date-fns"
|
||||||
|
|
56
package.json
56
package.json
|
@ -20,18 +20,18 @@
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@github/hotkey": "1.6.1",
|
"@github/hotkey": "1.6.1",
|
||||||
"@kyvg/vue3-notification": "2.3.4",
|
"@kyvg/vue3-notification": "2.3.4",
|
||||||
"@sentry/tracing": "6.16.1",
|
"@sentry/tracing": "6.17.3",
|
||||||
"@sentry/vue": "6.16.1",
|
"@sentry/vue": "6.17.3",
|
||||||
"@types/is-touch-device": "1.0.0",
|
"@types/is-touch-device": "1.0.0",
|
||||||
"@vue/compat": "3.2.27",
|
"@vue/compat": "3.2.29",
|
||||||
"@vueuse/core": "7.5.2",
|
"@vueuse/core": "7.5.5",
|
||||||
"@vueuse/router": "7.5.3",
|
"@vueuse/router": "7.5.5",
|
||||||
"bulma-css-variables": "0.9.33",
|
"bulma-css-variables": "0.9.33",
|
||||||
"camel-case": "4.1.2",
|
"camel-case": "4.1.2",
|
||||||
"codemirror": "5.65.0",
|
"codemirror": "5.65.1",
|
||||||
"copy-to-clipboard": "3.3.1",
|
"copy-to-clipboard": "3.3.1",
|
||||||
"date-fns": "2.28.0",
|
"date-fns": "2.28.0",
|
||||||
"dompurify": "2.3.4",
|
"dompurify": "2.3.5",
|
||||||
"easymde": "2.16.1",
|
"easymde": "2.16.1",
|
||||||
"flatpickr": "4.6.9",
|
"flatpickr": "4.6.9",
|
||||||
"flexsearch": "0.7.21",
|
"flexsearch": "0.7.21",
|
||||||
|
@ -39,16 +39,16 @@
|
||||||
"is-touch-device": "1.0.1",
|
"is-touch-device": "1.0.1",
|
||||||
"lodash.clonedeep": "4.5.0",
|
"lodash.clonedeep": "4.5.0",
|
||||||
"lodash.debounce": "4.0.8",
|
"lodash.debounce": "4.0.8",
|
||||||
"marked": "4.0.10",
|
"marked": "4.0.12",
|
||||||
"register-service-worker": "1.7.2",
|
"register-service-worker": "1.7.2",
|
||||||
"snake-case": "3.0.4",
|
"snake-case": "3.0.4",
|
||||||
"ufo": "0.7.9",
|
"ufo": "0.7.9",
|
||||||
"v-tooltip": "4.0.0-beta.17",
|
"v-tooltip": "4.0.0-beta.17",
|
||||||
"vue": "3.2.27",
|
"vue": "3.2.29",
|
||||||
"vue-advanced-cropper": "2.7.1",
|
"vue-advanced-cropper": "2.8.0",
|
||||||
"vue-drag-resize": "2.0.3",
|
"vue-drag-resize": "2.0.3",
|
||||||
"vue-flatpickr-component": "9.0.5",
|
"vue-flatpickr-component": "9.0.5",
|
||||||
"vue-i18n": "9.2.0-beta.28",
|
"vue-i18n": "9.2.0-beta.30",
|
||||||
"vue-router": "4.0.12",
|
"vue-router": "4.0.12",
|
||||||
"vuedraggable": "4.1.0",
|
"vuedraggable": "4.1.0",
|
||||||
"vuex": "4.0.2",
|
"vuex": "4.0.2",
|
||||||
|
@ -56,41 +56,41 @@
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@4tw/cypress-drag-drop": "2.1.0",
|
"@4tw/cypress-drag-drop": "2.1.0",
|
||||||
|
"@faker-js/faker": "6.0.0-alpha.5",
|
||||||
"@fortawesome/fontawesome-svg-core": "1.2.36",
|
"@fortawesome/fontawesome-svg-core": "1.2.36",
|
||||||
"@fortawesome/free-regular-svg-icons": "5.15.4",
|
"@fortawesome/free-regular-svg-icons": "5.15.4",
|
||||||
"@fortawesome/free-solid-svg-icons": "5.15.4",
|
"@fortawesome/free-solid-svg-icons": "5.15.4",
|
||||||
"@fortawesome/vue-fontawesome": "3.0.0-5",
|
"@fortawesome/vue-fontawesome": "3.0.0-5",
|
||||||
"@types/flexsearch": "0.7.2",
|
"@types/flexsearch": "0.7.2",
|
||||||
"@typescript-eslint/eslint-plugin": "5.10.0",
|
"@typescript-eslint/eslint-plugin": "5.10.1",
|
||||||
"@typescript-eslint/parser": "5.10.0",
|
"@typescript-eslint/parser": "5.10.1",
|
||||||
"@vitejs/plugin-legacy": "1.6.4",
|
"@vitejs/plugin-legacy": "1.6.4",
|
||||||
"@vitejs/plugin-vue": "2.0.1",
|
"@vitejs/plugin-vue": "2.1.0",
|
||||||
"@vue/eslint-config-typescript": "10.0.0",
|
"@vue/eslint-config-typescript": "10.0.0",
|
||||||
"autoprefixer": "10.4.2",
|
"autoprefixer": "10.4.2",
|
||||||
"axios": "0.25.0",
|
"axios": "0.25.0",
|
||||||
"browserslist": "4.19.1",
|
"browserslist": "4.19.1",
|
||||||
"caniuse-lite": "1.0.30001300",
|
"caniuse-lite": "1.0.30001304",
|
||||||
"cypress": "9.2.1",
|
"cypress": "9.3.1",
|
||||||
"cypress-file-upload": "5.0.8",
|
"cypress-file-upload": "5.0.8",
|
||||||
"esbuild": "0.14.11",
|
"esbuild": "0.14.14",
|
||||||
"eslint": "8.7.0",
|
"eslint": "8.8.0",
|
||||||
"eslint-plugin-vue": "8.3.0",
|
"eslint-plugin-vue": "8.4.0",
|
||||||
"express": "4.17.2",
|
"express": "4.17.2",
|
||||||
"faker": "5.5.3",
|
"netlify-cli": "8.13.0",
|
||||||
"netlify-cli": "8.8.2",
|
"happy-dom": "2.30.1",
|
||||||
"happy-dom": "2.27.0",
|
|
||||||
"postcss": "8.4.5",
|
"postcss": "8.4.5",
|
||||||
"postcss-preset-env": "7.2.3",
|
"postcss-preset-env": "7.2.3",
|
||||||
"rollup": "2.64.0",
|
"rollup": "2.66.1",
|
||||||
"rollup-plugin-visualizer": "5.5.4",
|
"rollup-plugin-visualizer": "5.5.4",
|
||||||
"sass": "1.48.0",
|
"sass": "1.49.0",
|
||||||
"slugify": "1.6.5",
|
"slugify": "1.6.5",
|
||||||
"typescript": "4.5.4",
|
"typescript": "4.5.5",
|
||||||
"vite": "2.7.12",
|
"vite": "2.7.13",
|
||||||
"vite-plugin-pwa": "0.11.13",
|
"vite-plugin-pwa": "0.11.13",
|
||||||
"vite-svg-loader": "3.1.2",
|
"vite-svg-loader": "3.1.2",
|
||||||
"vitest": "0.1.20",
|
"vitest": "0.2.5",
|
||||||
"vue-tsc": "0.30.5",
|
"vue-tsc": "0.31.1",
|
||||||
"wait-on": "6.0.0",
|
"wait-on": "6.0.0",
|
||||||
"workbox-cli": "6.4.2"
|
"workbox-cli": "6.4.2"
|
||||||
},
|
},
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
<aside :class="{'is-active': menuActive}" class="namespace-container">
|
<aside :class="{'is-active': menuActive}" class="namespace-container">
|
||||||
<nav class="menu top-menu">
|
<nav class="menu top-menu">
|
||||||
<router-link :to="{name: 'home'}" class="logo">
|
<router-link :to="{name: 'home'}" class="logo">
|
||||||
<Logo width="164" height="48" />
|
<Logo width="164" height="48"/>
|
||||||
</router-link>
|
</router-link>
|
||||||
<ul class="menu-list">
|
<ul class="menu-list">
|
||||||
<li>
|
<li>
|
||||||
|
@ -49,28 +49,32 @@
|
||||||
</nav>
|
</nav>
|
||||||
|
|
||||||
<nav class="menu namespaces-lists loader-container is-loading-small" :class="{'is-loading': loading}">
|
<nav class="menu namespaces-lists loader-container is-loading-small" :class="{'is-loading': loading}">
|
||||||
<template v-for="(n, nk) in namespaces" :key="n.id" >
|
<template v-for="(n, nk) in namespaces" :key="n.id">
|
||||||
<div class="namespace-title" :class="{'has-menu': n.id > 0}">
|
<div class="namespace-title" :class="{'has-menu': n.id > 0}">
|
||||||
<span
|
<span
|
||||||
@click="toggleLists(n.id)"
|
@click="toggleLists(n.id)"
|
||||||
class="menu-label"
|
class="menu-label"
|
||||||
v-tooltip="namespaceTitles[nk]">
|
v-tooltip="namespaceTitles[nk]"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
v-if="n.hexColor !== ''"
|
||||||
|
:style="{ backgroundColor: n.hexColor }"
|
||||||
|
class="color-bubble"
|
||||||
|
/>
|
||||||
<span class="name">
|
<span class="name">
|
||||||
<span
|
|
||||||
:style="{ backgroundColor: n.hexColor }"
|
|
||||||
class="color-bubble"
|
|
||||||
v-if="n.hexColor !== ''">
|
|
||||||
</span>
|
|
||||||
{{ namespaceTitles[nk] }}
|
{{ namespaceTitles[nk] }}
|
||||||
</span>
|
</span>
|
||||||
|
<a
|
||||||
|
class="icon is-small toggle-lists-icon pl-2"
|
||||||
|
:class="{'active': typeof listsVisible[n.id] !== 'undefined' ? listsVisible[n.id] : true}"
|
||||||
|
@click="toggleLists(n.id)"
|
||||||
|
>
|
||||||
|
<icon icon="chevron-down"/>
|
||||||
|
</a>
|
||||||
|
<span class="count" :class="{'ml-2 mr-0': n.id > 0}">
|
||||||
|
({{ namespaceListsCount[nk] }})
|
||||||
|
</span>
|
||||||
</span>
|
</span>
|
||||||
<a
|
|
||||||
class="icon is-small toggle-lists-icon"
|
|
||||||
:class="{'active': typeof listsVisible[n.id] !== 'undefined' ? listsVisible[n.id] : true}"
|
|
||||||
@click="toggleLists(n.id)"
|
|
||||||
>
|
|
||||||
<icon icon="chevron-down"/>
|
|
||||||
</a>
|
|
||||||
<namespace-settings-dropdown :namespace="n" v-if="n.id > 0"/>
|
<namespace-settings-dropdown :namespace="n" v-if="n.id > 0"/>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
|
@ -86,13 +90,15 @@
|
||||||
v-bind="dragOptions"
|
v-bind="dragOptions"
|
||||||
:modelValue="activeLists[nk]"
|
:modelValue="activeLists[nk]"
|
||||||
@update:modelValue="(lists) => updateActiveLists(n, lists)"
|
@update:modelValue="(lists) => updateActiveLists(n, lists)"
|
||||||
:group="`namespace-${n.id}-lists`"
|
group="namespace-lists"
|
||||||
@start="() => drag = true"
|
@start="() => drag = true"
|
||||||
@end="e => saveListPosition(e, nk)"
|
@end="saveListPosition"
|
||||||
handle=".handle"
|
handle=".handle"
|
||||||
:disabled="n.id < 0 || null"
|
:disabled="n.id < 0 || null"
|
||||||
tag="transition-group"
|
tag="transition-group"
|
||||||
item-key="id"
|
item-key="id"
|
||||||
|
:data-namespace-id="n.id"
|
||||||
|
:data-namespace-index="nk"
|
||||||
:component-data="{
|
:component-data="{
|
||||||
type: 'transition',
|
type: 'transition',
|
||||||
tag: 'ul',
|
tag: 'ul',
|
||||||
|
@ -134,7 +140,7 @@
|
||||||
:class="{'is-favorite': l.isFavorite}"
|
:class="{'is-favorite': l.isFavorite}"
|
||||||
@click.prevent.stop="toggleFavoriteList(l)"
|
@click.prevent.stop="toggleFavoriteList(l)"
|
||||||
class="favorite">
|
class="favorite">
|
||||||
<icon :icon="l.isFavorite ? 'star' : ['far', 'star']" />
|
<icon :icon="l.isFavorite ? 'star' : ['far', 'star']"/>
|
||||||
</span>
|
</span>
|
||||||
</a>
|
</a>
|
||||||
</router-link>
|
</router-link>
|
||||||
|
@ -146,7 +152,7 @@
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
</nav>
|
</nav>
|
||||||
<PoweredByLink />
|
<PoweredByLink/>
|
||||||
</aside>
|
</aside>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
@ -194,13 +200,13 @@ export default {
|
||||||
loading: state => state[LOADING] && state[LOADING_MODULE] === 'namespaces',
|
loading: state => state[LOADING] && state[LOADING_MODULE] === 'namespaces',
|
||||||
}),
|
}),
|
||||||
activeLists() {
|
activeLists() {
|
||||||
return this.namespaces.map(({lists}) => lists?.filter(item => !item.isArchived))
|
return this.namespaces.map(({lists}) => lists?.filter(item => typeof item !== 'undefined' && !item.isArchived))
|
||||||
},
|
},
|
||||||
namespaceTitles() {
|
namespaceTitles() {
|
||||||
return this.namespaces.map((namespace, index) => {
|
return this.namespaces.map((namespace) => this.getNamespaceTitle(namespace))
|
||||||
const title = this.getNamespaceTitle(namespace)
|
},
|
||||||
return `${title} (${this.activeLists[index]?.length ?? 0})`
|
namespaceListsCount() {
|
||||||
})
|
return this.namespaces.map((_, index) => this.activeLists[index]?.length ?? 0)
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
beforeCreate() {
|
beforeCreate() {
|
||||||
|
@ -237,15 +243,15 @@ export default {
|
||||||
this.listsVisible[namespaceId] = !this.listsVisible[namespaceId]
|
this.listsVisible[namespaceId] = !this.listsVisible[namespaceId]
|
||||||
},
|
},
|
||||||
updateActiveLists(namespace, activeLists) {
|
updateActiveLists(namespace, activeLists) {
|
||||||
// this is a bit hacky: since we do have to filter out the archived items from the list
|
// This is a bit hacky: since we do have to filter out the archived items from the list
|
||||||
// for vue draggable updating it is not as simple as replacing it.
|
// for vue draggable updating it is not as simple as replacing it.
|
||||||
// instead we iterate over the non archived items in the old list and replace them with the ones in their new order
|
// To work around this, we merge the active lists with the archived ones. Doing so breaks the order
|
||||||
const lists = namespace.lists.map((item) => {
|
// because now all archived lists are sorted after the active ones. This is fine because they are sorted
|
||||||
if (item.isArchived) {
|
// later when showing them anyway, and it makes the merging happening here a lot easier.
|
||||||
return item
|
const lists = [
|
||||||
}
|
...activeLists,
|
||||||
return activeLists.shift()
|
...namespace.lists.filter(l => l.isArchived),
|
||||||
})
|
]
|
||||||
|
|
||||||
const newNamespace = {
|
const newNamespace = {
|
||||||
...namespace,
|
...namespace,
|
||||||
|
@ -255,8 +261,11 @@ export default {
|
||||||
this.$store.commit('namespaces/setNamespaceById', newNamespace)
|
this.$store.commit('namespaces/setNamespaceById', newNamespace)
|
||||||
},
|
},
|
||||||
|
|
||||||
async saveListPosition(e, namespaceIndex) {
|
async saveListPosition(e) {
|
||||||
const listsActive = this.activeLists[namespaceIndex]
|
const namespaceId = parseInt(e.to.dataset.namespaceId)
|
||||||
|
const newNamespaceIndex = parseInt(e.to.dataset.namespaceIndex)
|
||||||
|
|
||||||
|
const listsActive = this.activeLists[newNamespaceIndex]
|
||||||
const list = listsActive[e.newIndex]
|
const list = listsActive[e.newIndex]
|
||||||
const listBefore = listsActive[e.newIndex - 1] ?? null
|
const listBefore = listsActive[e.newIndex - 1] ?? null
|
||||||
const listAfter = listsActive[e.newIndex + 1] ?? null
|
const listAfter = listsActive[e.newIndex + 1] ?? null
|
||||||
|
@ -269,6 +278,7 @@ export default {
|
||||||
await this.$store.dispatch('lists/updateList', {
|
await this.$store.dispatch('lists/updateList', {
|
||||||
...list,
|
...list,
|
||||||
position,
|
position,
|
||||||
|
namespaceId,
|
||||||
})
|
})
|
||||||
} finally {
|
} finally {
|
||||||
this.listUpdating[list.id] = false
|
this.listUpdating[list.id] = false
|
||||||
|
@ -365,8 +375,9 @@ $vikunja-nav-selected-width: 0.4rem;
|
||||||
|
|
||||||
.menu-label {
|
.menu-label {
|
||||||
.color-bubble {
|
.color-bubble {
|
||||||
width: 14px !important;
|
width: 14px;
|
||||||
height: 14px !important;
|
height: 14px;
|
||||||
|
flex-basis: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
.is-archived {
|
.is-archived {
|
||||||
|
@ -387,6 +398,12 @@ $vikunja-nav-selected-width: 0.4rem;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
|
margin-right: auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.count {
|
||||||
|
color: var(--grey-500);
|
||||||
|
margin-right: .5rem;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<template>
|
<template>
|
||||||
<x-button
|
<x-button
|
||||||
variant="secondary"
|
variant="secondary"
|
||||||
:icon="icon"
|
:icon="iconName"
|
||||||
v-tooltip="tooltipText"
|
v-tooltip="tooltipText"
|
||||||
@click="changeSubscription"
|
@click="changeSubscription"
|
||||||
:disabled="disabled || null"
|
:disabled="disabled || null"
|
||||||
|
@ -16,7 +16,7 @@
|
||||||
v-else
|
v-else
|
||||||
>
|
>
|
||||||
<span class="icon">
|
<span class="icon">
|
||||||
<icon :icon="icon"/>
|
<icon :icon="iconName"/>
|
||||||
</span>
|
</span>
|
||||||
{{ buttonText }}
|
{{ buttonText }}
|
||||||
</a>
|
</a>
|
||||||
|
@ -74,7 +74,7 @@ const tooltipText = computed(() => {
|
||||||
})
|
})
|
||||||
|
|
||||||
const buttonText = computed(() => props.subscription !== null ? t('task.subscription.unsubscribe') : t('task.subscription.subscribe'))
|
const buttonText = computed(() => props.subscription !== null ? t('task.subscription.unsubscribe') : t('task.subscription.subscribe'))
|
||||||
const icon = computed(() => props.subscription !== null ? ['far', 'bell-slash'] : 'bell')
|
const iconName = computed(() => props.subscription !== null ? ['far', 'bell-slash'] : 'bell')
|
||||||
const disabled = computed(() => {
|
const disabled = computed(() => {
|
||||||
if (props.subscription === null) {
|
if (props.subscription === null) {
|
||||||
return false
|
return false
|
||||||
|
|
|
@ -288,7 +288,7 @@ const getDateFromWeekday = (text: string): dateFoundResult => {
|
||||||
}
|
}
|
||||||
|
|
||||||
const getDayFromText = (text: string) => {
|
const getDayFromText = (text: string) => {
|
||||||
const matcher = /(([1-2][0-9])|(3[01])|(0?[1-9]))(st|nd|rd|th|\.)/ig
|
const matcher = /($| )(([1-2][0-9])|(3[01])|(0?[1-9]))(st|nd|rd|th|\.)($| )/ig
|
||||||
const results = matcher.exec(text)
|
const results = matcher.exec(text)
|
||||||
if (results === null) {
|
if (results === null) {
|
||||||
return {
|
return {
|
||||||
|
@ -302,16 +302,16 @@ const getDayFromText = (text: string) => {
|
||||||
const day = parseInt(results[0])
|
const day = parseInt(results[0])
|
||||||
date.setDate(day)
|
date.setDate(day)
|
||||||
|
|
||||||
// If the parsed day is the 31st but the next month only has 30 days, setting the day to 31 will "overflow" the
|
// If the parsed day is the 31st (or 29+ and the next month is february) but the next month only has 30 days,
|
||||||
// date to the next month, but the first.
|
// setting the day to 31 will "overflow" the date to the next month, but the first.
|
||||||
// This would look like a very weired bug. Now, to prevent that, we check if the day is the same as parsed after
|
// This would look like a very weired bug. Now, to prevent that, we check if the day is the same as parsed after
|
||||||
// setting it for the first time and set it again if it isn't - that would mean the month overflowed.
|
// setting it for the first time and set it again if it isn't - that would mean the month overflowed.
|
||||||
if (day === 31 && date.getDate() !== day) {
|
while (date < now) {
|
||||||
date.setDate(day)
|
date.setMonth(date.getMonth() + 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (date < now) {
|
if (date.getDate() !== day) {
|
||||||
date.setMonth(date.getMonth() + 1)
|
date.setDate(day)
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|
|
@ -24,7 +24,7 @@
|
||||||
},
|
},
|
||||||
"offline": {
|
"offline": {
|
||||||
"title": "Sei offline.",
|
"title": "Sei offline.",
|
||||||
"text": "Please check your network connection and try again."
|
"text": "Controlla la connessione di rete e riprova."
|
||||||
},
|
},
|
||||||
"user": {
|
"user": {
|
||||||
"auth": {
|
"auth": {
|
||||||
|
@ -36,7 +36,7 @@
|
||||||
"password": "Password",
|
"password": "Password",
|
||||||
"passwordRepeat": "Digita di nuovo la tua password",
|
"passwordRepeat": "Digita di nuovo la tua password",
|
||||||
"passwordPlaceholder": "es. ••••••••••••",
|
"passwordPlaceholder": "es. ••••••••••••",
|
||||||
"forgotPassword": "Forgot your password?",
|
"forgotPassword": "Password dimenticata?",
|
||||||
"resetPassword": "Reimposta la tua password",
|
"resetPassword": "Reimposta la tua password",
|
||||||
"resetPasswordAction": "Inviami il link per reimpostare la password",
|
"resetPasswordAction": "Inviami il link per reimpostare la password",
|
||||||
"resetPasswordSuccess": "Controlla la tua casella di posta! Dovresti avere un'e-mail con le istruzioni su come reimpostare la password.",
|
"resetPasswordSuccess": "Controlla la tua casella di posta! Dovresti avere un'e-mail con le istruzioni su come reimpostare la password.",
|
||||||
|
@ -48,7 +48,7 @@
|
||||||
"register": "Registrati",
|
"register": "Registrati",
|
||||||
"loginWith": "Accedi con {provider}",
|
"loginWith": "Accedi con {provider}",
|
||||||
"authenticating": "Autenticazione…",
|
"authenticating": "Autenticazione…",
|
||||||
"openIdStateError": "State does not match, refusing to continue!",
|
"openIdStateError": "Stato non corrispondente, impossibile continuare!",
|
||||||
"openIdGeneralError": "Si è verificato un errore durante l'autenticazione con terze parti.",
|
"openIdGeneralError": "Si è verificato un errore durante l'autenticazione con terze parti.",
|
||||||
"logout": "Esci"
|
"logout": "Esci"
|
||||||
},
|
},
|
||||||
|
@ -103,31 +103,31 @@
|
||||||
"title": "Avatar",
|
"title": "Avatar",
|
||||||
"initials": "Iniziali",
|
"initials": "Iniziali",
|
||||||
"gravatar": "Gravatar",
|
"gravatar": "Gravatar",
|
||||||
"marble": "Marble",
|
"marble": "Marmo",
|
||||||
"upload": "Carica",
|
"upload": "Carica",
|
||||||
"uploadAvatar": "Carica Avatar",
|
"uploadAvatar": "Carica Avatar",
|
||||||
"statusUpdateSuccess": "Avatar status was updated successfully!",
|
"statusUpdateSuccess": "Avatar aggiornato!",
|
||||||
"setSuccess": "L'avatar è stato impostato con successo!"
|
"setSuccess": "L'avatar è stato impostato con successo!"
|
||||||
},
|
},
|
||||||
"quickAddMagic": {
|
"quickAddMagic": {
|
||||||
"title": "Quick Add Magic Mode",
|
"title": "Modalità Aggiunta Rapida Magica",
|
||||||
"disabled": "Disabilitato",
|
"disabled": "Disabilitato",
|
||||||
"todoist": "Todoist",
|
"todoist": "Todoist",
|
||||||
"vikunja": "Vikunja"
|
"vikunja": "Vikunja"
|
||||||
},
|
},
|
||||||
"appearance": {
|
"appearance": {
|
||||||
"title": "Color Scheme",
|
"title": "Tema",
|
||||||
"setSuccess": "Saved change of color scheme to {colorScheme}",
|
"setSuccess": "Tema cambiato in {colorScheme}",
|
||||||
"colorScheme": {
|
"colorScheme": {
|
||||||
"light": "Light",
|
"light": "Chiaro",
|
||||||
"system": "System",
|
"system": "Sistema",
|
||||||
"dark": "Dark"
|
"dark": "Scuro"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"deletion": {
|
"deletion": {
|
||||||
"title": "Delete your Vikunja Account",
|
"title": "Elimina il tuo Account Vikunja",
|
||||||
"text1": "The deletion of your account is permanent and cannot be undone. We will delete all your namespaces, lists, tasks and everything associated with it.",
|
"text1": "La cancellazione del tuo account è permanente e non può essere annullata. Elimineremo tutti i tuoi namespace, liste, attività e tutto ciò che è ad esso associato.",
|
||||||
"text2": "Per continuare, inserisci la tua password. Riceverai un'e-mail con ulteriori istruzioni.",
|
"text2": "Per continuare, inserisci la tua password. Riceverai un'e-mail con ulteriori istruzioni.",
|
||||||
"confirm": "Elimina il mio profilo",
|
"confirm": "Elimina il mio profilo",
|
||||||
"requestSuccess": "Richiesta riuscita. Riceverai un'e-mail con ulteriori istruzioni.",
|
"requestSuccess": "Richiesta riuscita. Riceverai un'e-mail con ulteriori istruzioni.",
|
||||||
|
@ -141,7 +141,7 @@
|
||||||
},
|
},
|
||||||
"export": {
|
"export": {
|
||||||
"title": "Esporta i tuoi dati Vikunja",
|
"title": "Esporta i tuoi dati Vikunja",
|
||||||
"description": "You can request a copy of all your Vikunja data. This include Namespaces, Lists, Tasks and everything associated to them. You can import this data in any Vikunja instance through the migration function.",
|
"description": "Puoi richiedere una copia di tutti i tuoi dati all'interno di Vikunja. Questo include i Namespace, le Liste, le Attività e tutto ciò che è loro associato. È possibile importare questi dati in qualsiasi istanza Vikunja attraverso la funzione di migrazione.",
|
||||||
"descriptionPasswordRequired": "Inserisci la tua password per procedere:",
|
"descriptionPasswordRequired": "Inserisci la tua password per procedere:",
|
||||||
"request": "Richiedi una copia dei miei dati Vikunja",
|
"request": "Richiedi una copia dei miei dati Vikunja",
|
||||||
"success": "Hai richiesto con successo i tuoi dati Vikunja! Ti invieremo un'e-mail una volta che saranno pronti da scaricare.",
|
"success": "Hai richiesto con successo i tuoi dati Vikunja! Ti invieremo un'e-mail una volta che saranno pronti da scaricare.",
|
||||||
|
@ -157,7 +157,7 @@
|
||||||
"searchSelect": "Fare clic o premere invio per selezionare questa lista",
|
"searchSelect": "Fare clic o premere invio per selezionare questa lista",
|
||||||
"shared": "Liste Condivise",
|
"shared": "Liste Condivise",
|
||||||
"create": {
|
"create": {
|
||||||
"header": "New list",
|
"header": "Nuova lista",
|
||||||
"titlePlaceholder": "Il titolo della lista va qui…",
|
"titlePlaceholder": "Il titolo della lista va qui…",
|
||||||
"addTitleRequired": "Specifica un titolo.",
|
"addTitleRequired": "Specifica un titolo.",
|
||||||
"createdSuccess": "La lista è stata creata correttamente.",
|
"createdSuccess": "La lista è stata creata correttamente.",
|
||||||
|
@ -191,7 +191,7 @@
|
||||||
"duplicate": {
|
"duplicate": {
|
||||||
"title": "Duplica questa lista",
|
"title": "Duplica questa lista",
|
||||||
"label": "Duplica",
|
"label": "Duplica",
|
||||||
"text": "Select a namespace which should hold the duplicated list:",
|
"text": "Seleziona un namespace che dovrebbe contenere l'elenco duplicato:",
|
||||||
"success": "Lista duplicata."
|
"success": "Lista duplicata."
|
||||||
},
|
},
|
||||||
"edit": {
|
"edit": {
|
||||||
|
@ -279,23 +279,23 @@
|
||||||
"title": "Kanban",
|
"title": "Kanban",
|
||||||
"limit": "Limite: {limit}",
|
"limit": "Limite: {limit}",
|
||||||
"noLimit": "Non Impostato",
|
"noLimit": "Non Impostato",
|
||||||
"doneBucket": "Done bucket",
|
"doneBucket": "Colonna attività completate",
|
||||||
"doneBucketHint": "All tasks moved into this bucket will automatically marked as done.",
|
"doneBucketHint": "Tutte le attività spostate in questa colonna verranno automaticamente contrassegnate come completate.",
|
||||||
"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.",
|
"doneBucketHintExtended": "Tutte le attività spostate nella colonna attività completate saranno contrassegnate automaticamente come completate. Tutte le attività contrassegnate come completate altrove verranno anche spostate.",
|
||||||
"doneBucketSavedSuccess": "The done bucket has been saved successfully.",
|
"doneBucketSavedSuccess": "Colonna attività completate salvata.",
|
||||||
"deleteLast": "You cannot remove the last bucket.",
|
"deleteLast": "Impossibile eliminare l'ultima colonna.",
|
||||||
"addTaskPlaceholder": "Enter the new task title…",
|
"addTaskPlaceholder": "Inserisci il nuovo titolo dell'attività…",
|
||||||
"addTask": "Aggiungi un'attività",
|
"addTask": "Aggiungi un'attività",
|
||||||
"addAnotherTask": "Aggiungi un'altra attività",
|
"addAnotherTask": "Aggiungi un'altra attività",
|
||||||
"addBucket": "Create a new bucket",
|
"addBucket": "Crea una nuova colonna",
|
||||||
"addBucketPlaceholder": "Enter the new bucket title…",
|
"addBucketPlaceholder": "Inserisci il titolo della nuova colonna…",
|
||||||
"deleteHeaderBucket": "Delete the bucket",
|
"deleteHeaderBucket": "Elimina la colonna",
|
||||||
"deleteBucketText1": "Are you sure you want to delete this bucket?",
|
"deleteBucketText1": "Confermi di voler eliminare questa colonna?",
|
||||||
"deleteBucketText2": "This will not delete any tasks but move them into the default bucket.",
|
"deleteBucketText2": "Questo non eliminerà nessuna attività, ma la sposterà nel bucket predefinito.",
|
||||||
"deleteBucketSuccess": "The bucket has been deleted successfully.",
|
"deleteBucketSuccess": "Colonna eliminata.",
|
||||||
"bucketTitleSavedSuccess": "The bucket title has been saved successfully.",
|
"bucketTitleSavedSuccess": "Titolo della colonna salvato.",
|
||||||
"bucketLimitSavedSuccess": "The bucket limit been saved successfully.",
|
"bucketLimitSavedSuccess": "Limite della colonna salvato.",
|
||||||
"collapse": "Collapse this bucket"
|
"collapse": "Comprimi questa colonna"
|
||||||
},
|
},
|
||||||
"pseudo": {
|
"pseudo": {
|
||||||
"favorites": {
|
"favorites": {
|
||||||
|
@ -304,52 +304,52 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"namespace": {
|
"namespace": {
|
||||||
"title": "Namespaces & Lists",
|
"title": "Namespace e Liste",
|
||||||
"namespace": "Namespace",
|
"namespace": "Namespace",
|
||||||
"showArchived": "Show Archived",
|
"showArchived": "Mostra Archiviati",
|
||||||
"noneAvailable": "You don't have any namespaces right now.",
|
"noneAvailable": "Non hai alcun namespace in questo momento.",
|
||||||
"unarchive": "Un-Archive",
|
"unarchive": "De-Archivia",
|
||||||
"archived": "Archived",
|
"archived": "Archiviato",
|
||||||
"noLists": "This namespace does not contain any lists.",
|
"noLists": "Questo namespace non contiene alcuna lista.",
|
||||||
"createList": "Create a new list in this namespace.",
|
"createList": "Crea una nuova lista in questo namespace.",
|
||||||
"namespaces": "Namespaces",
|
"namespaces": "Namespace",
|
||||||
"search": "Type to search for a namespace…",
|
"search": "Digita per cercare un namespace…",
|
||||||
"create": {
|
"create": {
|
||||||
"title": "New namespace",
|
"title": "Nuovo namespace",
|
||||||
"titleRequired": "Please specify a title.",
|
"titleRequired": "Specifica un titolo.",
|
||||||
"explanation": "A namespace is a collection of lists you can share and use to organize your lists with. In fact, every list belongs to a namepace.",
|
"explanation": "Un namespace è una raccolta di liste che puoi condividere e che puoi usare per organizzare le tue liste. Infatti, ogni lista appartiene a un namespace.",
|
||||||
"tooltip": "What's a namespace?",
|
"tooltip": "Che cos'è un namespace?",
|
||||||
"success": "The namespace was successfully created."
|
"success": "Namespace creato."
|
||||||
},
|
},
|
||||||
"archive": {
|
"archive": {
|
||||||
"titleArchive": "Archivia \"{namespace}\"",
|
"titleArchive": "Archivia \"{namespace}\"",
|
||||||
"titleUnarchive": "Un-Archive \"{namespace}\"",
|
"titleUnarchive": "Disarchivia \"{namespace}\"",
|
||||||
"archiveText": "You won't be able to edit this namespace or create new lists until you un-archive it. This will also archive all lists in this namespace.",
|
"archiveText": "Non sarà possibile modificare questo namespace o creare nuove liste fino a quando non verrà disarchiviato. Questo archivierà anche tutte le liste in questo namespace.",
|
||||||
"unarchiveText": "You will be able to create new lists or edit it.",
|
"unarchiveText": "Potrai creare nuove liste o modificarle.",
|
||||||
"success": "The namespace was successfully archived.",
|
"success": "Namespace creato.",
|
||||||
"description": "If a namespace is archived, you cannot create new lists or edit it."
|
"description": "Se un namespace è archiviato, non è possibile creare nuove liste o modificarlo."
|
||||||
},
|
},
|
||||||
"delete": {
|
"delete": {
|
||||||
"title": "Delete \"{namespace}\"",
|
"title": "Elimina \"{namespace}\"",
|
||||||
"text1": "Are you sure you want to delete this namespace and all of its contents?",
|
"text1": "Sei sicuro di voler rimuovere questo namespace e tutto il relativo contenuto?",
|
||||||
"text2": "Questo include tutte le liste e le attività e NON PUÒ ESSERE RIPRISTINATO!",
|
"text2": "Questo include tutte le liste e le attività e NON PUÒ ESSERE RIPRISTINATO!",
|
||||||
"success": "The namespace was successfully deleted."
|
"success": "Namespace eliminato."
|
||||||
},
|
},
|
||||||
"edit": {
|
"edit": {
|
||||||
"title": "Modifica \"{namespace}\"",
|
"title": "Modifica \"{namespace}\"",
|
||||||
"success": "The namespace was successfully updated."
|
"success": "Namespace aggiornato."
|
||||||
},
|
},
|
||||||
"share": {
|
"share": {
|
||||||
"title": "Condividi \"{namespace}\""
|
"title": "Condividi \"{namespace}\""
|
||||||
},
|
},
|
||||||
"attributes": {
|
"attributes": {
|
||||||
"title": "Namespace Title",
|
"title": "Titolo del Namespace",
|
||||||
"titlePlaceholder": "The namespace title goes here…",
|
"titlePlaceholder": "Il titolo del namespace va qui…",
|
||||||
"description": "Descrizione",
|
"description": "Descrizione",
|
||||||
"descriptionPlaceholder": "The namespaces description goes here…",
|
"descriptionPlaceholder": "La descrizione del namespace va qui…",
|
||||||
"color": "Colore",
|
"color": "Colore",
|
||||||
"archived": "Is Archived",
|
"archived": "Archiviato",
|
||||||
"isArchived": "This namespace is archived"
|
"isArchived": "Questo namespace è archiviato"
|
||||||
},
|
},
|
||||||
"pseudo": {
|
"pseudo": {
|
||||||
"sharedLists": {
|
"sharedLists": {
|
||||||
|
@ -365,7 +365,7 @@
|
||||||
},
|
},
|
||||||
"filters": {
|
"filters": {
|
||||||
"title": "Filtri",
|
"title": "Filtri",
|
||||||
"clear": "Clear Filters",
|
"clear": "Pulisci Filtri",
|
||||||
"attributes": {
|
"attributes": {
|
||||||
"title": "Titolo",
|
"title": "Titolo",
|
||||||
"titlePlaceholder": "Il titolo del filtro salvato va qui…",
|
"titlePlaceholder": "Il titolo del filtro salvato va qui…",
|
||||||
|
@ -374,17 +374,17 @@
|
||||||
"includeNulls": "Includi attività che non hanno un valore impostato",
|
"includeNulls": "Includi attività che non hanno un valore impostato",
|
||||||
"requireAll": "Tutti i filtri devono essere veri affinché l'attività venga mostrata",
|
"requireAll": "Tutti i filtri devono essere veri affinché l'attività venga mostrata",
|
||||||
"showDoneTasks": "Mostra Attività Fatte",
|
"showDoneTasks": "Mostra Attività Fatte",
|
||||||
"sortAlphabetically": "Sort Alphabetically",
|
"sortAlphabetically": "Ordine alfabetico",
|
||||||
"enablePriority": "Abilita Filtro Per Priorità",
|
"enablePriority": "Abilita Filtro Per Priorità",
|
||||||
"enablePercentDone": "Abilitare Filtro Per Percentuale Fatta",
|
"enablePercentDone": "Abilitare Filtro Per Percentuale Fatta",
|
||||||
"dueDateRange": "Intervallo Data Di Scadenza",
|
"dueDateRange": "Intervallo Data Di Scadenza",
|
||||||
"startDateRange": "Intervallo Data Iniziale",
|
"startDateRange": "Intervallo Data Iniziale",
|
||||||
"endDateRange": "Intervallo Data Finale",
|
"endDateRange": "Intervallo Data Finale",
|
||||||
"reminderRange": "Reminder Date Range"
|
"reminderRange": "Intervallo date dei promemoria"
|
||||||
},
|
},
|
||||||
"create": {
|
"create": {
|
||||||
"title": "New Saved Filter",
|
"title": "Nuovo Filtro Salvato",
|
||||||
"description": "A saved filter is a virtual list which is computed from a set of filters each time it is accessed. Once created, it will appear in a special namespace.",
|
"description": "Un filtro salvato è una lista virtuale che viene calcolata da un insieme di filtri di volta in volta. Una volta creato, apparirà in un namespace speciale.",
|
||||||
"action": "Crea nuovo filtro salvato"
|
"action": "Crea nuovo filtro salvato"
|
||||||
},
|
},
|
||||||
"delete": {
|
"delete": {
|
||||||
|
@ -446,9 +446,9 @@
|
||||||
},
|
},
|
||||||
"navigation": {
|
"navigation": {
|
||||||
"overview": "Panoramica",
|
"overview": "Panoramica",
|
||||||
"upcoming": "Upcoming",
|
"upcoming": "Prossimamente",
|
||||||
"settings": "Impostazioni",
|
"settings": "Impostazioni",
|
||||||
"imprint": "Imprint",
|
"imprint": "Informazioni legali",
|
||||||
"privacy": "Politica sulla Privacy"
|
"privacy": "Politica sulla Privacy"
|
||||||
},
|
},
|
||||||
"misc": {
|
"misc": {
|
||||||
|
@ -464,19 +464,19 @@
|
||||||
"searchPlaceholder": "Digita per cercare…",
|
"searchPlaceholder": "Digita per cercare…",
|
||||||
"previous": "Precedente",
|
"previous": "Precedente",
|
||||||
"next": "Successivo",
|
"next": "Successivo",
|
||||||
"poweredBy": "Powered by Vikunja",
|
"poweredBy": "Creato con Vikunja",
|
||||||
"info": "Info",
|
"info": "Info",
|
||||||
"create": "Create",
|
"create": "Crea",
|
||||||
"doit": "Fallo!",
|
"doit": "Fallo!",
|
||||||
"saving": "Salvataggio…",
|
"saving": "Salvataggio…",
|
||||||
"saved": "Salvato!",
|
"saved": "Salvato!",
|
||||||
"default": "Predefinito",
|
"default": "Predefinito",
|
||||||
"close": "Chiudi",
|
"close": "Chiudi",
|
||||||
"download": "Scarica",
|
"download": "Scarica",
|
||||||
"showMenu": "Show the menu",
|
"showMenu": "Mostra il menu",
|
||||||
"hideMenu": "Hide the menu",
|
"hideMenu": "Nascondi il menù",
|
||||||
"forExample": "For example:",
|
"forExample": "Ad esempio:",
|
||||||
"welcomeBack": "Welcome Back!"
|
"welcomeBack": "Bentornato!"
|
||||||
},
|
},
|
||||||
"input": {
|
"input": {
|
||||||
"resetColor": "Ripristina Colore",
|
"resetColor": "Ripristina Colore",
|
||||||
|
@ -485,9 +485,9 @@
|
||||||
"tomorrow": "Domani",
|
"tomorrow": "Domani",
|
||||||
"nextMonday": "Lunedì Prossimo",
|
"nextMonday": "Lunedì Prossimo",
|
||||||
"thisWeekend": "Questo fine settimana",
|
"thisWeekend": "Questo fine settimana",
|
||||||
"laterThisWeek": "Later This Week",
|
"laterThisWeek": "Alla fine di questa settimana",
|
||||||
"nextWeek": "Prossima Settimana",
|
"nextWeek": "Prossima Settimana",
|
||||||
"chooseDate": "Choose a date"
|
"chooseDate": "Seleziona una data"
|
||||||
},
|
},
|
||||||
"editor": {
|
"editor": {
|
||||||
"edit": "Modifica",
|
"edit": "Modifica",
|
||||||
|
@ -504,16 +504,16 @@
|
||||||
"quote": "Citazione",
|
"quote": "Citazione",
|
||||||
"unorderedList": "Elenco puntato",
|
"unorderedList": "Elenco puntato",
|
||||||
"orderedList": "Elenco numerato",
|
"orderedList": "Elenco numerato",
|
||||||
"cleanBlock": "Clean Block",
|
"cleanBlock": "Pulisci Blocco",
|
||||||
"link": "Link",
|
"link": "Link",
|
||||||
"image": "Immagine",
|
"image": "Immagine",
|
||||||
"table": "Tabella",
|
"table": "Tabella",
|
||||||
"horizontalRule": "Horizontal Rule",
|
"horizontalRule": "Divisore Orizzontale",
|
||||||
"sideBySide": "Side By Side",
|
"sideBySide": "Affianca",
|
||||||
"guide": "Guide"
|
"guide": "Guida"
|
||||||
},
|
},
|
||||||
"multiselect": {
|
"multiselect": {
|
||||||
"createPlaceholder": "Create new",
|
"createPlaceholder": "Crea nuovo",
|
||||||
"selectPlaceholder": "Clicca o premere invio per selezionare"
|
"selectPlaceholder": "Clicca o premere invio per selezionare"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -533,19 +533,19 @@
|
||||||
"titleDates": "Attività dal {from} al {to}",
|
"titleDates": "Attività dal {from} al {to}",
|
||||||
"noDates": "Mostra attività senza date",
|
"noDates": "Mostra attività senza date",
|
||||||
"current": "Attività attuali",
|
"current": "Attività attuali",
|
||||||
"from": "Tasks from",
|
"from": "Attività dal",
|
||||||
"until": "until",
|
"until": "fino al",
|
||||||
"today": "Oggi",
|
"today": "Oggi",
|
||||||
"nextWeek": "Settimana Prossima",
|
"nextWeek": "Settimana Prossima",
|
||||||
"nextMonth": "Prossimo Mese",
|
"nextMonth": "Prossimo Mese",
|
||||||
"noTasks": "Nothing to do — Have a nice day!"
|
"noTasks": "Nessuna attività — Buona giornata!"
|
||||||
},
|
},
|
||||||
"detail": {
|
"detail": {
|
||||||
"chooseDueDate": "Clicca qui per impostare una data di scadenza",
|
"chooseDueDate": "Clicca qui per impostare una data di scadenza",
|
||||||
"chooseStartDate": "Clicca qui per impostare una data di inizio",
|
"chooseStartDate": "Clicca qui per impostare una data di inizio",
|
||||||
"chooseEndDate": "Clicca qui per impostare una data di fine",
|
"chooseEndDate": "Clicca qui per impostare una data di fine",
|
||||||
"move": "Sposta attività in un'altra lista",
|
"move": "Sposta attività in un'altra lista",
|
||||||
"done": "Mark task done!",
|
"done": "Segna attività fatta!",
|
||||||
"undone": "Segna come non completato",
|
"undone": "Segna come non completato",
|
||||||
"created": "Creato {0} da {1}",
|
"created": "Creato {0} da {1}",
|
||||||
"updated": "Aggiornato {0}",
|
"updated": "Aggiornato {0}",
|
||||||
|
@ -554,21 +554,21 @@
|
||||||
"deleteSuccess": "L'attività è stata eliminata con successo.",
|
"deleteSuccess": "L'attività è stata eliminata con successo.",
|
||||||
"belongsToList": "Questa attività appartiene alla lista '{list}'",
|
"belongsToList": "Questa attività appartiene alla lista '{list}'",
|
||||||
"due": "Scadenza {at}",
|
"due": "Scadenza {at}",
|
||||||
"closePopup": "Close popup",
|
"closePopup": "Chiudi popup",
|
||||||
"delete": {
|
"delete": {
|
||||||
"header": "Elimina questa attività",
|
"header": "Elimina questa attività",
|
||||||
"text1": "Sei sicuro di voler eliminare questa attività?",
|
"text1": "Sei sicuro di voler eliminare questa attività?",
|
||||||
"text2": "Questo rimuoverà anche tutti gli allegati, i promemoria e le relazioni associati a questa attività e non può essere ripristinato!"
|
"text2": "Questo rimuoverà anche tutti gli allegati, i promemoria e le relazioni associati a questa attività e non può essere ripristinato!"
|
||||||
},
|
},
|
||||||
"actions": {
|
"actions": {
|
||||||
"assign": "Assign to a user",
|
"assign": "Assegna ad un utente",
|
||||||
"label": "Aggiungi etichette",
|
"label": "Aggiungi etichette",
|
||||||
"priority": "Imposta Priorità",
|
"priority": "Imposta Priorità",
|
||||||
"dueDate": "Imposta data di scadenza",
|
"dueDate": "Imposta data di scadenza",
|
||||||
"startDate": "Imposta una data di inizio",
|
"startDate": "Imposta una data di inizio",
|
||||||
"endDate": "Imposta una data di fine",
|
"endDate": "Imposta una data di fine",
|
||||||
"reminders": "Imposta promemoria",
|
"reminders": "Imposta promemoria",
|
||||||
"repeatAfter": "Set a repeating interval",
|
"repeatAfter": "Imposta ricorrenza",
|
||||||
"percentDone": "Imposta Percentuale Completata",
|
"percentDone": "Imposta Percentuale Completata",
|
||||||
"attachments": "Aggiungi allegati",
|
"attachments": "Aggiungi allegati",
|
||||||
"relatedTasks": "Aggiungi attività collegate",
|
"relatedTasks": "Aggiungi attività collegate",
|
||||||
|
@ -599,13 +599,13 @@
|
||||||
"updated": "Aggiornato"
|
"updated": "Aggiornato"
|
||||||
},
|
},
|
||||||
"subscription": {
|
"subscription": {
|
||||||
"subscribedThroughParent": "You can't unsubscribe here because you are subscribed to this {entity} through its {parent}.",
|
"subscribedThroughParent": "Non puoi annullare l'iscrizione qui perché sei iscritto a questo {entity} attraverso il suo {parent}.",
|
||||||
"subscribed": "You are currently subscribed to this {entity} and will receive notifications for changes.",
|
"subscribed": "Sei attualmente iscritto a questo {entity} e riceverai notifiche per le modifiche.",
|
||||||
"notSubscribed": "You are not subscribed to this {entity} and won't receive notifications for changes.",
|
"notSubscribed": "Non sei iscritto a questo {entity} e non riceverai notifiche per le modifiche.",
|
||||||
"subscribe": "Subscribe",
|
"subscribe": "Iscriviti",
|
||||||
"unsubscribe": "Unsubscribe",
|
"unsubscribe": "Disiscriviti",
|
||||||
"subscribeSuccess": "You are now subscribed to this {entity}",
|
"subscribeSuccess": "Ti sei iscritto a questo {entity}",
|
||||||
"unsubscribeSuccess": "You are now unsubscribed to this {entity}"
|
"unsubscribeSuccess": "Ti sei disiscritto a questo {entity}"
|
||||||
},
|
},
|
||||||
"attachment": {
|
"attachment": {
|
||||||
"title": "Allegati",
|
"title": "Allegati",
|
||||||
|
@ -623,41 +623,41 @@
|
||||||
"comment": {
|
"comment": {
|
||||||
"title": "Commenti",
|
"title": "Commenti",
|
||||||
"loading": "Caricamento commenti…",
|
"loading": "Caricamento commenti…",
|
||||||
"edited": "edited {date}",
|
"edited": "modificato il {date}",
|
||||||
"creating": "Creazione del commento…",
|
"creating": "Creazione del commento…",
|
||||||
"placeholder": "Aggiungi un commento…",
|
"placeholder": "Aggiungi un commento…",
|
||||||
"comment": "Comment",
|
"comment": "Commenta",
|
||||||
"delete": "Elimina questo commento",
|
"delete": "Elimina questo commento",
|
||||||
"deleteText1": "Sei sicuro di voler eliminare questo commento?",
|
"deleteText1": "Sei sicuro di voler eliminare questo commento?",
|
||||||
"deleteText2": "Questa azione non può essere annullata!",
|
"deleteText2": "Questa azione non può essere annullata!",
|
||||||
"addedSuccess": "Il commento è stato aggiunto correttamente."
|
"addedSuccess": "Il commento è stato aggiunto correttamente."
|
||||||
},
|
},
|
||||||
"deferDueDate": {
|
"deferDueDate": {
|
||||||
"title": "Defer due date",
|
"title": "Rinvia data di scadenza",
|
||||||
"1day": "1 giorno",
|
"1day": "1 giorno",
|
||||||
"3days": "3 giorni",
|
"3days": "3 giorni",
|
||||||
"1week": "1 settimana"
|
"1week": "1 settimana"
|
||||||
},
|
},
|
||||||
"description": {
|
"description": {
|
||||||
"placeholder": "Click here to enter a description…",
|
"placeholder": "Clicca qui per inserire una descrizione…",
|
||||||
"empty": "No description available yet."
|
"empty": "Nessuna descrizione."
|
||||||
},
|
},
|
||||||
"assignee": {
|
"assignee": {
|
||||||
"placeholder": "Type to assign a user…",
|
"placeholder": "Digita per assegnare un utente…",
|
||||||
"selectPlaceholder": "Assegna questo utente",
|
"selectPlaceholder": "Assegna questo utente",
|
||||||
"assignSuccess": "The user has been assigned successfully.",
|
"assignSuccess": "Utente assegnato.",
|
||||||
"unassignSuccess": "The user has been unassigned successfully."
|
"unassignSuccess": "Utente disassegnato."
|
||||||
},
|
},
|
||||||
"label": {
|
"label": {
|
||||||
"placeholder": "Type to add a new label…",
|
"placeholder": "Digita per aggiungere una nuova etichetta…",
|
||||||
"createPlaceholder": "Add this as new label",
|
"createPlaceholder": "Aggiungila come nuova etichetta",
|
||||||
"addSuccess": "Etichetta aggiunta.",
|
"addSuccess": "Etichetta aggiunta.",
|
||||||
"createSuccess": "Etichetta creata.",
|
"createSuccess": "Etichetta creata.",
|
||||||
"removeSuccess": "Etichetta eliminata.",
|
"removeSuccess": "Etichetta eliminata.",
|
||||||
"addCreateSuccess": "Etichetta creata e aggiunta."
|
"addCreateSuccess": "Etichetta creata e aggiunta."
|
||||||
},
|
},
|
||||||
"priority": {
|
"priority": {
|
||||||
"unset": "Unset",
|
"unset": "Azzera",
|
||||||
"low": "Bassa",
|
"low": "Bassa",
|
||||||
"medium": "Media",
|
"medium": "Media",
|
||||||
"high": "Alta",
|
"high": "Alta",
|
||||||
|
@ -665,38 +665,38 @@
|
||||||
"doNow": "FARE ORA"
|
"doNow": "FARE ORA"
|
||||||
},
|
},
|
||||||
"relation": {
|
"relation": {
|
||||||
"add": "Add a New Task Relation",
|
"add": "Aggiungi Attività Collegata",
|
||||||
"new": "New Task Relation",
|
"new": "Nuova Attività Collegata",
|
||||||
"searchPlaceholder": "Type search for a new task to add as related…",
|
"searchPlaceholder": "Digita per cercare un'attività da aggiungere come collegata…",
|
||||||
"createPlaceholder": "Add this as new related task",
|
"createPlaceholder": "Aggiungi come attività collegata",
|
||||||
"differentList": "This task belongs to a different list.",
|
"differentList": "Questa attività è di una lista diversa.",
|
||||||
"differentNamespace": "This task belongs to a different namespace.",
|
"differentNamespace": "Questa attività appartiene ad un namespace diverso.",
|
||||||
"noneYet": "No task relations yet.",
|
"noneYet": "Nessuna attività collegata.",
|
||||||
"delete": "Delete Task Relation",
|
"delete": "Elimina Collegamento Attività",
|
||||||
"deleteText1": "Are you sure you want to delete this task relation?",
|
"deleteText1": "Confermi di voler eliminare questo collegamento attività?",
|
||||||
"deleteText2": "Questa azione non può essere annullata!",
|
"deleteText2": "Questa azione non può essere annullata!",
|
||||||
"select": "Select a relation kind",
|
"select": "Seleziona un tipo di collegamento",
|
||||||
"kinds": {
|
"kinds": {
|
||||||
"subtask": "Subtask | Subtasks",
|
"subtask": "Sotto-attività | Sotto-attività",
|
||||||
"parenttask": "Parent Task | Parent Tasks",
|
"parenttask": "Attività Principale | Attività Principale",
|
||||||
"related": "Related Task | Related Tasks",
|
"related": "Attività Correlata | Attività Correlata",
|
||||||
"duplicateof": "Duplicato Di | Duplicati Di",
|
"duplicateof": "Duplicato Di | Duplicati Di",
|
||||||
"duplicates": "Duplicates | Duplicates",
|
"duplicates": "Duplicato | Duplicati",
|
||||||
"blocking": "Blocking | Blocking",
|
"blocking": "Bloccante | Bloccanti",
|
||||||
"blocked": "Blocked By | Blocked By",
|
"blocked": "Bloccato Da | Bloccati Da",
|
||||||
"precedes": "Precedes | Precedes",
|
"precedes": "Precede | Precede",
|
||||||
"follows": "Follows | Follows",
|
"follows": "Segue | Segue",
|
||||||
"copiedfrom": "Copied From | Copied From",
|
"copiedfrom": "Copiata Da | Copiate Da",
|
||||||
"copiedto": "Copied To | Copied To"
|
"copiedto": "Copiata In | Copiate In"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"repeat": {
|
"repeat": {
|
||||||
"everyDay": "Ogni Giorno",
|
"everyDay": "Ogni Giorno",
|
||||||
"everyWeek": "Ogni Settimana",
|
"everyWeek": "Ogni Settimana",
|
||||||
"everyMonth": "Ogni Mese",
|
"everyMonth": "Ogni Mese",
|
||||||
"mode": "Repeat mode",
|
"mode": "Modalità Ripetizione",
|
||||||
"monthly": "Mensilmente",
|
"monthly": "Mensilmente",
|
||||||
"fromCurrentDate": "From Current Date",
|
"fromCurrentDate": "Dalla Data Attuale",
|
||||||
"each": "Ogni",
|
"each": "Ogni",
|
||||||
"specifyAmount": "Specifica una quantità…",
|
"specifyAmount": "Specifica una quantità…",
|
||||||
"hours": "Ore",
|
"hours": "Ore",
|
||||||
|
@ -706,32 +706,32 @@
|
||||||
"years": "Anni"
|
"years": "Anni"
|
||||||
},
|
},
|
||||||
"quickAddMagic": {
|
"quickAddMagic": {
|
||||||
"hint": "You can use Quick Add Magic",
|
"hint": "Puoi usare l'Aggiunta Rapida Magica",
|
||||||
"what": "Cosa?",
|
"what": "Cosa?",
|
||||||
"title": "Quick Add Magic",
|
"title": "Aggiunta Rapida Magica",
|
||||||
"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.",
|
"intro": "Quando si crea un'attività, è possibile utilizzare parole chiave speciali per aggiungere direttamente attributi all'attività appena creata. Questo permette di aggiungere gli attributi comuni molto più velocemente.",
|
||||||
"multiple": "Puoi usarlo più volte.",
|
"multiple": "Puoi usarlo più volte.",
|
||||||
"label1": "To add a label, simply prefix the name of the label with {prefix}.",
|
"label1": "Per aggiungere un'etichetta, basta aggiungere il nome dell'etichetta preceduto da {prefix}.",
|
||||||
"label2": "Vikunja will first check if the label already exist and create it if not.",
|
"label2": "Vikunja controllerà prima se l'etichetta esiste già e nel caso la creerà.",
|
||||||
"label3": "To use spaces, simply add a \" around the label name.",
|
"label3": "Per usare gli spazi, basta \" prima e dopo del nome dell'etichetta.",
|
||||||
"label4": "For example: {prefix}\"Label with spaces\".",
|
"label4": "Per esempio: {prefix}\"Etichetta con spazi\".",
|
||||||
"priority1": "To set a task's priority, add a number 1-5, prefixed with a {prefix}.",
|
"priority1": "Per impostare la priorità di un'attività, aggiungi un numero 1-5, preceduto da {prefix}.",
|
||||||
"priority2": "The higher the number, the higher the priority.",
|
"priority2": "Più alto è il numero, più alta è la priorità.",
|
||||||
"assignees": "To directly assign the task to a user, add their username prefixed with {prefix} to the task.",
|
"assignees": "Per assegnare direttamente l'attività a un utente, aggiungere il suo nome utente preceduto da {prefix} all'attività.",
|
||||||
"list1": "To set a list for the task to appear in, enter its name prefixed with {prefix}.",
|
"list1": "Per impostare una lista di appartenenza all'attività, inserisci il suo nome prefisso con {prefix}.",
|
||||||
"list2": "This will return an error if the list does not exist.",
|
"list2": "Ciò restituirà un errore se la lista non esiste.",
|
||||||
"dateAndTime": "Data e ora",
|
"dateAndTime": "Data e ora",
|
||||||
"date": "Any date will be used as the due date of the new task. You can use dates in any of these formats:",
|
"date": "Qualsiasi data verrà utilizzata come data di scadenza della nuova attività. È possibile utilizzare le date in uno qualsiasi di questi formati:",
|
||||||
"dateWeekday": "any weekday, will use the next date with that date",
|
"dateWeekday": "qualsiasi giorno della settimana, userà la data più vicina",
|
||||||
"dateCurrentYear": "will use the current year",
|
"dateCurrentYear": "userà l’anno corrente",
|
||||||
"dateNth": "will use the {day}th of the current month",
|
"dateNth": "userà il {day} del mese corrente",
|
||||||
"dateTime": "Combine any of the date formats with \"{time}\" (or {timePM}) to set a time.",
|
"dateTime": "Combina uno qualsiasi dei formati di data con \"{time}\" (o {timePM}) per impostare un orario.",
|
||||||
"repeats": "Repeating tasks",
|
"repeats": "Attività ricorrenti",
|
||||||
"repeatsDescription": "To set a task as repeating in an interval, simply add '{suffix}' to the task text. The amount needs to be a number and can be omitted to use just the type (see examples)."
|
"repeatsDescription": "Per impostare un'attività come ricorrente in un intervallo, basta aggiungere '{suffix}' al testo dell'attività. La quantità deve essere un numero e può essere omesso per usare solo il tipo (vedi esempi)."
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"team": {
|
"team": {
|
||||||
"title": "Teams",
|
"title": "Gruppi",
|
||||||
"noTeams": "Non fai parte di nessun gruppo.",
|
"noTeams": "Non fai parte di nessun gruppo.",
|
||||||
"create": {
|
"create": {
|
||||||
"title": "Crea un nuovo gruppo",
|
"title": "Crea un nuovo gruppo",
|
||||||
|
@ -746,23 +746,23 @@
|
||||||
"makeAdmin": "Rendi Amministratore",
|
"makeAdmin": "Rendi Amministratore",
|
||||||
"success": "Gruppo aggiornato.",
|
"success": "Gruppo aggiornato.",
|
||||||
"userAddedSuccess": "Membro del gruppo aggiunto.",
|
"userAddedSuccess": "Membro del gruppo aggiunto.",
|
||||||
"madeMember": "The team member was successfully made member.",
|
"madeMember": "Membro del gruppo reso membro.",
|
||||||
"madeAdmin": "The team member was successfully made admin.",
|
"madeAdmin": "Membro del gruppo reso amministratore.",
|
||||||
"delete": {
|
"delete": {
|
||||||
"header": "Elimina il gruppo",
|
"header": "Elimina il gruppo",
|
||||||
"text1": "Sei sicuro di voler eliminare questo gruppo e tutti i suoi membri?",
|
"text1": "Sei sicuro di voler eliminare questo gruppo e tutti i suoi membri?",
|
||||||
"text2": "All team members will lose access to lists and namespaces shared with this team. This CANNOT BE UNDONE!",
|
"text2": "Tutti i membri del gruppo perderanno l'accesso alle liste e ai namespace condivisi con questo gruppo. NON PUÒ ESSERE RIPRISTINATO!",
|
||||||
"success": "Gruppo eliminato."
|
"success": "Gruppo eliminato."
|
||||||
},
|
},
|
||||||
"deleteUser": {
|
"deleteUser": {
|
||||||
"header": "Rimuovi un utente dal gruppo",
|
"header": "Rimuovi un utente dal gruppo",
|
||||||
"text1": "Confermi di voler rimuovere questo utente dal gruppo?",
|
"text1": "Confermi di voler rimuovere questo utente dal gruppo?",
|
||||||
"text2": "They will lose access to all lists and namespaces this team has access to. This CANNOT BE UNDONE!",
|
"text2": "Perderanno l'accesso a tutte le liste e i namespace a cui questo gruppo ha accesso. NON PUÒ ESSERE RIPRISTINATO!",
|
||||||
"success": "Utente rimosso dal gruppo."
|
"success": "Utente rimosso dal gruppo."
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"attributes": {
|
"attributes": {
|
||||||
"name": "Team Name",
|
"name": "Nome Gruppo",
|
||||||
"namePlaceholder": "Il nome del gruppo va qui…",
|
"namePlaceholder": "Il nome del gruppo va qui…",
|
||||||
"nameRequired": "Specifica un nome.",
|
"nameRequired": "Specifica un nome.",
|
||||||
"description": "Descrizione",
|
"description": "Descrizione",
|
||||||
|
@ -772,32 +772,32 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"keyboardShortcuts": {
|
"keyboardShortcuts": {
|
||||||
"title": "Keyboard Shortcuts",
|
"title": "Tasti Rapidi",
|
||||||
"general": "General",
|
"general": "Generali",
|
||||||
"allPages": "Queste scorciatoie funzionano in tutte le pagine.",
|
"allPages": "Queste scorciatoie funzionano in tutte le pagine.",
|
||||||
"currentPageOnly": "Queste scorciatoie funzionano solo nella pagina attuale.",
|
"currentPageOnly": "Queste scorciatoie funzionano solo nella pagina attuale.",
|
||||||
"toggleMenu": "Attiva/Disattiva Menu",
|
"toggleMenu": "Attiva/Disattiva Menu",
|
||||||
"quickSearch": "Apri la barra di ricerca/azione rapida",
|
"quickSearch": "Apri la barra di ricerca/azione rapida",
|
||||||
"then": "then",
|
"then": "e dopo",
|
||||||
"task": {
|
"task": {
|
||||||
"title": "Task Page",
|
"title": "Pagina Attività",
|
||||||
"done": "Done",
|
"done": "Fatto",
|
||||||
"assign": "Assign to a user",
|
"assign": "Assegna a un utente",
|
||||||
"labels": "Add labels to this task",
|
"labels": "Aggiungi etichette a questa attività",
|
||||||
"dueDate": "Change the due date of this task",
|
"dueDate": "Modifica la data di scadenza di questa attività",
|
||||||
"attachment": "Add an attachment to this task",
|
"attachment": "Aggiungi un allegato a questa attività",
|
||||||
"related": "Modify related tasks of this task"
|
"related": "Modifica le attività collegate a questa"
|
||||||
},
|
},
|
||||||
"list": {
|
"list": {
|
||||||
"title": "List Views",
|
"title": "Viste Liste",
|
||||||
"switchToListView": "Switch to list view",
|
"switchToListView": "Passa alla vista Lista",
|
||||||
"switchToGanttView": "Switch to gantt view",
|
"switchToGanttView": "Passa alla vista Gantt",
|
||||||
"switchToKanbanView": "Switch to kanban view",
|
"switchToKanbanView": "Passa alla vista Kanban",
|
||||||
"switchToTableView": "Switch to table view"
|
"switchToTableView": "Passa alla vista Tabella"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"update": {
|
"update": {
|
||||||
"available": "There is an update for Vikunja available!",
|
"available": "È disponibile un aggiornamento per Vikunja!",
|
||||||
"do": "Aggiorna Adesso"
|
"do": "Aggiorna Adesso"
|
||||||
},
|
},
|
||||||
"menu": {
|
"menu": {
|
||||||
|
@ -805,136 +805,136 @@
|
||||||
"archive": "Archivia",
|
"archive": "Archivia",
|
||||||
"duplicate": "Duplica",
|
"duplicate": "Duplica",
|
||||||
"delete": "Elimina",
|
"delete": "Elimina",
|
||||||
"unarchive": "Un-Archive",
|
"unarchive": "Disarchivia",
|
||||||
"setBackground": "Set background",
|
"setBackground": "Imposta sfondo",
|
||||||
"share": "Condividi",
|
"share": "Condividi",
|
||||||
"newList": "Nuova lista"
|
"newList": "Nuova lista"
|
||||||
},
|
},
|
||||||
"apiConfig": {
|
"apiConfig": {
|
||||||
"url": "URL Vikunja",
|
"url": "URL Vikunja",
|
||||||
"urlPlaceholder": "es. http://localhost:8080",
|
"urlPlaceholder": "es. http://localhost:8080",
|
||||||
"change": "change",
|
"change": "modifica",
|
||||||
"use": "Using Vikunja installation at {0}",
|
"use": "Usa l'installazione di Vikunja a {0}",
|
||||||
"error": "Could not find or use Vikunja installation at \"{domain}\". Please try a different url.",
|
"error": "Impossibile trovare o usare l'installazione di Vikunja su \"{domain}\". Prova per favore con un altro Url.",
|
||||||
"success": "Using Vikunja installation at \"{domain}\".",
|
"success": "Utilizzando l'installazione di Vikunja su \"{domain}\".",
|
||||||
"urlRequired": "A url is required."
|
"urlRequired": "L'URL è obbligatorio."
|
||||||
},
|
},
|
||||||
"loadingError": {
|
"loadingError": {
|
||||||
"failed": "Loading failed, please {0}. If the error persists, please {1}.",
|
"failed": "Caricamento non riuscito, si prega di {0}. Se l'errore persiste, per favore {1}.",
|
||||||
"tryAgain": "try again",
|
"tryAgain": "riprova",
|
||||||
"contact": "contact us"
|
"contact": "Contattaci"
|
||||||
},
|
},
|
||||||
"notification": {
|
"notification": {
|
||||||
"title": "Notifications",
|
"title": "Notifiche",
|
||||||
"none": "You don't have any notifications. Have a nice day!",
|
"none": "Nessuna notifica. Buona giornata!",
|
||||||
"explainer": "Notifications will appear here when actions on namespaces, lists or tasks you subscribed to happen."
|
"explainer": "Le notifiche appariranno qui quando le azioni su Namespace, liste o attività a cui hai sottoscritto la sottoscrizione avvengono."
|
||||||
},
|
},
|
||||||
"quickActions": {
|
"quickActions": {
|
||||||
"commands": "Commands",
|
"commands": "Comandi",
|
||||||
"placeholder": "Type a command or search…",
|
"placeholder": "Digita un comando o cerca…",
|
||||||
"hint": "You can use {list} to limit the search to a list. Combine {list} or {label} (labels) with a search query to search for a task with these labels or on that list. Use {assignee} to only search for teams.",
|
"hint": "Puoi usare {list} per limitare la ricerca a una lista. Unisci {list} o {label} (etichette) alla ricerca per trovare un'attività con quelle etichette o in quella lista. Usa {assignee} per cercare solo i gruppi.",
|
||||||
"tasks": "Tasks",
|
"tasks": "Attivitá",
|
||||||
"lists": "Liste",
|
"lists": "Liste",
|
||||||
"teams": "Teams",
|
"teams": "Gruppi",
|
||||||
"newList": "Enter the title of the new list…",
|
"newList": "Inserisci il titolo della nuova lista…",
|
||||||
"newTask": "Enter the title of the new task…",
|
"newTask": "Inserisci il titolo della nuova attività…",
|
||||||
"newNamespace": "Enter the title of the new namespace…",
|
"newNamespace": "Inserisci il titolo del nuovo namespace…",
|
||||||
"newTeam": "Enter the name of the new team…",
|
"newTeam": "Inserisci il nome del nuovo gruppo…",
|
||||||
"createTask": "Create a task in the current list ({title})",
|
"createTask": "Crea un'attività nella lista attuale ({title})",
|
||||||
"createList": "Create a list in the current namespace ({title})",
|
"createList": "Crea una lista nel namespace attuale ({title})",
|
||||||
"cmds": {
|
"cmds": {
|
||||||
"newTask": "New task",
|
"newTask": "Nuova attività",
|
||||||
"newList": "New list",
|
"newList": "Nuova lista",
|
||||||
"newNamespace": "New namespace",
|
"newNamespace": "Nuovo Namespace",
|
||||||
"newTeam": "New team"
|
"newTeam": "Nuovo gruppo"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"date": {
|
"date": {
|
||||||
"locale": "en",
|
"locale": "it",
|
||||||
"altFormatLong": "j M Y H:i",
|
"altFormatLong": "j M Y H:i",
|
||||||
"altFormatShort": "j M Y"
|
"altFormatShort": "j M Y"
|
||||||
},
|
},
|
||||||
"error": {
|
"error": {
|
||||||
"error": "Errore",
|
"error": "Errore",
|
||||||
"success": "Success",
|
"success": "Fatto",
|
||||||
"0001": "Non ti è permesso farlo.",
|
"0001": "Non ti è permesso farlo.",
|
||||||
"1001": "A user with this username already exists.",
|
"1001": "Esiste già un utente con questo nome utente.",
|
||||||
"1002": "Un utente con questo indirizzo e-mail esiste già.",
|
"1002": "Un utente con questo indirizzo e-mail esiste già.",
|
||||||
"1004": "No username and password specified.",
|
"1004": "Nessun nome utente e password specificati.",
|
||||||
"1005": "L'utente non esiste.",
|
"1005": "L'utente non esiste.",
|
||||||
"1006": "Impossibile ottenere l'id utente.",
|
"1006": "Impossibile ottenere l'id utente.",
|
||||||
"1008": "No password reset token provided.",
|
"1008": "Nessun codice di reimpostazione password fornito.",
|
||||||
"1009": "Invalid password reset token.",
|
"1009": "Codice di reimpostazione password non valido.",
|
||||||
"1010": "Token di conferma dell'e-mail non valido.",
|
"1010": "Token di conferma dell'e-mail non valido.",
|
||||||
"1011": "Wrong username or password.",
|
"1011": "Nome utente o password errati.",
|
||||||
"1012": "Indirizzo e-mail dell'utente non confermato.",
|
"1012": "Indirizzo e-mail dell'utente non confermato.",
|
||||||
"1013": "La nuova password è vuota.",
|
"1013": "La nuova password è vuota.",
|
||||||
"1014": "La vecchia password è vuota.",
|
"1014": "La vecchia password è vuota.",
|
||||||
"1015": "Autenticazione TOTP già abilitata per questo utente.",
|
"1015": "Autenticazione TOTP già abilitata per questo utente.",
|
||||||
"1016": "Autenticazione TOTP non abilitata per questo utente.",
|
"1016": "Autenticazione TOTP non abilitata per questo utente.",
|
||||||
"1017": "Codice TOTP non valido.",
|
"1017": "Codice TOTP non valido.",
|
||||||
"1018": "The user avatar type setting is invalid.",
|
"1018": "L'impostazione del tipo di avatar utente non è valida.",
|
||||||
"2001": "L'ID non può essere vuoto o 0.",
|
"2001": "L'ID non può essere vuoto o 0.",
|
||||||
"2002": "Alcuni dati della richiesta non erano validi.",
|
"2002": "Alcuni dati della richiesta non erano validi.",
|
||||||
"3001": "La lista non esiste.",
|
"3001": "La lista non esiste.",
|
||||||
"3004": "You need to have read permissions on that list to perform that action.",
|
"3004": "Devi avere i permessi di lettura su quella lista per eseguire quell'azione.",
|
||||||
"3005": "Il titolo della lista non può essere vuoto.",
|
"3005": "Il titolo della lista non può essere vuoto.",
|
||||||
"3006": "The list share does not exist.",
|
"3006": "La condivisione della lista non esiste.",
|
||||||
"3007": "Esiste già una lista con questo identificatore.",
|
"3007": "Esiste già una lista con questo identificatore.",
|
||||||
"3008": "The list is archived and can therefore only be accessed read only. This is also true for all tasks associated with this list.",
|
"3008": "La lista è archiviata e può quindi essere consultata solo in sola lettura. Questo vale anche per tutte le attività associate a questa lista.",
|
||||||
"4001": "The list task text cannot be empty.",
|
"4001": "Il testo delle attività della lista non può essere vuoto.",
|
||||||
"4002": "The list task does not exist.",
|
"4002": "Lista di attività non esistente.",
|
||||||
"4003": "Tutte le attività di modifica in blocco devono appartenere alla stessa lista.",
|
"4003": "Tutte le attività di modifica in blocco devono appartenere alla stessa lista.",
|
||||||
"4004": "Hai bisogno di almeno un'attività quando si modificano in blocco le attività.",
|
"4004": "Hai bisogno di almeno un'attività quando si modificano in blocco le attività.",
|
||||||
"4005": "Non hai il permesso di vedere l'attività.",
|
"4005": "Non hai il permesso di vedere l'attività.",
|
||||||
"4006": "You can't set a parent task as the task itself.",
|
"4006": "Non è possibile impostare un'attività principale come l'attività stessa.",
|
||||||
"4007": "You can't create a task relation with an invalid kind of relation.",
|
"4007": "Non è possibile creare una relazione di attività con un tipo di relazione non valido.",
|
||||||
"4008": "You can't create a task relation which already exists.",
|
"4008": "Non è possibile creare una relazione di attività già esistente.",
|
||||||
"4009": "The task relation does not exist.",
|
"4009": "La relazione di attività non esiste.",
|
||||||
"4010": "Cannot relate a task with itself.",
|
"4010": "Non è possibile relazionare un'attività con se stessa.",
|
||||||
"4011": "The task attachment does not exist.",
|
"4011": "L'allegato dell'attività non esiste.",
|
||||||
"4012": "The task attachment is too large.",
|
"4012": "L'allegato dell'attività è troppo grande.",
|
||||||
"4013": "The task sort param is invalid.",
|
"4013": "Il parametro di ordinamento dei task non è valido.",
|
||||||
"4014": "The task sort order is invalid.",
|
"4014": "L' ordinamento dei task non è valido.",
|
||||||
"4015": "The task comment does not exist.",
|
"4015": "Il commento all'attività non esiste.",
|
||||||
"4016": "Invalid task field.",
|
"4016": "Campo attività non valido.",
|
||||||
"4017": "Invalid task filter comparator.",
|
"4017": "Comparatore di filtri attività non valido.",
|
||||||
"4018": "Invalid task filter concatenator.",
|
"4018": "Concatenatore filtro attività non valido.",
|
||||||
"4019": "Invalid task filter value.",
|
"4019": "Filtro attività non valido.",
|
||||||
"5001": "The namespace does not exist.",
|
"5001": "Il namespace non esiste.",
|
||||||
"5003": "You do not have access to the specified namespace.",
|
"5003": "Non hai accesso a questo namespace.",
|
||||||
"5006": "The namespace name cannot be empty.",
|
"5006": "Il nome del namespace non può essere vuoto.",
|
||||||
"5009": "You need to have namespace read access to perform that action.",
|
"5009": "Devi avere accesso in lettura al namespace per effettuare questa operazione.",
|
||||||
"5010": "This team does not have access to that namespace.",
|
"5010": "Il tuo gruppo non ha accesso a questo namespace.",
|
||||||
"5011": "This user has already access to that namespace.",
|
"5011": "Questo utente ha già accesso a quel namespace.",
|
||||||
"5012": "The namespace is archived and can therefore only be accessed read only.",
|
"5012": "Il namespace è archiviato e può quindi essere accessibile solo in sola lettura.",
|
||||||
"6001": "The team name cannot be empty.",
|
"6001": "Il nome del gruppo non può essere vuoto.",
|
||||||
"6002": "The team does not exist.",
|
"6002": "Gruppo non esistente.",
|
||||||
"6004": "The team already has access to that namespace or list.",
|
"6004": "Il team ha già accesso a questo namespace o lista.",
|
||||||
"6005": "The user is already a member of that team.",
|
"6005": "L'utente è già membro di quel gruppo.",
|
||||||
"6006": "Cannot delete the last team member.",
|
"6006": "Non è possibile eliminare l'ultimo membro del gruppo.",
|
||||||
"6007": "The team does not have access to the list to perform that action.",
|
"6007": "Il gruppo non ha accesso alla lista per eseguire quell'azione.",
|
||||||
"7002": "The user already has access to that list.",
|
"7002": "L'utente ha già accesso a quella lista.",
|
||||||
"7003": "Non hai accesso a quella lista.",
|
"7003": "Non hai accesso a quella lista.",
|
||||||
"8001": "Questa etichetta esiste già in quell'attività.",
|
"8001": "Questa etichetta esiste già in quell'attività.",
|
||||||
"8002": "L'etichetta non esiste.",
|
"8002": "L'etichetta non esiste.",
|
||||||
"8003": "Non hai accesso a questa etichetta.",
|
"8003": "Non hai accesso a questa etichetta.",
|
||||||
"9001": "The right is invalid.",
|
"9001": "Permesso non valido.",
|
||||||
"10001": "The bucket does not exist.",
|
"10001": "Colonna non esistente.",
|
||||||
"10002": "The bucket does not belong to that list.",
|
"10002": "La colonna non appartiene a quella lista.",
|
||||||
"10003": "You cannot remove the last bucket on a list.",
|
"10003": "Non puoi rimuovere l'ultima colonna di una lista.",
|
||||||
"10004": "You cannot add the task to this bucket as it already exceeded the limit of tasks it can hold.",
|
"10004": "Non puoi aggiungere l'attività a questa colonna perché ha già superato il limite di attività che può contenere.",
|
||||||
"10005": "There can be only one done bucket per list.",
|
"10005": "Ci può essere solo una colonna completati per lista.",
|
||||||
"11001": "The saved filter does not exist.",
|
"11001": "Filtro salvato non esistente.",
|
||||||
"11002": "Saved filters are not available for link shares.",
|
"11002": "I filtri salvati non sono disponibili per i link di condivisione.",
|
||||||
"12001": "The subscription entity type is invalid.",
|
"12001": "Il tipo di entità sottoscritto non è valido.",
|
||||||
"12002": "You are already subscribed to the entity itself or a parent entity.",
|
"12002": "Sei già iscritto all'entità stessa o a un'entità principale.",
|
||||||
"13001": "This link share requires a password for authentication, but none was provided.",
|
"13001": "Questa condivisione di link richiede una password per l'autenticazione, ma non è stato inserita.",
|
||||||
"13002": "The provided link share password was invalid."
|
"13002": "La password inserita per il link di condivisione è valida."
|
||||||
},
|
},
|
||||||
"about": {
|
"about": {
|
||||||
"title": "About",
|
"title": "Informazioni",
|
||||||
"frontendVersion": "Frontend Version: {version}",
|
"frontendVersion": "Versione Frontend: {version}",
|
||||||
"apiVersion": "API Version: {version}"
|
"apiVersion": "Versione API: {version}"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import {describe, it, expect} from 'vitest'
|
import {beforeEach, afterEach, describe, it, expect, vi} from 'vitest'
|
||||||
|
|
||||||
import {parseTaskText} from './parseTaskText'
|
import {parseTaskText} from './parseTaskText'
|
||||||
import {getDateFromText, getDateFromTextIn} from '../helpers/time/parseDate'
|
import {getDateFromText, getDateFromTextIn} from '../helpers/time/parseDate'
|
||||||
|
@ -6,6 +6,14 @@ import {calculateDayInterval} from '../helpers/time/calculateDayInterval'
|
||||||
import priorities from '../models/constants/priorities.json'
|
import priorities from '../models/constants/priorities.json'
|
||||||
|
|
||||||
describe('Parse Task Text', () => {
|
describe('Parse Task Text', () => {
|
||||||
|
beforeEach(() => {
|
||||||
|
vi.useFakeTimers()
|
||||||
|
})
|
||||||
|
|
||||||
|
afterEach(() => {
|
||||||
|
vi.useRealTimers()
|
||||||
|
})
|
||||||
|
|
||||||
it('should return text with no intents as is', () => {
|
it('should return text with no intents as is', () => {
|
||||||
expect(parseTaskText('Lorem Ipsum').text).toBe('Lorem Ipsum')
|
expect(parseTaskText('Lorem Ipsum').text).toBe('Lorem Ipsum')
|
||||||
})
|
})
|
||||||
|
@ -211,17 +219,36 @@ describe('Parse Task Text', () => {
|
||||||
expect(`${result.date.getHours()}:${result.date.getMinutes()}`).toBe('14:0')
|
expect(`${result.date.getHours()}:${result.date.getMinutes()}`).toBe('14:0')
|
||||||
})
|
})
|
||||||
it('should recognize dates of the month in the past but next month', () => {
|
it('should recognize dates of the month in the past but next month', () => {
|
||||||
const date = new Date()
|
const time = new Date(2022, 0, 15)
|
||||||
date.setDate(date.getDate() - 1)
|
vi.setSystemTime(time)
|
||||||
const result = parseTaskText(`Lorem Ipsum ${date.getDate()}nd`)
|
|
||||||
|
const result = parseTaskText(`Lorem Ipsum ${time.getDate() - 1}th`)
|
||||||
|
|
||||||
expect(result.text).toBe('Lorem Ipsum')
|
expect(result.text).toBe('Lorem Ipsum')
|
||||||
expect(result.date.getDate()).toBe(date.getDate())
|
expect(result.date.getDate()).toBe(time.getDate() - 1)
|
||||||
|
expect(result.date.getMonth()).toBe(time.getMonth() + 1)
|
||||||
|
})
|
||||||
|
it('should recognize dates of the month in the past but next month when february is the next month', () => {
|
||||||
|
const jan = new Date(2022, 0, 30)
|
||||||
|
vi.setSystemTime(jan)
|
||||||
|
|
||||||
const nextMonthWithDate = result.date.getDate() === 31
|
const result = parseTaskText(`Lorem Ipsum ${jan.getDate() - 1}th`)
|
||||||
? (date.getMonth() + 2) % 12
|
|
||||||
: (date.getMonth() + 1) % 12
|
const expectedDate = new Date(2022, 2, jan.getDate() - 1)
|
||||||
expect(result.date.getMonth()).toBe(nextMonthWithDate)
|
expect(result.text).toBe('Lorem Ipsum')
|
||||||
|
expect(result.date.getDate()).toBe(expectedDate.getDate())
|
||||||
|
expect(result.date.getMonth()).toBe(expectedDate.getMonth())
|
||||||
|
})
|
||||||
|
it('should recognize dates of the month in the past but next month when the next month has less days than this one', () => {
|
||||||
|
const mar = new Date(2022, 2, 32)
|
||||||
|
vi.setSystemTime(mar)
|
||||||
|
|
||||||
|
const result = parseTaskText(`Lorem Ipsum 31st`)
|
||||||
|
|
||||||
|
const expectedDate = new Date(2022, 4, 31)
|
||||||
|
expect(result.text).toBe('Lorem Ipsum')
|
||||||
|
expect(result.date.getDate()).toBe(expectedDate.getDate())
|
||||||
|
expect(result.date.getMonth()).toBe(expectedDate.getMonth())
|
||||||
})
|
})
|
||||||
it('should recognize dates of the month in the future', () => {
|
it('should recognize dates of the month in the future', () => {
|
||||||
const nextDay = new Date(+new Date() + 60 * 60 * 24 * 1000)
|
const nextDay = new Date(+new Date() + 60 * 60 * 24 * 1000)
|
||||||
|
@ -242,6 +269,12 @@ describe('Parse Task Text', () => {
|
||||||
expect(result.text).toBe('Lorem Ipsum github')
|
expect(result.text).toBe('Lorem Ipsum github')
|
||||||
expect(result.date).toBeNull()
|
expect(result.date).toBeNull()
|
||||||
})
|
})
|
||||||
|
it('should not recognize date number with no spacing around them', () => {
|
||||||
|
const result = parseTaskText('Lorem Ispum v1.1.1')
|
||||||
|
|
||||||
|
expect(result.text).toBe('Lorem Ispum v1.1.1')
|
||||||
|
expect(result.date).toBeNull()
|
||||||
|
})
|
||||||
|
|
||||||
describe('Parse weekdays', () => {
|
describe('Parse weekdays', () => {
|
||||||
|
|
||||||
|
|
|
@ -23,8 +23,6 @@ export default {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: direct manipulation of the prop
|
|
||||||
// might not be a problem since this is happening in the mutation
|
|
||||||
if (!namespace.lists || namespace.lists.length === 0) {
|
if (!namespace.lists || namespace.lists.length === 0) {
|
||||||
namespace.lists = state.namespaces[namespaceIndex].lists
|
namespace.lists = state.namespaces[namespaceIndex].lists
|
||||||
}
|
}
|
||||||
|
@ -136,8 +134,8 @@ export default {
|
||||||
},
|
},
|
||||||
|
|
||||||
loadNamespacesIfFavoritesDontExist(ctx) {
|
loadNamespacesIfFavoritesDontExist(ctx) {
|
||||||
// The first namespace should be the one holding all favorites
|
// The first or second namespace should be the one holding all favorites
|
||||||
if (ctx.state.namespaces[0].id !== -2) {
|
if (ctx.state.namespaces[0].id !== -2 && ctx.state.namespaces[1]?.id !== -2) {
|
||||||
return ctx.dispatch('loadNamespaces')
|
return ctx.dispatch('loadNamespaces')
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
4
src/types/faker.d.ts
vendored
Normal file
4
src/types/faker.d.ts
vendored
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
declare module '@faker-js/faker' {
|
||||||
|
import faker from 'faker'
|
||||||
|
export default faker
|
||||||
|
}
|
|
@ -6,7 +6,9 @@
|
||||||
<template #header><span>{{ title }}</span></template>
|
<template #header><span>{{ title }}</span></template>
|
||||||
|
|
||||||
<template #text>
|
<template #text>
|
||||||
<p>{{ list.isArchived ? $t('namespace.archive.unarchiveText') : $t('namespace.archive.archiveText') }}</p>
|
<p>
|
||||||
|
{{ namespace.isArchived ? $t('namespace.archive.unarchiveText') : $t('namespace.archive.archiveText')}}
|
||||||
|
</p>
|
||||||
</template>
|
</template>
|
||||||
</modal>
|
</modal>
|
||||||
</template>
|
</template>
|
||||||
|
@ -27,17 +29,18 @@ export default {
|
||||||
created() {
|
created() {
|
||||||
this.namespace = this.$store.getters['namespaces/getNamespaceById'](this.$route.params.id)
|
this.namespace = this.$store.getters['namespaces/getNamespaceById'](this.$route.params.id)
|
||||||
this.title = this.namespace.isArchived ?
|
this.title = this.namespace.isArchived ?
|
||||||
this.$t('namespace.archive.titleUnarchive', { namespace: this.namespace.title }) :
|
this.$t('namespace.archive.titleUnarchive', {namespace: this.namespace.title}) :
|
||||||
this.$t('namespace.archive.titleArchive', { namespace: this.namespace.title })
|
this.$t('namespace.archive.titleArchive', {namespace: this.namespace.title})
|
||||||
this.setTitle(this.title)
|
this.setTitle(this.title)
|
||||||
},
|
},
|
||||||
|
|
||||||
methods: {
|
methods: {
|
||||||
async archiveNamespace() {
|
async archiveNamespace() {
|
||||||
this.namespace.isArchived = !this.namespace.isArchived
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const namespace = await this.namespaceService.update(this.namespace)
|
const namespace = await this.namespaceService.update({
|
||||||
|
...this.namespace,
|
||||||
|
isArchived: !this.namespace.isArchived,
|
||||||
|
})
|
||||||
this.$store.commit('namespaces/setNamespaceById', namespace)
|
this.$store.commit('namespaces/setNamespaceById', namespace)
|
||||||
this.$message.success({message: this.$t('namespace.archive.success')})
|
this.$message.success({message: this.$t('namespace.archive.success')})
|
||||||
} finally {
|
} finally {
|
||||||
|
|
Loading…
Reference in a new issue