Merge branch 'main' into feature/ganttastic
# Conflicts: # pnpm-lock.yaml
This commit is contained in:
commit
a1e280e47b
15 changed files with 364 additions and 312 deletions
18
.drone.yml
18
.drone.yml
|
@ -46,7 +46,7 @@ steps:
|
||||||
PNPM_CACHE_FOLDER: .cache/pnpm
|
PNPM_CACHE_FOLDER: .cache/pnpm
|
||||||
CYPRESS_CACHE_FOLDER: .cache/cypress
|
CYPRESS_CACHE_FOLDER: .cache/cypress
|
||||||
commands:
|
commands:
|
||||||
- corepack enable && corepack prepare pnpm@7.9.3 --activate && pnpm config set store-dir .cache/pnpm
|
- corepack enable && pnpm config set store-dir .cache/pnpm
|
||||||
- pnpm install --fetch-timeout 100000
|
- pnpm install --fetch-timeout 100000
|
||||||
# depends_on:
|
# depends_on:
|
||||||
# - restore-cache
|
# - restore-cache
|
||||||
|
@ -57,7 +57,7 @@ steps:
|
||||||
environment:
|
environment:
|
||||||
PNPM_CACHE_FOLDER: .cache/pnpm
|
PNPM_CACHE_FOLDER: .cache/pnpm
|
||||||
commands:
|
commands:
|
||||||
- corepack enable && corepack prepare pnpm@7.9.3 --activate && pnpm config set store-dir .cache/pnpm
|
- corepack enable && pnpm config set store-dir .cache/pnpm
|
||||||
- pnpm run lint
|
- pnpm run lint
|
||||||
depends_on:
|
depends_on:
|
||||||
- dependencies
|
- dependencies
|
||||||
|
@ -68,7 +68,7 @@ steps:
|
||||||
environment:
|
environment:
|
||||||
PNPM_CACHE_FOLDER: .cache/pnpm
|
PNPM_CACHE_FOLDER: .cache/pnpm
|
||||||
commands:
|
commands:
|
||||||
- corepack enable && corepack prepare pnpm@7.9.3 --activate && pnpm config set store-dir .cache/pnpm
|
- corepack enable && pnpm config set store-dir .cache/pnpm
|
||||||
- pnpm run build
|
- pnpm run build
|
||||||
depends_on:
|
depends_on:
|
||||||
- dependencies
|
- dependencies
|
||||||
|
@ -77,7 +77,7 @@ steps:
|
||||||
image: node:18-alpine
|
image: node:18-alpine
|
||||||
pull: true
|
pull: true
|
||||||
commands:
|
commands:
|
||||||
- corepack enable && corepack prepare pnpm@7.9.3 --activate && pnpm config set store-dir .cache/pnpm
|
- corepack enable && pnpm config set store-dir .cache/pnpm
|
||||||
- pnpm run test:unit
|
- pnpm run test:unit
|
||||||
depends_on:
|
depends_on:
|
||||||
- dependencies
|
- dependencies
|
||||||
|
@ -89,7 +89,7 @@ steps:
|
||||||
environment:
|
environment:
|
||||||
PNPM_CACHE_FOLDER: .cache/pnpm
|
PNPM_CACHE_FOLDER: .cache/pnpm
|
||||||
commands:
|
commands:
|
||||||
- corepack enable && corepack prepare pnpm@7.9.3 --activate && pnpm config set store-dir .cache/pnpm
|
- corepack enable && pnpm config set store-dir .cache/pnpm
|
||||||
- pnpm run typecheck
|
- pnpm run typecheck
|
||||||
depends_on:
|
depends_on:
|
||||||
- dependencies
|
- dependencies
|
||||||
|
@ -107,7 +107,7 @@ steps:
|
||||||
from_secret: cypress_project_key
|
from_secret: cypress_project_key
|
||||||
commands:
|
commands:
|
||||||
- sed -i 's/localhost/api/g' dist/index.html
|
- sed -i 's/localhost/api/g' dist/index.html
|
||||||
- corepack enable && corepack prepare pnpm@7.9.3 --activate && pnpm config set store-dir .cache/pnpm
|
- corepack enable && pnpm config set store-dir .cache/pnpm
|
||||||
- pnpm cypress install
|
- pnpm cypress install
|
||||||
- pnpm run serve:dist & npx wait-on http://localhost:4173
|
- pnpm run serve:dist & npx wait-on http://localhost:4173
|
||||||
- pnpm run test:frontend --browser chrome --record
|
- pnpm run test:frontend --browser chrome --record
|
||||||
|
@ -202,7 +202,7 @@ steps:
|
||||||
environment:
|
environment:
|
||||||
PNPM_CACHE_FOLDER: .cache/pnpm
|
PNPM_CACHE_FOLDER: .cache/pnpm
|
||||||
commands:
|
commands:
|
||||||
- corepack enable && corepack prepare pnpm@7.9.3 --activate && pnpm config set store-dir .cache/.pnp
|
- corepack enable && pnpm config set store-dir .cache/.pnp
|
||||||
- pnpm install --fetch-timeout 100000
|
- pnpm install --fetch-timeout 100000
|
||||||
- pnpm run lint
|
- pnpm run lint
|
||||||
- "echo '{\"VERSION\": \"'$(git describe --tags --always --abbrev=10 | sed 's/-/+/' | sed 's/^v//' | sed 's/-g/-/')'\"}' > src/version.json"
|
- "echo '{\"VERSION\": \"'$(git describe --tags --always --abbrev=10 | sed 's/-/+/' | sed 's/^v//' | sed 's/-g/-/')'\"}' > src/version.json"
|
||||||
|
@ -278,7 +278,7 @@ steps:
|
||||||
environment:
|
environment:
|
||||||
PNPM_CACHE_FOLDER: .cache/pnpm
|
PNPM_CACHE_FOLDER: .cache/pnpm
|
||||||
commands:
|
commands:
|
||||||
- corepack enable && corepack prepare pnpm@7.9.3 --activate && pnpm config set store-dir .cache/pnpm
|
- corepack enable && pnpm config set store-dir .cache/pnpm
|
||||||
- pnpm install --fetch-timeout 100000
|
- pnpm install --fetch-timeout 100000
|
||||||
- pnpm run lint
|
- pnpm run lint
|
||||||
- "echo '{\"VERSION\": \"'$(git describe --tags --always --abbrev=10 | sed 's/-/+/' | sed 's/^v//' | sed 's/-g/-/')'\"}' > src/version.json"
|
- "echo '{\"VERSION\": \"'$(git describe --tags --always --abbrev=10 | sed 's/-/+/' | sed 's/^v//' | sed 's/-g/-/')'\"}' > src/version.json"
|
||||||
|
@ -659,6 +659,6 @@ steps:
|
||||||
from_secret: crowdin_key
|
from_secret: crowdin_key
|
||||||
---
|
---
|
||||||
kind: signature
|
kind: signature
|
||||||
hmac: 9eccb4a9999236be0f772c4cbe7ccce2875faa57f32de179bd75cf0df4124d00
|
hmac: c885a0e50db729842402494aa645dd3ac662828b691108550f6bf302158295ba
|
||||||
|
|
||||||
...
|
...
|
||||||
|
|
|
@ -21,16 +21,17 @@ COPY pnpm-lock.yaml ./
|
||||||
RUN \
|
RUN \
|
||||||
# https://pnpm.io/installation#using-corepack
|
# https://pnpm.io/installation#using-corepack
|
||||||
corepack enable && \
|
corepack enable && \
|
||||||
corepack prepare pnpm@7.9.3 --activate && \
|
# we don't use corepack prepare here by intend since
|
||||||
|
# we have renovate to keep our dependencies up to date
|
||||||
# Build the frontend
|
# Build the frontend
|
||||||
pnpm fetch
|
pnpm fetch --prod
|
||||||
|
|
||||||
ADD . ./
|
ADD . ./
|
||||||
|
|
||||||
RUN apk add --no-cache git
|
RUN apk add --no-cache git
|
||||||
|
|
||||||
RUN \
|
RUN \
|
||||||
pnpm install --offline && \
|
pnpm install -r --offline --prod && \
|
||||||
echo '{"VERSION": "'$(git describe --tags --always --abbrev=10 | sed 's/-/+/' | sed 's/^v//' | sed 's/-g/-/')'"}' > src/version.json && \
|
echo '{"VERSION": "'$(git describe --tags --always --abbrev=10 | sed 's/-/+/' | sed 's/^v//' | sed 's/-g/-/')'"}' > src/version.json && \
|
||||||
pnpm run build
|
pnpm run build
|
||||||
|
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<title>Vikunja</title>
|
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
||||||
<meta name="viewport" content="width=device-width,initial-scale=1.0">
|
<meta name="viewport" content="width=device-width,initial-scale=1.0">
|
||||||
|
<title>Vikunja</title>
|
||||||
<meta name="description" content="Vikunja (/vɪˈkuːnjə/) - The to-do app to organize your life.">
|
<meta name="description" content="Vikunja (/vɪˈkuːnjə/) - The to-do app to organize your life.">
|
||||||
<meta name="theme-color" content="#1973ff"/>
|
<meta name="theme-color" content="#1973ff"/>
|
||||||
|
|
||||||
|
|
15
package.json
15
package.json
|
@ -25,15 +25,15 @@
|
||||||
"@github/hotkey": "2.0.1",
|
"@github/hotkey": "2.0.1",
|
||||||
"@infectoone/vue-ganttastic": "^2.0.4",
|
"@infectoone/vue-ganttastic": "^2.0.4",
|
||||||
"@kyvg/vue3-notification": "2.4.1",
|
"@kyvg/vue3-notification": "2.4.1",
|
||||||
"@sentry/tracing": "7.13.0",
|
"@sentry/tracing": "7.14.0",
|
||||||
"@sentry/vue": "7.13.0",
|
"@sentry/vue": "7.14.0",
|
||||||
"@types/is-touch-device": "1.0.0",
|
"@types/is-touch-device": "1.0.0",
|
||||||
"@types/lodash.clonedeep": "4.5.7",
|
"@types/lodash.clonedeep": "4.5.7",
|
||||||
"@types/sortablejs": "1.15.0",
|
"@types/sortablejs": "1.15.0",
|
||||||
"@vueuse/core": "9.3.0",
|
"@vueuse/core": "9.3.0",
|
||||||
"@vueuse/router": "9.3.0",
|
"@vueuse/router": "9.3.0",
|
||||||
"axios": "0.27.2",
|
"axios": "0.27.2",
|
||||||
"blurhash": "2.0.1",
|
"blurhash": "2.0.2",
|
||||||
"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.9",
|
"codemirror": "5.65.9",
|
||||||
|
@ -54,7 +54,7 @@
|
||||||
"sortablejs": "1.15.0",
|
"sortablejs": "1.15.0",
|
||||||
"ufo": "0.8.5",
|
"ufo": "0.8.5",
|
||||||
"v-tooltip": "4.0.0-beta.17",
|
"v-tooltip": "4.0.0-beta.17",
|
||||||
"vue": "3.2.39",
|
"vue": "3.2.40",
|
||||||
"vue-advanced-cropper": "2.8.3",
|
"vue-advanced-cropper": "2.8.3",
|
||||||
"vue-flatpickr-component": "9.0.6",
|
"vue-flatpickr-component": "9.0.6",
|
||||||
"vue-i18n": "9.2.2",
|
"vue-i18n": "9.2.2",
|
||||||
|
@ -70,6 +70,7 @@
|
||||||
"@faker-js/faker": "7.5.0",
|
"@faker-js/faker": "7.5.0",
|
||||||
"@types/dompurify": "2.3.4",
|
"@types/dompurify": "2.3.4",
|
||||||
"@types/flexsearch": "0.7.3",
|
"@types/flexsearch": "0.7.3",
|
||||||
|
"@types/node": "16.11.62",
|
||||||
"@typescript-eslint/eslint-plugin": "5.38.1",
|
"@typescript-eslint/eslint-plugin": "5.38.1",
|
||||||
"@typescript-eslint/parser": "5.38.1",
|
"@typescript-eslint/parser": "5.38.1",
|
||||||
"@vitejs/plugin-legacy": "2.2.0",
|
"@vitejs/plugin-legacy": "2.2.0",
|
||||||
|
@ -80,7 +81,7 @@
|
||||||
"autoprefixer": "10.4.12",
|
"autoprefixer": "10.4.12",
|
||||||
"browserslist": "4.21.4",
|
"browserslist": "4.21.4",
|
||||||
"caniuse-lite": "1.0.30001412",
|
"caniuse-lite": "1.0.30001412",
|
||||||
"cypress": "10.8.0",
|
"cypress": "10.9.0",
|
||||||
"esbuild": "0.15.9",
|
"esbuild": "0.15.9",
|
||||||
"eslint": "8.24.0",
|
"eslint": "8.24.0",
|
||||||
"eslint-plugin-vue": "9.5.1",
|
"eslint-plugin-vue": "9.5.1",
|
||||||
|
@ -92,8 +93,8 @@
|
||||||
"rollup": "2.79.1",
|
"rollup": "2.79.1",
|
||||||
"rollup-plugin-visualizer": "5.8.2",
|
"rollup-plugin-visualizer": "5.8.2",
|
||||||
"sass": "1.55.0",
|
"sass": "1.55.0",
|
||||||
"typescript": "4.8.3",
|
"typescript": "4.8.4",
|
||||||
"vite": "3.1.3",
|
"vite": "3.1.4",
|
||||||
"vite-plugin-pwa": "0.13.1",
|
"vite-plugin-pwa": "0.13.1",
|
||||||
"vite-svg-loader": "3.6.0",
|
"vite-svg-loader": "3.6.0",
|
||||||
"vitest": "0.23.4",
|
"vitest": "0.23.4",
|
||||||
|
|
454
pnpm-lock.yaml
454
pnpm-lock.yaml
File diff suppressed because it is too large
Load diff
|
@ -6,13 +6,13 @@
|
||||||
{{ $t('input.datemathHelp.intro') }}
|
{{ $t('input.datemathHelp.intro') }}
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
<i18n-t keypath="input.datemathHelp.expression">
|
<i18n-t keypath="input.datemathHelp.expression" scope="global">
|
||||||
<code>now</code>
|
<code>now</code>
|
||||||
<code>||</code>
|
<code>||</code>
|
||||||
</i18n-t>
|
</i18n-t>
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
<i18n-t keypath="input.datemathHelp.similar">
|
<i18n-t keypath="input.datemathHelp.similar" scope="global">
|
||||||
<BaseButton
|
<BaseButton
|
||||||
href="https://grafana.com/docs/grafana/latest/dashboards/time-range-controls/"
|
href="https://grafana.com/docs/grafana/latest/dashboards/time-range-controls/"
|
||||||
target="_blank">
|
target="_blank">
|
||||||
|
@ -99,7 +99,7 @@
|
||||||
<tr>
|
<tr>
|
||||||
<td><code>{{ exampleDate }}||+1M/d</code></td>
|
<td><code>{{ exampleDate }}||+1M/d</code></td>
|
||||||
<td>
|
<td>
|
||||||
<i18n-t keypath="input.datemathHelp.examples.datePlusMonth">
|
<i18n-t keypath="input.datemathHelp.examples.datePlusMonth" scope="global">
|
||||||
<code>{{ exampleDate }}</code>
|
<code>{{ exampleDate }}</code>
|
||||||
</i18n-t>
|
</i18n-t>
|
||||||
</td>
|
</td>
|
||||||
|
|
|
@ -23,7 +23,7 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="api-url-info" v-else>
|
<div class="api-url-info" v-else>
|
||||||
<i18n-t keypath="apiConfig.use">
|
<i18n-t keypath="apiConfig.use" scope="global">
|
||||||
<span class="url" v-tooltip="apiUrl"> {{ apiDomain }} </span>
|
<span class="url" v-tooltip="apiUrl"> {{ apiDomain }} </span>
|
||||||
</i18n-t>
|
</i18n-t>
|
||||||
<br/>
|
<br/>
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<template>
|
<template>
|
||||||
<message variant="danger">
|
<message variant="danger">
|
||||||
<i18n-t keypath="loadingError.failed">
|
<i18n-t keypath="loadingError.failed" scope="global">
|
||||||
<ButtonLink @click="reload">{{ $t('loadingError.tryAgain') }}</ButtonLink>
|
<ButtonLink @click="reload">{{ $t('loadingError.tryAgain') }}</ButtonLink>
|
||||||
<ButtonLink href="https://vikunja.io/contact/">{{ $t('loadingError.contact') }}</ButtonLink>
|
<ButtonLink href="https://vikunja.io/contact/">{{ $t('loadingError.contact') }}</ButtonLink>
|
||||||
</i18n-t>
|
</i18n-t>
|
||||||
|
|
|
@ -92,7 +92,7 @@
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
<p class="mb-2">
|
<p class="mb-2">
|
||||||
<i18n-t keypath="list.share.links.sharedBy">
|
<i18n-t keypath="list.share.links.sharedBy" scope="global">
|
||||||
<strong>{{ s.sharedBy.getDisplayName() }}</strong>
|
<strong>{{ s.sharedBy.getDisplayName() }}</strong>
|
||||||
</i18n-t>
|
</i18n-t>
|
||||||
</p>
|
</p>
|
||||||
|
|
|
@ -38,7 +38,7 @@
|
||||||
<div class="filename">{{ a.file.name }}</div>
|
<div class="filename">{{ a.file.name }}</div>
|
||||||
<div class="info">
|
<div class="info">
|
||||||
<p class="attachment-info-meta">
|
<p class="attachment-info-meta">
|
||||||
<i18n-t keypath="task.attachment.createdBy">
|
<i18n-t keypath="task.attachment.createdBy" scope="global">
|
||||||
<span v-tooltip="formatDateLong(a.created)">
|
<span v-tooltip="formatDateLong(a.created)">
|
||||||
{{ formatDateSince(a.created) }}
|
{{ formatDateSince(a.created) }}
|
||||||
</span>
|
</span>
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<template>
|
<template>
|
||||||
<p class="created">
|
<p class="created">
|
||||||
<time :datetime="formatISO(task.created)" v-tooltip="formatDateLong(task.created)">
|
<time :datetime="formatISO(task.created)" v-tooltip="formatDateLong(task.created)">
|
||||||
<i18n-t keypath="task.detail.created">
|
<i18n-t keypath="task.detail.created" scope="global">
|
||||||
<span>{{ formatDateSince(task.created) }}</span>
|
<span>{{ formatDateSince(task.created) }}</span>
|
||||||
{{ task.createdBy.getDisplayName() }}
|
{{ task.createdBy.getDisplayName() }}
|
||||||
</i18n-t>
|
</i18n-t>
|
||||||
|
@ -10,7 +10,7 @@
|
||||||
<br/>
|
<br/>
|
||||||
<!-- Computed properties to show the actual date every time it gets updated -->
|
<!-- Computed properties to show the actual date every time it gets updated -->
|
||||||
<time :datetime="formatISO(task.updated)" v-tooltip="updatedFormatted">
|
<time :datetime="formatISO(task.updated)" v-tooltip="updatedFormatted">
|
||||||
<i18n-t keypath="task.detail.updated">
|
<i18n-t keypath="task.detail.updated" scope="global">
|
||||||
<span>{{ updatedSince }}</span>
|
<span>{{ updatedSince }}</span>
|
||||||
</i18n-t>
|
</i18n-t>
|
||||||
</time>
|
</time>
|
||||||
|
@ -18,7 +18,7 @@
|
||||||
<template v-if="task.done">
|
<template v-if="task.done">
|
||||||
<br/>
|
<br/>
|
||||||
<time :datetime="formatISO(task.doneAt)" v-tooltip="doneFormatted">
|
<time :datetime="formatISO(task.doneAt)" v-tooltip="doneFormatted">
|
||||||
<i18n-t keypath="task.detail.doneAt">
|
<i18n-t keypath="task.detail.doneAt" scope="global">
|
||||||
<span>{{ doneSince }}</span>
|
<span>{{ doneSince }}</span>
|
||||||
</i18n-t>
|
</i18n-t>
|
||||||
</time>
|
</time>
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
import AbstractService from './abstractService'
|
import AbstractService from './abstractService'
|
||||||
import {downloadBlob} from '../helpers/downloadBlob'
|
import {downloadBlob} from '../helpers/downloadBlob'
|
||||||
|
|
||||||
|
const DOWNLOAD_NAME = 'vikunja-export.zip'
|
||||||
|
|
||||||
export default class DataExportService extends AbstractService {
|
export default class DataExportService extends AbstractService {
|
||||||
request(password: string) {
|
request(password: string) {
|
||||||
return this.post('/user/export/request', {password})
|
return this.post('/user/export/request', {password})
|
||||||
|
@ -10,7 +12,7 @@ export default class DataExportService extends AbstractService {
|
||||||
const clear = this.setLoading()
|
const clear = this.setLoading()
|
||||||
try {
|
try {
|
||||||
const url = await this.getBlobUrl('/user/export/download', 'POST', {password})
|
const url = await this.getBlobUrl('/user/export/download', 'POST', {password})
|
||||||
downloadBlob(url, 'vikunja-export.zip')
|
downloadBlob(url, DOWNLOAD_NAME)
|
||||||
} finally {
|
} finally {
|
||||||
clear()
|
clear()
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,52 +34,43 @@
|
||||||
</create-edit>
|
</create-edit>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script setup lang="ts">
|
||||||
import {defineComponent} from 'vue'
|
import {computed, ref} from 'vue'
|
||||||
import {mapState} from 'pinia'
|
import {useI18n} from 'vue-i18n'
|
||||||
|
import {useRouter} from 'vue-router'
|
||||||
|
|
||||||
import LabelModel from '../../models/label'
|
|
||||||
import CreateEdit from '@/components/misc/create-edit.vue'
|
import CreateEdit from '@/components/misc/create-edit.vue'
|
||||||
import ColorPicker from '../../components/input/colorPicker.vue'
|
import ColorPicker from '@/components/input/colorPicker.vue'
|
||||||
import { setTitle } from '@/helpers/setTitle'
|
|
||||||
import { useLabelStore } from '@/stores/labels'
|
|
||||||
|
|
||||||
export default defineComponent({
|
import LabelModel from '@/models/label'
|
||||||
name: 'NewLabel',
|
import {useLabelStore} from '@/stores/labels'
|
||||||
data() {
|
import {useTitle} from '@/composables/useTitle'
|
||||||
return {
|
import {success} from '@/message'
|
||||||
label: new LabelModel(),
|
|
||||||
showError: false,
|
const router = useRouter()
|
||||||
}
|
|
||||||
},
|
const {t} = useI18n({useScope: 'global'})
|
||||||
components: {
|
useTitle(() => t('label.create.title'))
|
||||||
CreateEdit,
|
|
||||||
ColorPicker,
|
const labelStore = useLabelStore()
|
||||||
},
|
const label = ref(new LabelModel())
|
||||||
mounted() {
|
|
||||||
setTitle(this.$t('label.create.title'))
|
const showError = ref(false)
|
||||||
},
|
const loading = computed(() => labelStore.isLoading)
|
||||||
computed: {
|
|
||||||
...mapState(useLabelStore, {
|
async function newLabel() {
|
||||||
loading: state => state.isLoading,
|
if (label.value.title === '') {
|
||||||
}),
|
showError.value = true
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
async newLabel() {
|
|
||||||
if (this.label.title === '') {
|
|
||||||
this.showError = true
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
this.showError = false
|
showError.value = false
|
||||||
|
|
||||||
const labelStore = useLabelStore()
|
const labelStore = useLabelStore()
|
||||||
const label = labelStore.createLabel(this.label)
|
const newLabel = labelStore.createLabel(label.value)
|
||||||
this.$router.push({
|
router.push({
|
||||||
name: 'labels.index',
|
name: 'labels.index',
|
||||||
params: {id: label.id},
|
params: {id: newLabel.id},
|
||||||
})
|
})
|
||||||
this.$message.success({message: this.$t('label.create.success')})
|
success({message: t('label.create.success')})
|
||||||
},
|
}
|
||||||
},
|
|
||||||
})
|
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -10,9 +10,12 @@
|
||||||
class="control is-expanded"
|
class="control is-expanded"
|
||||||
:class="{ 'is-loading': namespaceService.loading }"
|
:class="{ 'is-loading': namespaceService.loading }"
|
||||||
>
|
>
|
||||||
|
<!-- The user should be able to close the modal by pressing escape - that already works with the default modal.
|
||||||
|
But with the input modal here since it autofocuses the input that input field catches the focus instead.
|
||||||
|
Hence we place the listener on the input field directly. -->
|
||||||
<input
|
<input
|
||||||
@keyup.enter="newNamespace()"
|
@keyup.enter="newNamespace()"
|
||||||
@keyup.esc="back()"
|
@keyup.esc="$router.back()"
|
||||||
class="input"
|
class="input"
|
||||||
:placeholder="$t('namespace.attributes.titlePlaceholder')"
|
:placeholder="$t('namespace.attributes.titlePlaceholder')"
|
||||||
type="text"
|
type="text"
|
||||||
|
@ -40,48 +43,42 @@
|
||||||
</create-edit>
|
</create-edit>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script setup lang="ts">
|
||||||
import {defineComponent} from 'vue'
|
import {ref, shallowReactive} from 'vue'
|
||||||
|
import {useI18n} from 'vue-i18n'
|
||||||
|
import {useRouter} from 'vue-router'
|
||||||
|
|
||||||
import Message from '@/components/misc/message.vue'
|
import Message from '@/components/misc/message.vue'
|
||||||
import NamespaceModel from '../../models/namespace'
|
|
||||||
import NamespaceService from '../../services/namespace'
|
|
||||||
import CreateEdit from '@/components/misc/create-edit.vue'
|
import CreateEdit from '@/components/misc/create-edit.vue'
|
||||||
import ColorPicker from '../../components/input/colorPicker.vue'
|
import ColorPicker from '@/components/input/colorPicker.vue'
|
||||||
import { setTitle } from '@/helpers/setTitle'
|
|
||||||
import {useNamespaceStore} from '@/stores/namespaces'
|
|
||||||
|
|
||||||
export default defineComponent({
|
import NamespaceModel from '@/models/namespace'
|
||||||
name: 'NewNamespace',
|
import NamespaceService from '@/services/namespace'
|
||||||
data() {
|
import {useNamespaceStore} from '@/stores/namespaces'
|
||||||
return {
|
import type {INamespace} from '@/modelTypes/INamespace'
|
||||||
showError: false,
|
|
||||||
namespace: new NamespaceModel(),
|
import {useTitle} from '@/composables/useTitle'
|
||||||
namespaceService: new NamespaceService(),
|
import {success} from '@/message'
|
||||||
}
|
|
||||||
},
|
const showError = ref(false)
|
||||||
components: {
|
const namespace = ref<INamespace>(new NamespaceModel())
|
||||||
Message,
|
const namespaceService = shallowReactive(new NamespaceService())
|
||||||
ColorPicker,
|
|
||||||
CreateEdit,
|
const {t} = useI18n({useScope: 'global'})
|
||||||
},
|
const router = useRouter()
|
||||||
mounted() {
|
|
||||||
setTitle(this.$t('namespace.create.title'))
|
useTitle(() => t('namespace.create.title'))
|
||||||
},
|
|
||||||
methods: {
|
async function newNamespace() {
|
||||||
async newNamespace() {
|
if (namespace.value.title === '') {
|
||||||
if (this.namespace.title === '') {
|
showError.value = true
|
||||||
this.showError = true
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
this.showError = false
|
showError.value = false
|
||||||
|
|
||||||
const namespace = await this.namespaceService.create(this.namespace)
|
const newNamespace = await namespaceService.create(namespace.value)
|
||||||
const namespaceStore = useNamespaceStore()
|
useNamespaceStore().addNamespace(newNamespace)
|
||||||
namespaceStore.addNamespace(namespace)
|
success({message: t('namespace.create.success')})
|
||||||
this.$message.success({message: this.$t('namespace.create.success')})
|
router.back()
|
||||||
this.$router.back()
|
}
|
||||||
},
|
|
||||||
},
|
|
||||||
})
|
|
||||||
</script>
|
</script>
|
||||||
|
|
|
@ -25,7 +25,7 @@
|
||||||
{{ isLocalUser ? $t('user.settings.caldav.tokensHowTo') : $t('user.settings.caldav.mustUseToken') }}
|
{{ isLocalUser ? $t('user.settings.caldav.tokensHowTo') : $t('user.settings.caldav.mustUseToken') }}
|
||||||
<template v-if="!isLocalUser">
|
<template v-if="!isLocalUser">
|
||||||
<br/>
|
<br/>
|
||||||
<i18n-t keypath="user.settings.caldav.usernameIs">
|
<i18n-t keypath="user.settings.caldav.usernameIs" scope="global">
|
||||||
<strong>{{ username }}</strong>
|
<strong>{{ username }}</strong>
|
||||||
</i18n-t>
|
</i18n-t>
|
||||||
</template>
|
</template>
|
||||||
|
|
Loading…
Reference in a new issue