feat: add message component #1082
|
@ -8,7 +8,7 @@ const testAndAssertFailed = fixture => {
|
|||
|
||||
cy.wait(5000) // It can take waaaayy too long to log the user in
|
||||
cy.url().should('include', '/')
|
||||
cy.get('div.notification.is-danger').contains('Wrong username or password.')
|
||||
cy.get('div.message.danger').contains('Wrong username or password.')
|
||||
}
|
||||
|
||||
context('Login', () => {
|
||||
|
|
|
@ -32,7 +32,7 @@ context('Registration', () => {
|
|||
cy.get('h2').should('contain', `Hi ${fixture.username}!`)
|
||||
})
|
||||
|
||||
it('Should fail', () => {
|
||||
it.only('Should fail', () => {
|
||||
const fixture = {
|
||||
username: 'test',
|
||||
password: '123456',
|
||||
|
@ -45,6 +45,6 @@ context('Registration', () => {
|
|||
cy.get('#password').type(fixture.password)
|
||||
cy.get('#passwordValidation').type(fixture.password)
|
||||
cy.get('#register-submit').click()
|
||||
cy.get('div.notification.is-danger').contains('A user with this username already exists.')
|
||||
cy.get('div.message.danger').contains('A user with this username already exists.')
|
||||
})
|
||||
})
|
|
@ -129,7 +129,10 @@
|
|||
"ignorePatterns": [
|
||||
"*.test.*",
|
||||
"cypress/*"
|
||||
]
|
||||
],
|
||||
"globals": {
|
||||
"defineProps": "readonly"
|
||||
}
|
||||
},
|
||||
"postcss": {
|
||||
"plugins": {
|
||||
|
|
|
@ -30,27 +30,25 @@
|
|||
<a @click="() => (configureApi = true)">{{ $t('apiConfig.change') }}</a>
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="notification is-success mt-2"
|
||||
v-if="successMsg !== '' && errorMsg === ''"
|
||||
>
|
||||
<message variant="success" v-if="successMsg !== '' && errorMsg === ''" class="mt-2">
|
||||
{{ successMsg }}
|
||||
</div>
|
||||
<div
|
||||
class="notification is-danger mt-2"
|
||||
v-if="errorMsg !== '' && successMsg === ''"
|
||||
>
|
||||
</message>
|
||||
<message variant="danger" v-if="errorMsg !== '' && successMsg === ''" class="mt-2">
|
||||
{{ errorMsg }}
|
||||
</div>
|
||||
</message>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Message from '@/components/misc/message'
|
||||
import {parseURL} from 'ufo'
|
||||
import {checkAndSetApiUrl} from '@/helpers/checkAndSetApiUrl'
|
||||
|
||||
export default {
|
||||
name: 'apiConfig',
|
||||
components: {
|
||||
Message,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
configureApi: false,
|
||||
|
|
|
@ -1,15 +1,18 @@
|
|||
<template>
|
||||
<div class="notification is-danger">
|
||||
<message variant="danger">
|
||||
<i18n-t keypath="loadingError.failed">
|
||||
<a @click="reload">{{ $t('loadingError.tryAgain') }}</a>
|
||||
<a href="https://vikunja.io/contact/" rel="noreferrer noopener nofollow" target="_blank">{{ $t('loadingError.contact') }}</a>
|
||||
</i18n-t>
|
||||
</div>
|
||||
</message>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Message from '@/components/misc/message'
|
||||
|
||||
export default {
|
||||
name: 'error',
|
||||
components: {Message},
|
||||
methods: {
|
||||
reload() {
|
||||
window.location.reload()
|
||||
|
|
|
@ -4,13 +4,11 @@
|
|||
<template v-for="(s, i) in shortcuts" :key="i">
|
||||
<h3>{{ $t(s.title) }}</h3>
|
||||
|
||||
<div class="message is-primary">
|
||||
<div class="message-body">
|
||||
{{
|
||||
s.available($route) ? $t('keyboardShortcuts.currentPageOnly') : $t('keyboardShortcuts.allPages')
|
||||
}}
|
||||
</div>
|
||||
</div>
|
||||
<message>
|
||||
{{
|
||||
s.available($route) ? $t('keyboardShortcuts.currentPageOnly') : $t('keyboardShortcuts.allPages')
|
||||
}}
|
||||
</message>
|
||||
|
||||
<dl class="shortcut-list">
|
||||
<template v-for="(sc, si) in s.shortcuts" :key="si">
|
||||
|
@ -30,11 +28,15 @@
|
|||
<script>
|
||||
import {KEYBOARD_SHORTCUTS_ACTIVE} from '@/store/mutation-types'
|
||||
import Shortcut from '@/components/misc/shortcut.vue'
|
||||
import Message from '@/components/misc/message'
|
||||
import {KEYBOARD_SHORTCUTS} from './shortcuts'
|
||||
|
||||
export default {
|
||||
name: 'keyboard-shortcuts',
|
||||
components: {Shortcut},
|
||||
components: {
|
||||
Message,
|
||||
Shortcut,
|
||||
},
|
||||
data() {
|
||||
return {
|
||||
shortcuts: KEYBOARD_SHORTCUTS,
|
||||
|
|
41
src/components/misc/message.vue
Normal file
|
@ -0,0 +1,41 @@
|
|||
<template>
|
||||
<div class="message" :class="variant">
|
||||
konrad marked this conversation as resolved
Outdated
|
||||
<slot/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
defineProps({
|
||||
variant: {
|
||||
konrad marked this conversation as resolved
Outdated
dpschen
commented
`is` as a prop is already used by vues `component` component. There it indicates the component / tag. Since the meaning of this prop name is already taken I think we should use something different here. E.g. `variant` which is used in the modal.vue.
konrad
commented
I like I like `variant` - changed it.
dpschen
commented
Disabling might be prevented by removing Disabling might be prevented by removing `const props = `.
konrad
commented
That seems to work! I thought setting the prop with That seems to work! I thought setting the prop with `const props = ...` was required for props to work.
dpschen
commented
The props [are automatically exposed via the context](https://vue-next-template-explorer.netlify.app/#%7B%22src%22%3A%22%3Ctemplate%3E%5Cn%5Ct%3Cdiv%20class%3D%5C%22message%5C%22%20%3Aclass%3D%5C%22variant%5C%22%3E%5Cn%20%20%20%20%7B%7Bbla%7D%7D%5Cn%5Ct%5Ct%3Cslot%2F%3E%5Cn%5Ct%3C%2Fdiv%3E%5Cn%3C%2Ftemplate%3E%22%2C%22options%22%3A%7B%22mode%22%3A%22module%22%2C%22filename%22%3A%22Foo.vue%22%2C%22prefixIdentifiers%22%3Afalse%2C%22hoistStatic%22%3Afalse%2C%22cacheHandlers%22%3Afalse%2C%22scopeId%22%3Anull%2C%22inline%22%3Afalse%2C%22ssrCssVars%22%3A%22%7B%20color%20%7D%22%2C%22compatConfig%22%3A%7B%22MODE%22%3A3%7D%2C%22whitespace%22%3A%22condense%22%2C%22bindingMetadata%22%3A%7B%22TestComponent%22%3A%22setup-const%22%2C%22setupRef%22%3A%22setup-ref%22%2C%22setupConst%22%3A%22setup-const%22%2C%22setupLet%22%3A%22setup-let%22%2C%22setupMaybeRef%22%3A%22setup-maybe-ref%22%2C%22setupProp%22%3A%22props%22%2C%22vMySetupDir%22%3A%22setup-const%22%7D%7D%7D)
konrad
commented
Neat, I didn't know that. Neat, I didn't know that.
dpschen
commented
I think that's a composition api only thing. AFAIK with the option api you get the props in the render function via that I think that's a composition api only thing. AFAIK with the option api you get the props in the render function via that `$props` argument.
|
||||
type: String,
|
||||
default: 'info',
|
||||
},
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.message {
|
||||
padding: .75rem 1rem;
|
||||
konrad marked this conversation as resolved
dpschen
commented
Remove margin (we don't know all contexts this component will be used in). Remove margin (we don't know all contexts this component will be used in).
konrad
commented
Done. Done.
|
||||
border-radius: $radius;
|
||||
}
|
||||
|
||||
konrad marked this conversation as resolved
Outdated
dpschen
commented
No need for the first No need for the first `&`: the default prop already solves this.
konrad
commented
Done. Done.
|
||||
.info {
|
||||
border: 1px solid var(--primary);
|
||||
background: hsla(var(--primary-hsl), .05);
|
||||
}
|
||||
|
||||
konrad marked this conversation as resolved
Outdated
dpschen
commented
Don't indent classes: adds more (not needed) specifity. Don't indent classes: adds more (not needed) specifity.
konrad
commented
Done. Done.
|
||||
.danger {
|
||||
border: 1px solid var(--danger);
|
||||
background: hsla(var(--danger-h), var(--danger-s), var(--danger-l), .05);
|
||||
}
|
||||
|
||||
.warning {
|
||||
border: 1px solid var(--warning);
|
||||
background: hsla(var(--warning-h), var(--warning-s), var(--warning-l), .05);
|
||||
}
|
||||
|
||||
.success {
|
||||
border: 1px solid var(--success);
|
||||
background: hsla(var(--success-h), var(--success-s), var(--success-l), .05);
|
||||
}
|
||||
</style>
|
|
@ -2,14 +2,9 @@
|
|||
<div class="no-auth-wrapper">
|
||||
<div class="noauth-container">
|
||||
<Logo class="logo" width="400" height="117" />
|
||||
<div class="message is-info" v-if="motd !== ''">
|
||||
<div class="message-header">
|
||||
<p>{{ $t('misc.info') }}</p>
|
||||
</div>
|
||||
<div class="message-body">
|
||||
{{ motd }}
|
||||
</div>
|
||||
</div>
|
||||
<message v-if="motd !== ''" class="my-2">
|
||||
{{ motd }}
|
||||
</message>
|
||||
<slot/>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -17,6 +12,7 @@
|
|||
|
||||
<script setup>
|
||||
import Logo from '@/components/home/Logo.vue'
|
||||
import message from '@/components/misc/message'
|
||||
import {useStore} from 'vuex'
|
||||
import {computed} from 'vue'
|
||||
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
<p v-if="error === errorNoApiUrl">
|
||||
{{ $t('ready.noApiUrlConfigured') }}
|
||||
</p>
|
||||
<div class="notification is-danger" v-else>
|
||||
<message variant="danger" v-else>
|
||||
<p>
|
||||
{{ $t('ready.errorOccured') }}<br/>
|
||||
{{ error }}
|
||||
|
@ -24,7 +24,7 @@
|
|||
<p>
|
||||
{{ $t('ready.checkApiUrl') }}
|
||||
</p>
|
||||
</div>
|
||||
</message>
|
||||
<api-config :configure-open="true" @found-api="load"/>
|
||||
</card>
|
||||
</no-auth-wrapper>
|
||||
|
@ -43,6 +43,7 @@
|
|||
<script>
|
||||
import Logo from '@/assets/logo.svg?component'
|
||||
import ApiConfig from '@/components/misc/api-config'
|
||||
import Message from '@/components/misc/message'
|
||||
import NoAuthWrapper from '@/components/misc/no-auth-wrapper'
|
||||
import {mapState} from 'vuex'
|
||||
import {ERROR_NO_API_URL} from '@/helpers/checkAndSetApiUrl'
|
||||
|
@ -50,6 +51,7 @@ import {ERROR_NO_API_URL} from '@/helpers/checkAndSetApiUrl'
|
|||
export default {
|
||||
name: 'ready',
|
||||
components: {
|
||||
Message,
|
||||
Logo,
|
||||
NoAuthWrapper,
|
||||
ApiConfig,
|
||||
|
|
|
@ -193,10 +193,6 @@ export default {
|
|||
align-items: center;
|
||||
|
||||
}
|
||||
|
||||
.message-body {
|
||||
padding: .5rem .75rem;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
@import "bulma-css-variables/sass/elements/content";
|
||||
@import "bulma-css-variables/sass/elements/icon";
|
||||
@import "bulma-css-variables/sass/elements/image";
|
||||
@import "bulma-css-variables/sass/elements/notification";
|
||||
//@import "bulma-css-variables/sass/elements/notification"; // not used
|
||||
@import "bulma-css-variables/sass/elements/progress";
|
||||
@import "bulma-css-variables/sass/elements/table";
|
||||
@import "bulma-css-variables/sass/elements/tag";
|
||||
|
@ -48,7 +48,7 @@
|
|||
// @import "bulma-css-variables/sass/components/level"; // not used
|
||||
@import "bulma-css-variables/sass/components/media";
|
||||
@import "bulma-css-variables/sass/components/menu";
|
||||
@import "bulma-css-variables/sass/components/message";
|
||||
//@import "bulma-css-variables/sass/components/message"; // not used
|
||||
@import "bulma-css-variables/sass/components/modal";
|
||||
@import "bulma-css-variables/sass/components/navbar";
|
||||
@import "bulma-css-variables/sass/components/pagination";
|
||||
|
|
|
@ -7,5 +7,4 @@
|
|||
@import "form";
|
||||
@import "link-share";
|
||||
@import "loading";
|
||||
@import "notification";
|
||||
@import "flatpickr";
|
|
@ -1,12 +0,0 @@
|
|||
.notification {
|
||||
border: $thickness solid $border;
|
||||
}
|
||||
|
||||
.notifications {
|
||||
left: 0.5rem !important;
|
||||
bottom: 1rem !important;
|
||||
}
|
||||
|
||||
.message .message-body {
|
||||
border: $thickness solid;
|
||||
}
|
|
@ -3,7 +3,7 @@
|
|||
<h2 v-if="userInfo">
|
||||
{{ $t(`home.welcome${welcome}`, {username: userInfo.name !== '' ? userInfo.name : userInfo.username}) }}!
|
||||
</h2>
|
||||
<div class="notification is-danger" v-if="deletionScheduledAt !== null">
|
||||
<message variant="danger" v-if="deletionScheduledAt !== null">
|
||||
{{
|
||||
$t('user.deletion.scheduled', {
|
||||
date: formatDateShort(deletionScheduledAt),
|
||||
|
@ -13,7 +13,7 @@
|
|||
<router-link :to="{name: 'user.settings', hash: '#deletion'}">
|
||||
{{ $t('user.deletion.scheduledCancel') }}
|
||||
</router-link>
|
||||
</div>
|
||||
</message>
|
||||
<add-task
|
||||
:listId="defaultListId"
|
||||
@taskAdded="updateTaskList"
|
||||
|
@ -57,6 +57,7 @@
|
|||
|
||||
<script>
|
||||
import {mapState} from 'vuex'
|
||||
import Message from '@/components/misc/message'
|
||||
import ShowTasks from './tasks/ShowTasks.vue'
|
||||
import {getHistory} from '../modules/listHistory'
|
||||
import ListCard from '@/components/list/partials/list-card.vue'
|
||||
|
@ -67,6 +68,7 @@ import {parseDateOrNull} from '../helpers/parseDateOrNull'
|
|||
export default {
|
||||
name: 'Home',
|
||||
components: {
|
||||
Message,
|
||||
ListCard,
|
||||
ShowTasks,
|
||||
AddTask,
|
||||
|
@ -147,7 +149,7 @@ export default {
|
|||
flex-wrap: wrap;
|
||||
max-height: calc(#{$list-height * 2} + #{$list-spacing * 2} - 4px);
|
||||
overflow: hidden;
|
||||
|
||||
|
||||
@media screen and (max-width: $mobile) {
|
||||
max-height: calc(#{$list-height * 4} + #{$list-spacing * 4} - 4px);
|
||||
}
|
||||
|
|
|
@ -36,9 +36,9 @@
|
|||
</div>
|
||||
</div>
|
||||
<transition name="fade">
|
||||
<div class="notification is-warning" v-if="currentList.isArchived">
|
||||
<message variant="warning" v-if="currentList.isArchived" class="mb-4">
|
||||
{{ $t('list.archived') }}
|
||||
</div>
|
||||
</message>
|
||||
</transition>
|
||||
|
||||
<router-view/>
|
||||
|
@ -46,6 +46,7 @@
|
|||
</template>
|
||||
|
||||
<script>
|
||||
import Message from '@/components/misc/message'
|
||||
import ListModel from '../../models/list'
|
||||
import ListService from '../../services/list'
|
||||
import {CURRENT_LIST} from '../../store/mutation-types'
|
||||
|
@ -53,6 +54,7 @@ import {getListView} from '../../helpers/saveListView'
|
|||
import {saveListToHistory} from '../../modules/listHistory'
|
||||
|
||||
export default {
|
||||
components: {Message},
|
||||
data() {
|
||||
return {
|
||||
listService: new ListService(),
|
||||
|
|
|
@ -39,7 +39,7 @@
|
|||
<div class="migration-in-progress">
|
||||
<img :alt="migrator.name" :src="migrator.icon" class="logo"/>
|
||||
<div class="progress-dots">
|
||||
<span v-for="i in progressDotsCount" :key="i" />
|
||||
<span v-for="i in progressDotsCount" :key="i"/>
|
||||
</div>
|
||||
<Logo class="logo"/>
|
||||
</div>
|
||||
|
@ -57,11 +57,9 @@
|
|||
</div>
|
||||
</div>
|
||||
<div v-else>
|
||||
<div class="message is-primary">
|
||||
<div class="message-body">
|
||||
{{ message }}
|
||||
</div>
|
||||
</div>
|
||||
<message class="mb-4">
|
||||
{{ message }}
|
||||
</message>
|
||||
<x-button :to="{name: 'home'}">{{ $t('misc.refresh') }}</x-button>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -71,6 +69,7 @@
|
|||
import AbstractMigrationService from '@/services/migrator/abstractMigration'
|
||||
import AbstractMigrationFileService from '@/services/migrator/abstractMigrationFile'
|
||||
import Logo from '@/assets/logo.svg?component'
|
||||
import Message from '@/components/misc/message'
|
||||
|
||||
import {MIGRATORS} from './migrators'
|
||||
|
||||
|
@ -79,7 +78,10 @@ const PROGRESS_DOTS_COUNT = 8
|
|||
export default {
|
||||
name: 'MigrateService',
|
||||
|
||||
components: { Logo },
|
||||
components: {
|
||||
Logo,
|
||||
Message,
|
||||
},
|
||||
|
||||
data() {
|
||||
return {
|
||||
|
@ -101,7 +103,7 @@ export default {
|
|||
|
||||
beforeRouteEnter(to) {
|
||||
if (MIGRATORS[to.params.service] === undefined) {
|
||||
return { name: 'not-found' }
|
||||
return {name: 'not-found'}
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -122,7 +124,7 @@ export default {
|
|||
if (this.migrator.isFileMigrator) {
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
this.authUrl = await this.migrationService.getAuthUrl().then(({url}) => url)
|
||||
|
||||
this.migratorAuthCode = location.hash.startsWith('#token=')
|
||||
|
@ -150,7 +152,7 @@ export default {
|
|||
this.lastMigrationDate = null
|
||||
this.message = ''
|
||||
|
||||
let migrationConfig = { code: this.migratorAuthCode }
|
||||
let migrationConfig = {code: this.migratorAuthCode}
|
||||
|
||||
if (this.migrator.isFileMigrator) {
|
||||
if (this.$refs.uploadInput.files.length === 0) {
|
||||
|
@ -160,7 +162,7 @@ export default {
|
|||
}
|
||||
|
||||
try {
|
||||
const { message } = await this.migrationService.migrate(migrationConfig)
|
||||
const {message} = await this.migrationService.migrate(migrationConfig)
|
||||
this.message = message
|
||||
return this.$store.dispatch('namespaces/loadNamespaces')
|
||||
} finally {
|
||||
|
@ -173,24 +175,24 @@ export default {
|
|||
|
||||
<style lang="scss" scoped>
|
||||
.migration-in-progress-container {
|
||||
max-width: 400px;
|
||||
margin: 4rem auto 0;
|
||||
text-align: center;
|
||||
max-width: 400px;
|
||||
margin: 4rem auto 0;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.migration-in-progress {
|
||||
text-align: center;
|
||||
display: flex;
|
||||
max-width: 400px;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 2rem;
|
||||
text-align: center;
|
||||
display: flex;
|
||||
max-width: 400px;
|
||||
justify-content: space-between;
|
||||
align-items: center;
|
||||
margin-bottom: 2rem;
|
||||
}
|
||||
|
||||
.logo {
|
||||
display: block;
|
||||
max-height: 100px;
|
||||
max-width: 100px;
|
||||
display: block;
|
||||
max-height: 100px;
|
||||
max-width: 100px;
|
||||
}
|
||||
|
||||
.progress-dots {
|
||||
|
|
|
@ -28,19 +28,20 @@
|
|||
<div class="field">
|
||||
<label class="label">{{ $t('namespace.attributes.color') }}</label>
|
||||
<div class="control">
|
||||
<color-picker v-model="namespace.hexColor" />
|
||||
<color-picker v-model="namespace.hexColor"/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="notification is-info mt-4">
|
||||
<message class="mt-4">
|
||||
<h4 class="title">{{ $t('namespace.create.tooltip') }}</h4>
|
||||
|
||||
{{ $t('namespace.create.explanation') }}
|
||||
</div>
|
||||
</message>
|
||||
</create-edit>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Message from '@/components/misc/message'
|
||||
import NamespaceModel from '../../models/namespace'
|
||||
import NamespaceService from '../../services/namespace'
|
||||
import CreateEdit from '@/components/misc/create-edit.vue'
|
||||
|
@ -56,6 +57,7 @@ export default {
|
|||
}
|
||||
},
|
||||
components: {
|
||||
Message,
|
||||
ColorPicker,
|
||||
CreateEdit,
|
||||
},
|
||||
|
@ -72,7 +74,7 @@ export default {
|
|||
|
||||
const namespace = await this.namespaceService.create(this.namespace)
|
||||
this.$store.commit('namespaces/addNamespace', namespace)
|
||||
this.$message.success({message: this.$t('namespace.create.success') })
|
||||
this.$message.success({message: this.$t('namespace.create.success')})
|
||||
this.$router.back()
|
||||
},
|
||||
},
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
<template>
|
||||
<div>
|
||||
<div class="notification is-info is-light has-text-centered" v-if="loading">
|
||||
<message v-if="loading">
|
||||
{{ $t('sharing.authenticating') }}
|
||||
</div>
|
||||
</message>
|
||||
<div v-if="authenticateWithPassword" class="box">
|
||||
<p class="pb-2">
|
||||
{{ $t('sharing.passwordRequired') }}
|
||||
|
@ -25,18 +25,20 @@
|
|||
{{ $t('user.auth.login') }}
|
||||
</x-button>
|
||||
|
||||
<div class="notification is-danger mt-4" v-if="errorMessage !== ''">
|
||||
<message variant="danger" class="mt-4" v-if="errorMessage !== ''">
|
||||
{{ errorMessage }}
|
||||
</div>
|
||||
</message>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {mapGetters} from 'vuex'
|
||||
import Message from '@/components/misc/message'
|
||||
|
||||
export default {
|
||||
name: 'LinkSharingAuth',
|
||||
components: {Message},
|
||||
data() {
|
||||
return {
|
||||
loading: true,
|
||||
|
@ -72,7 +74,7 @@ export default {
|
|||
password: this.password,
|
||||
})
|
||||
this.$router.push({name: 'list.list', params: {listId: r.list_id}})
|
||||
} catch(e) {
|
||||
} catch (e) {
|
||||
if (typeof e.response.data.code !== 'undefined' && e.response.data.code === 13001) {
|
||||
this.authenticateWithPassword = true
|
||||
return
|
||||
|
|
|
@ -2,9 +2,9 @@
|
|||
<div>
|
||||
<h2 class="title has-text-centered">Login</h2>
|
||||
<div class="box">
|
||||
<div class="notification is-success has-text-centered" v-if="confirmedEmailSuccess">
|
||||
<message variant="success" class="has-text-centered" v-if="confirmedEmailSuccess">
|
||||
{{ $t('user.auth.confirmEmailSuccess') }}
|
||||
</div>
|
||||
</message>
|
||||
<api-config @foundApi="hasApiUrl = true"/>
|
||||
<form @submit.prevent="submit" id="loginform" v-if="hasApiUrl && localAuthEnabled">
|
||||
<div class="field">
|
||||
|
@ -78,9 +78,9 @@
|
|||
</router-link>
|
||||
</div>
|
||||
</div>
|
||||
<div class="notification is-danger" v-if="errorMessage">
|
||||
<message variant="danger" v-if="errorMessage">
|
||||
{{ errorMessage }}
|
||||
</div>
|
||||
</message>
|
||||
</form>
|
||||
|
||||
<div
|
||||
|
@ -110,11 +110,13 @@ import {LOADING} from '@/store/mutation-types'
|
|||
import legal from '../../components/misc/legal'
|
||||
import ApiConfig from '@/components/misc/api-config.vue'
|
||||
import {getErrorText} from '@/message'
|
||||
import Message from '@/components/misc/message'
|
||||
import {redirectToProvider} from '../../helpers/redirectToProvider'
|
||||
import {getLastVisited, clearLastVisited} from '../../helpers/saveLastVisited'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
Message,
|
||||
ApiConfig,
|
||||
legal,
|
||||
},
|
||||
|
@ -149,7 +151,7 @@ export default {
|
|||
const last = getLastVisited()
|
||||
if (last !== null) {
|
||||
this.$router.push({
|
||||
name: last.name,
|
||||
name: last.name,
|
||||
params: last.params,
|
||||
})
|
||||
clearLastVisited()
|
||||
|
@ -206,7 +208,7 @@ export default {
|
|||
try {
|
||||
await this.$store.dispatch('auth/login', credentials)
|
||||
this.$store.commit('auth/needsTotpPasscode', false)
|
||||
} catch(e) {
|
||||
} catch (e) {
|
||||
if (e.response && e.response.data.code === 1017 && !credentials.totpPasscode) {
|
||||
return
|
||||
}
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
<template>
|
||||
<div>
|
||||
<div class="notification is-danger" v-if="errorMessage">
|
||||
<message variant="danger" v-if="errorMessage">
|
||||
{{ errorMessage }}
|
||||
</div>
|
||||
<div class="notification is-info" v-if="loading">
|
||||
</message>
|
||||
<message v-if="loading">
|
||||
{{ $t('user.auth.authenticating') }}
|
||||
</div>
|
||||
</message>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
@ -14,10 +14,12 @@ import {mapState} from 'vuex'
|
|||
|
||||
import {LOADING} from '@/store/mutation-types'
|
||||
import {getErrorText} from '@/message'
|
||||
import Message from '@/components/misc/message'
|
||||
import {clearLastVisited, getLastVisited} from '../../helpers/saveLastVisited'
|
||||
|
||||
export default {
|
||||
name: 'Auth',
|
||||
components: {Message},
|
||||
data() {
|
||||
return {
|
||||
errorMessage: '',
|
||||
|
|
|
@ -45,37 +45,37 @@
|
|||
</x-button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="notification is-info" v-if="this.passwordResetService.loading">
|
||||
<message v-if="this.passwordResetService.loading">
|
||||
{{ $t('misc.loading') }}
|
||||
</div>
|
||||
<div class="notification is-danger" v-if="errorMsg">
|
||||
</message>
|
||||
<message v-if="errorMsg">
|
||||
{{ errorMsg }}
|
||||
</div>
|
||||
</message>
|
||||
</form>
|
||||
<div class="has-text-centered" v-if="successMessage">
|
||||
<div class="notification is-success">
|
||||
<message variant="success">
|
||||
{{ successMessage }}
|
||||
</div>
|
||||
</message>
|
||||
<x-button :to="{ name: 'user.login' }">
|
||||
{{ $t('user.auth.login') }}
|
||||
</x-button>
|
||||
</div>
|
||||
<Legal />
|
||||
<Legal/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import {ref, reactive} from 'vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import {useI18n} from 'vue-i18n'
|
||||
|
||||
import Legal from '@/components/misc/legal'
|
||||
|
||||
import PasswordResetModel from '@/models/passwordReset'
|
||||
import PasswordResetService from '@/services/passwordReset'
|
||||
import { useTitle } from '@/composables/useTitle'
|
||||
import {useTitle} from '@/composables/useTitle'
|
||||
import Message from '@/components/misc/message'
|
||||
|
||||
const { t } = useI18n()
|
||||
const {t} = useI18n()
|
||||
useTitle(() => t('user.auth.resetPassword'))
|
||||
|
||||
const credentials = reactive({
|
||||
|
@ -97,10 +97,10 @@ async function submit() {
|
|||
|
||||
const passwordReset = new PasswordResetModel({newPassword: credentials.password})
|
||||
try {
|
||||
const { message } = passwordResetService.resetPassword(passwordReset)
|
||||
const {message} = passwordResetService.resetPassword(passwordReset)
|
||||
successMessage.value = message
|
||||
localStorage.removeItem('passwordResetToken')
|
||||
} catch(e) {
|
||||
} catch (e) {
|
||||
errorMsg.value = e.response.data.message
|
||||
}
|
||||
}
|
||||
|
|
|
@ -83,12 +83,12 @@
|
|||
</x-button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="notification is-info" v-if="loading">
|
||||
<message v-if="loading">
|
||||
{{ $t('misc.loading') }}
|
||||
</div>
|
||||
<div class="notification is-danger" v-if="errorMessage !== ''">
|
||||
</message>
|
||||
<message variant="danger" v-if="errorMessage !== ''">
|
||||
{{ errorMessage }}
|
||||
</div>
|
||||
</message>
|
||||
</form>
|
||||
<legal/>
|
||||
</div>
|
||||
|
@ -97,13 +97,13 @@
|
|||
|
||||
<script setup>
|
||||
import {ref, reactive, toRaw, computed, onBeforeMount} from 'vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
import {useI18n} from 'vue-i18n'
|
||||
|
||||
import router from '@/router'
|
||||
import { store } from '@/store'
|
||||
import { useTitle } from '@/composables/useTitle'
|
||||
|
||||
import {store} from '@/store'
|
||||
import {useTitle} from '@/composables/useTitle'
|
||||
import Legal from '@/components/misc/legal'
|
||||
import Message from '@/components/misc/message'
|
||||
|
||||
// FIXME: use the `beforeEnter` hook of vue-router
|
||||
// Check if the user is already logged in, if so, redirect them to the homepage
|
||||
|
@ -113,7 +113,7 @@ onBeforeMount(() => {
|
|||
}
|
||||
})
|
||||
|
||||
const { t } = useI18n()
|
||||
const {t} = useI18n()
|
||||
useTitle(() => t('user.auth.register'))
|
||||
|
||||
const credentials = reactive({
|
||||
|
@ -137,7 +137,7 @@ async function submit() {
|
|||
|
||||
try {
|
||||
await store.dispatch('auth/register', toRaw(credentials))
|
||||
} catch(e) {
|
||||
} catch (e) {
|
||||
errorMessage.value = e.message
|
||||
}
|
||||
}
|
||||
|
|
|
@ -31,14 +31,14 @@
|
|||
</x-button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="notification is-danger" v-if="errorMsg">
|
||||
<message variant="danger" v-if="errorMsg">
|
||||
{{ errorMsg }}
|
||||
</div>
|
||||
</message>
|
||||
</form>
|
||||
<div class="has-text-centered" v-if="isSuccess">
|
||||
<div class="notification is-success">
|
||||
<message variant="success">
|
||||
{{ $t('user.auth.resetPasswordSuccess') }}
|
||||
</div>
|
||||
</message>
|
||||
<x-button :to="{ name: 'user.login' }">
|
||||
{{ $t('user.auth.login') }}
|
||||
</x-button>
|
||||
|
@ -57,6 +57,7 @@ import Legal from '@/components/misc/legal'
|
|||
import PasswordResetModel from '@/models/passwordReset'
|
||||
import PasswordResetService from '@/services/passwordReset'
|
||||
import { useTitle } from '@/composables/useTitle'
|
||||
import Message from '@/components/misc/message'
|
||||
|
||||
const { t } = useI18n()
|
||||
useTitle(() => t('user.auth.resetPassword'))
|
||||
|
|
picky: remove brachets
Done.