Move buttons to separate component (#380)
Co-authored-by: kolaente <k@knt.li> Reviewed-on: https://kolaente.dev/vikunja/frontend/pulls/380 Co-authored-by: konrad <konrad@kola-entertainments.de> Co-committed-by: konrad <konrad@kola-entertainments.de>
This commit is contained in:
@ -5,7 +5,8 @@
|
||||
<div class="field has-addons">
|
||||
<div class="control is-expanded">
|
||||
<input
|
||||
class="input" id="api-url"
|
||||
class="input"
|
||||
id="api-url"
|
||||
placeholder="eg. https://localhost:3456"
|
||||
required
|
||||
type="url"
|
||||
@ -15,21 +16,29 @@
|
||||
/>
|
||||
</div>
|
||||
<div class="control">
|
||||
<a class="button is-primary" @click="setApiUrl" :disabled="apiUrl === ''">
|
||||
<x-button @click="setApiUrl" :disabled="apiUrl === ''">
|
||||
Change
|
||||
</a>
|
||||
</x-button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="api-url-info" v-else>
|
||||
Sign in to your Vikunja account on <span v-tooltip="apiUrl">{{ apiDomain() }}</span><br/>
|
||||
<a @click="() => configureApi = true">change</a>
|
||||
Sign in to your Vikunja account on
|
||||
<span v-tooltip="apiUrl"> {{ apiDomain() }} </span>
|
||||
<br />
|
||||
<a @click="() => (configureApi = true)">change</a>
|
||||
</div>
|
||||
|
||||
<div class="notification is-success mt-2" v-if="successMsg !== '' && errorMsg === ''">
|
||||
<div
|
||||
class="notification is-success mt-2"
|
||||
v-if="successMsg !== '' && errorMsg === ''"
|
||||
>
|
||||
{{ successMsg }}
|
||||
</div>
|
||||
<div class="notification is-danger mt-2" v-if="errorMsg !== '' && successMsg === ''">
|
||||
<div
|
||||
class="notification is-danger mt-2"
|
||||
v-if="errorMsg !== '' && successMsg === ''"
|
||||
>
|
||||
{{ errorMsg }}
|
||||
</div>
|
||||
</div>
|
||||
@ -57,7 +66,9 @@ export default {
|
||||
if (window.API_URL.startsWith('/api/v1')) {
|
||||
return window.location.host
|
||||
}
|
||||
const urlParts = window.API_URL.replace('http://', '').replace('https://', '').split(/[/?#]/)
|
||||
const urlParts = window.API_URL.replace('http://', '')
|
||||
.replace('https://', '')
|
||||
.split(/[/?#]/)
|
||||
return urlParts[0]
|
||||
},
|
||||
setApiUrl() {
|
||||
@ -68,7 +79,10 @@ export default {
|
||||
let urlToCheck = this.apiUrl
|
||||
|
||||
// Check if the url has an http prefix
|
||||
if (!urlToCheck.startsWith('http://') && !urlToCheck.startsWith('https://')) {
|
||||
if (
|
||||
!urlToCheck.startsWith('http://') &&
|
||||
!urlToCheck.startsWith('https://')
|
||||
) {
|
||||
urlToCheck = `http://${urlToCheck}`
|
||||
}
|
||||
|
||||
@ -79,17 +93,21 @@ export default {
|
||||
window.API_URL = urlToCheck.toString()
|
||||
|
||||
// Check if the api is reachable at the provided url
|
||||
this.$store.dispatch('config/update')
|
||||
.catch(e => {
|
||||
this.$store
|
||||
.dispatch('config/update')
|
||||
.catch((e) => {
|
||||
// Check if it is reachable at /api/v1 and http
|
||||
if (!urlToCheck.pathname.endsWith('/api/v1') && !urlToCheck.pathname.endsWith('/api/v1/')) {
|
||||
if (
|
||||
!urlToCheck.pathname.endsWith('/api/v1') &&
|
||||
!urlToCheck.pathname.endsWith('/api/v1/')
|
||||
) {
|
||||
urlToCheck.pathname = `${urlToCheck.pathname}api/v1`
|
||||
window.API_URL = urlToCheck.toString()
|
||||
return this.$store.dispatch('config/update')
|
||||
}
|
||||
return Promise.reject(e)
|
||||
})
|
||||
.catch(e => {
|
||||
.catch((e) => {
|
||||
// Check if it has a port and if not check if it is reachable at https
|
||||
if (urlToCheck.protocol === 'http:') {
|
||||
urlToCheck.protocol = 'https:'
|
||||
@ -98,17 +116,20 @@ export default {
|
||||
}
|
||||
return Promise.reject(e)
|
||||
})
|
||||
.catch(e => {
|
||||
.catch((e) => {
|
||||
// Check if it is reachable at /api/v1 and https
|
||||
urlToCheck.pathname = origUrlToCheck.pathname
|
||||
if (!urlToCheck.pathname.endsWith('/api/v1') && !urlToCheck.pathname.endsWith('/api/v1/')) {
|
||||
if (
|
||||
!urlToCheck.pathname.endsWith('/api/v1') &&
|
||||
!urlToCheck.pathname.endsWith('/api/v1/')
|
||||
) {
|
||||
urlToCheck.pathname = `${urlToCheck.pathname}api/v1`
|
||||
window.API_URL = urlToCheck.toString()
|
||||
return this.$store.dispatch('config/update')
|
||||
}
|
||||
return Promise.reject(e)
|
||||
})
|
||||
.catch(e => {
|
||||
.catch((e) => {
|
||||
// Check if it is reachable at port 3456 and https
|
||||
if (urlToCheck.port !== 3456) {
|
||||
urlToCheck.protocol = 'https:'
|
||||
@ -118,17 +139,20 @@ export default {
|
||||
}
|
||||
return Promise.reject(e)
|
||||
})
|
||||
.catch(e => {
|
||||
.catch((e) => {
|
||||
// Check if it is reachable at :3456 and /api/v1 and https
|
||||
urlToCheck.pathname = origUrlToCheck.pathname
|
||||
if (!urlToCheck.pathname.endsWith('/api/v1') && !urlToCheck.pathname.endsWith('/api/v1/')) {
|
||||
if (
|
||||
!urlToCheck.pathname.endsWith('/api/v1') &&
|
||||
!urlToCheck.pathname.endsWith('/api/v1/')
|
||||
) {
|
||||
urlToCheck.pathname = `${urlToCheck.pathname}api/v1`
|
||||
window.API_URL = urlToCheck.toString()
|
||||
return this.$store.dispatch('config/update')
|
||||
}
|
||||
return Promise.reject(e)
|
||||
})
|
||||
.catch(e => {
|
||||
.catch((e) => {
|
||||
// Check if it is reachable at port 3456 and http
|
||||
if (urlToCheck.port !== 3456) {
|
||||
urlToCheck.protocol = 'http:'
|
||||
@ -138,10 +162,13 @@ export default {
|
||||
}
|
||||
return Promise.reject(e)
|
||||
})
|
||||
.catch(e => {
|
||||
.catch((e) => {
|
||||
// Check if it is reachable at :3456 and /api/v1 and http
|
||||
urlToCheck.pathname = origUrlToCheck.pathname
|
||||
if (!urlToCheck.pathname.endsWith('/api/v1') && !urlToCheck.pathname.endsWith('/api/v1/')) {
|
||||
if (
|
||||
!urlToCheck.pathname.endsWith('/api/v1') &&
|
||||
!urlToCheck.pathname.endsWith('/api/v1/')
|
||||
) {
|
||||
urlToCheck.pathname = `${urlToCheck.pathname}api/v1`
|
||||
window.API_URL = urlToCheck.toString()
|
||||
return this.$store.dispatch('config/update')
|
||||
@ -154,7 +181,7 @@ export default {
|
||||
this.errorMsg = `Could not find or use Vikunja installation at "${this.apiDomain()}".`
|
||||
window.API_URL = oldUrl
|
||||
})
|
||||
.then(r => {
|
||||
.then((r) => {
|
||||
if (typeof r !== 'undefined') {
|
||||
// Set it + save it to local storage to save us the hoops
|
||||
this.errorMsg = ''
|
||||
|
39
src/components/misc/card.vue
Normal file
39
src/components/misc/card.vue
Normal file
@ -0,0 +1,39 @@
|
||||
<template>
|
||||
<div class="card">
|
||||
<header class="card-header" v-if="title !== ''">
|
||||
<p class="card-header-title">
|
||||
{{ title }}
|
||||
</p>
|
||||
<a @click="$emit('close')" class="card-header-icon" v-if="hasClose">
|
||||
<span class="icon">
|
||||
<icon icon="angle-right"/>
|
||||
</span>
|
||||
</a>
|
||||
</header>
|
||||
<div class="card-content" :class="{'p-0': !padding}">
|
||||
<div class="content">
|
||||
<slot></slot>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'card',
|
||||
props: {
|
||||
title: {
|
||||
type: String,
|
||||
default: '',
|
||||
},
|
||||
padding: {
|
||||
type: Boolean,
|
||||
default: true,
|
||||
},
|
||||
hasClose: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
@ -2,71 +2,50 @@
|
||||
<div class="modal-mask keyboard-shortcuts-modal">
|
||||
<div @click.self="close()" class="modal-container">
|
||||
<div class="modal-content">
|
||||
<div class="card has-background-white has-no-shadow">
|
||||
<header class="card-header">
|
||||
<p class="card-header-title">Available Keyboard Shortcuts</p>
|
||||
</header>
|
||||
<div class="card-content content">
|
||||
<p>
|
||||
<strong>Toggle The Menu</strong>
|
||||
<span class="shortcuts">
|
||||
<span>ctrl</span>
|
||||
<i>+</i>
|
||||
<span>e</span>
|
||||
</span>
|
||||
</p>
|
||||
<h3>Kanban</h3>
|
||||
<div class="message is-primary" v-if="$route.name === 'list.kanban'">
|
||||
<div class="message-body">
|
||||
These shortcuts work on the current page.
|
||||
</div>
|
||||
<card class="has-background-white has-no-shadow" title="Available Keyboard Shortcuts">
|
||||
<p>
|
||||
<strong>Toggle The Menu</strong>
|
||||
<shortcut :keys="['ctrl', 'e']"/>
|
||||
</p>
|
||||
<h3>Kanban</h3>
|
||||
<div class="message is-primary" v-if="$route.name === 'list.kanban'">
|
||||
<div class="message-body">
|
||||
These shortcuts work on the current page.
|
||||
</div>
|
||||
<p>
|
||||
<strong>Mark a task as done</strong>
|
||||
<span class="shortcuts">
|
||||
<span>ctrl</span>
|
||||
<i>+</i>
|
||||
<span>click</span>
|
||||
</span>
|
||||
</p>
|
||||
<h3>Task Page</h3>
|
||||
<div class="message is-primary" v-if="$route.name === 'task.detail' || $route.name === 'task.list.detail' || $route.name === 'task.gantt.detail' || $route.name === 'task.kanban.detail' || $route.name === 'task.detail'">
|
||||
<div class="message-body">
|
||||
These shortcuts work on the current page.
|
||||
</div>
|
||||
</div>
|
||||
<p>
|
||||
<strong>Assign this task to a user</strong>
|
||||
<span class="shortcuts">
|
||||
<span>a</span>
|
||||
</span>
|
||||
</p>
|
||||
<p>
|
||||
<strong>Add labels to this task</strong>
|
||||
<span class="shortcuts">
|
||||
<span>l</span>
|
||||
</span>
|
||||
</p>
|
||||
<p>
|
||||
<strong>Change the due date of this task</strong>
|
||||
<span class="shortcuts">
|
||||
<span>d</span>
|
||||
</span>
|
||||
</p>
|
||||
<p>
|
||||
<strong>Add an attachment to this task</strong>
|
||||
<span class="shortcuts">
|
||||
<span>f</span>
|
||||
</span>
|
||||
</p>
|
||||
<p>
|
||||
<strong>Modify related tasks of this task</strong>
|
||||
<span class="shortcuts">
|
||||
<span>r</span>
|
||||
</span>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<p>
|
||||
<strong>Mark a task as done</strong>
|
||||
<shortcut :keys="['ctrl', 'click']"/>
|
||||
</p>
|
||||
<h3>Task Page</h3>
|
||||
<div
|
||||
class="message is-primary"
|
||||
v-if="$route.name === 'task.detail' || $route.name === 'task.list.detail' || $route.name === 'task.gantt.detail' || $route.name === 'task.kanban.detail' || $route.name === 'task.detail'">
|
||||
<div class="message-body">
|
||||
These shortcuts work on the current page.
|
||||
</div>
|
||||
</div>
|
||||
<p>
|
||||
<strong>Assign this task to a user</strong>
|
||||
<shortcut :keys="['a']"/>
|
||||
</p>
|
||||
<p>
|
||||
<strong>Add labels to this task</strong>
|
||||
<shortcut :keys="['l']"/>
|
||||
</p>
|
||||
<p>
|
||||
<strong>Change the due date of this task</strong>
|
||||
<shortcut :keys="['d']"/>
|
||||
</p>
|
||||
<p>
|
||||
<strong>Add an attachment to this task</strong>
|
||||
<shortcut :keys="['f']"/>
|
||||
</p>
|
||||
<p>
|
||||
<strong>Modify related tasks of this task</strong>
|
||||
<shortcut :keys="['r']"/>
|
||||
</p>
|
||||
</card>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -74,9 +53,11 @@
|
||||
|
||||
<script>
|
||||
import {KEYBOARD_SHORTCUTS_ACTIVE} from '@/store/mutation-types'
|
||||
import Shortcut from '@/components/misc/shortcut'
|
||||
|
||||
export default {
|
||||
name: 'keyboard-shortcuts',
|
||||
components: {Shortcut},
|
||||
methods: {
|
||||
close() {
|
||||
this.$store.commit(KEYBOARD_SHORTCUTS_ACTIVE, false)
|
||||
|
@ -1,27 +1,40 @@
|
||||
<template>
|
||||
<notifications position="bottom left" :max="2" class="global-notification">
|
||||
<template slot="body" slot-scope="props">
|
||||
<div :class="['vue-notification-template', 'vue-notification', props.item.type]" @click="close(props)">
|
||||
<div
|
||||
:class="[
|
||||
'vue-notification-template',
|
||||
'vue-notification',
|
||||
props.item.type,
|
||||
]"
|
||||
@click="close(props)"
|
||||
>
|
||||
<div
|
||||
class="notification-title"
|
||||
v-html="props.item.title"
|
||||
v-if="props.item.title"
|
||||
>
|
||||
</div>
|
||||
></div>
|
||||
<div
|
||||
class="notification-content"
|
||||
v-html="props.item.text"
|
||||
>
|
||||
</div>
|
||||
></div>
|
||||
<div
|
||||
class="buttons is-right"
|
||||
v-if="props.item.data && props.item.data.actions && props.item.data.actions.length > 0">
|
||||
<button
|
||||
:key="'action_'+i"
|
||||
v-if="
|
||||
props.item.data &&
|
||||
props.item.data.actions &&
|
||||
props.item.data.actions.length > 0
|
||||
"
|
||||
>
|
||||
<x-button
|
||||
:key="'action_' + i"
|
||||
@click="action.callback"
|
||||
class="button has-no-shadow is-small" v-for="(action, i) in props.item.data.actions">
|
||||
:shadow="false"
|
||||
class="is-small"
|
||||
v-for="(action, i) in props.item.data.actions"
|
||||
>
|
||||
{{ action.title }}
|
||||
</button>
|
||||
</x-button>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
@ -40,12 +53,11 @@ export default {
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
|
||||
.vue-notification {
|
||||
z-index: 9999;
|
||||
}
|
||||
|
||||
.buttons {
|
||||
margin-top: .5em;
|
||||
margin-top: 0.5em;
|
||||
}
|
||||
</style>
|
20
src/components/misc/shortcut.vue
Normal file
20
src/components/misc/shortcut.vue
Normal file
@ -0,0 +1,20 @@
|
||||
<template>
|
||||
<span class="shortcuts">
|
||||
<template v-for="(k, i) in keys">
|
||||
<span :key="i">{{ k }}</span>
|
||||
<i v-if="i < keys.length - 1" :key="`plus${i}`">+</i>
|
||||
</template>
|
||||
</span>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
name: 'shortcut',
|
||||
props: {
|
||||
keys: {
|
||||
type: Array,
|
||||
required: true,
|
||||
}
|
||||
},
|
||||
}
|
||||
</script>
|
Reference in New Issue
Block a user