linting…

This commit is contained in:
Axolotle 2020-07-15 16:39:24 +02:00
parent d69bb8b906
commit 6f8457381a
15 changed files with 577 additions and 546 deletions

View file

@ -2,15 +2,21 @@
<div id="app" class="container">
<header>
<b-navbar>
<b-navbar-brand to="/" exact exact-active-class="active"><img alt="Yunohost logo" src="./assets/logo.png"></b-navbar-brand>
<b-navbar-brand to="/" exact exact-active-class="active">
<img alt="Yunohost logo" src="./assets/logo.png">
</b-navbar-brand>
<b-navbar-nav class="ml-auto">
<li class="nav-item">
<b-button href="/yunohost/sso" variant="primary" block size="sm">
<b-button href="/yunohost/sso"
variant="primary" size="sm" block
>
{{ $t('user_interface_link') }} <icon iname="user" />
</b-button>
</li>
<li class="nav-item" v-show="connected">
<b-button @click.prevent="logout" to="/logout" variant="outline-dark" block size="sm" >
<b-button @click.prevent="logout" to="/logout"
variant="outline-dark" block size="sm"
>
{{ $t('logout') }} <icon iname="sign-out" />
</b-button>
</li>
@ -25,19 +31,29 @@
<footer>
<nav>
<b-nav>
<b-nav-item href="https://yunohost.org/docs" target="_blank" link-classes='text-secondary'>
<b-nav-item href="https://yunohost.org/docs" target="_blank" link-classes="text-secondary">
<icon iname="book" /> Documentation
</b-nav-item>
<b-nav-item href="https://yunohost.org/help" target="_blank" link-classes='text-secondary'>
<b-nav-item href="https://yunohost.org/help" target="_blank" link-classes="text-secondary">
<icon iname="life-ring" /> Need help?
</b-nav-item>
<b-nav-item href="https://donate.yunohost.org/" target="_blank" link-classes='text-secondary'>
<b-nav-item href="https://donate.yunohost.org/" target="_blank" link-classes="text-secondary">
<icon iname="heart" /> Donate
</b-nav-item>
<i18n v-if="yunohostInfos" path="footer_version" tag="b-nav-text" class="ml-auto" id="yunohost-version">
<template v-slot:ynh><b-link href="https://yunohost.org">YunoHost</b-link></template>
<template v-slot:version>{{ yunohostInfos.version }}</template>
<template v-slot:repo>{{ yunohostInfos.repo }}</template>
<i18n v-if="yunohostInfos" path="footer_version" tag="b-nav-text"
id="yunohost-version" class="ml-auto"
>
<template v-slot:ynh>
<b-link href="https://yunohost.org">
YunoHost
</b-link>
</template>
<template v-slot:version>
{{ yunohostInfos.version }}
</template>
<template v-slot:repo>
{{ yunohostInfos.repo }}
</template>
</i18n>
</b-nav>
</nav>
@ -50,25 +66,24 @@ import { mapState } from 'vuex'
import api from '@/helpers/api'
export default {
name: 'App',
data: () => {
return {
// isReady blocks the rendering of the rooter-view until we have a true info
// about the connected state of the user.
isReady: false,
isReady: false
}
},
computed: {
...mapState(['connected', 'yunohostInfos']),
...mapState(['connected', 'yunohostInfos'])
},
methods: {
async logout () {
await api.logout()
this.$store.commit('CONNECTED', false);
this.$store.commit('CONNECTED', false)
this.$router.push('/login')
},
}
},
// This hook is only triggered at page reload so the value of state.connected
// always come from the localStorage
@ -87,11 +102,11 @@ export default {
// Session expired, reset the 'connected' state and redirect with a query
// FIXME is there a case where the error may not be a 401 therefor requires
// better handling ?
this.$store.commit('CONNECTED', false);
this.$store.commit('CONNECTED', false)
this.$router.push({ name: 'login', query: { redirect: this.$route.path } })
} finally {
// in any case allow the router-view to be rendered
this.isReady = true;
this.isReady = true
}
}
}

View file

@ -38,8 +38,8 @@ export default {
},
lastIndex: function () {
return this.breadcrumb.length - 1
},
},
}
}
}
</script>

View file

@ -1,11 +1,13 @@
<template>
<span :class="'icon fa fa-' + iname" aria-hidden="true"></span>
<span :class="'icon fa fa-' + iname" aria-hidden="true" />
</template>
<script>
export default {
name: 'icon',
props: ['iname'],
name: 'Icon',
props: {
iname: { type: String, required: true }
}
}
</script>

View file

@ -1,26 +1,21 @@
function objectToParams (object) {
const urlParams = new URLSearchParams();
const urlParams = new URLSearchParams()
for (const [key, value] of Object.entries(object)) {
urlParams.append(key, value)
}
return urlParams
}
function handleResponse (response, type = 'json') {
return response.ok ? response[type]() : handleErrors(response)
}
function handleErrors (response) {
if (response.status == 401) {
throw new Error('Unauthorized');
if (response.status === 401) {
throw new Error('Unauthorized')
}
}
export default {
options: {
credentials: 'include',
@ -32,7 +27,7 @@ export default {
// "Accept": "*/*",
// Also is this still important ? (needed by back-end)
'X-Requested-With': 'XMLHttpRequest',
'X-Requested-With': 'XMLHttpRequest'
}
},
@ -57,7 +52,6 @@ export default {
},
getVersion () {
return fetch('/api/versions', this.options)
.then(response => handleResponse(response))
return fetch('/api/versions', this.options).then(response => handleResponse(response))
}
}

View file

@ -7,11 +7,10 @@ import store from './plugins/store'
import * as globalsComponents from './components/globals'
Vue.config.productionTip = false
// Register global components
for (let component of Object.values(globalsComponents)) {
for (const component of Object.values(globalsComponents)) {
Vue.component(component.name, component)
}
@ -19,5 +18,5 @@ new Vue({
i18n,
router,
store,
render: h => h(App),
render: h => h(App)
}).$mount('#app')

View file

@ -1,7 +1,6 @@
import Vue from 'vue'
import VueI18n from 'vue-i18n'
Vue.use(VueI18n)
function loadLocaleMessages () {

View file

@ -3,7 +3,6 @@ import VueRouter from 'vue-router'
import routes from '../routes'
import store from './store'
Vue.use(VueRouter)
const router = new VueRouter({
@ -22,5 +21,4 @@ router.beforeEach((to, from, next) => {
}
})
export default router;
export default router

View file

@ -1,7 +1,6 @@
import Vue from 'vue'
import Vuex from 'vuex'
Vue.use(Vuex)
export default new Vuex.Store({
@ -11,15 +10,15 @@ export default new Vuex.Store({
},
// Mutations must be synchronous. They are used to change the store state.
mutations: {
['CONNECTED'] (state, connected) {
'CONNECTED' (state, connected) {
localStorage.setItem('connected', connected)
state.connected = connected
if (!connected) {
state.yunohostInfos = null
}
},
['YUNOHOST_INFOS'] (state, data) {
console.log('version changed', data);
'YUNOHOST_INFOS' (state, data) {
console.log('version changed', data)
state.yunohostInfos = data
}
},

View file

@ -3,21 +3,29 @@ import Login from './views/Login'
import Users from './views/Users'
import User from './views/User'
const routes = [
{ name: 'home', path: '/', component: Home },
{name: 'login', path: '/login', component: Login, meta: {
noAuth: true
}},
{name: 'users', path: '/users', component: Users, meta: {
{ name: 'login', path: '/login', component: Login, meta: { noAuth: true } },
{
name: 'users',
path: '/users',
component: Users,
meta: {
breadcrumb: [{ name: 'users', trad: 'users' }]
}},
{name: 'user', path: '/user/:name', component: User, props: true, meta: {
}
},
{
name: 'user',
path: '/user/:name',
component: User,
props: true,
meta: {
breadcrumb: [
{ name: 'users', trad: 'users' },
{ name: 'user', param: 'name' }
]
}},
}
}
]
export default routes

View file

@ -23,10 +23,10 @@ export default {
{ id: 4, uri: '/services', icon: 'cog', translation: 'services' },
{ id: 5, uri: '/tools', icon: 'wrench', translation: 'tools' },
{ id: 6, uri: '/diagnosis', icon: 'stethoscope', translation: 'diagnosis' },
{id: 7, uri: '/backup', icon: 'archive', translation: 'backup'},
{ id: 7, uri: '/backup', icon: 'archive', translation: 'backup' }
]
}
},
}
}
</script>

View file

@ -8,14 +8,16 @@
<icon iname="lock" class="sm" />
</b-input-group-text>
</template>
<b-form-input required id="input-password"
<b-form-input
id="input-password"
required type="password"
v-model="password"
type="password"
:placeholder="$t('administration_password')"
:state="isValid"
></b-form-input>
:placeholder="$t('administration_password')" :state="isValid"
/>
<template v-slot:append>
<b-button type="submit" variant="success">{{ $t('login') }}</b-button>
<b-button type="submit" variant="success">
{{ $t('login') }}
</b-button>
</template>
</b-input-group>
<b-form-invalid-feedback :state="isValid">
@ -27,29 +29,28 @@
<script>
import api from '@/helpers/api'
export default {
name: 'Login',
data: () => {
return {
password: '',
isValid: null,
isValid: null
}
},
methods: {
async login () {
const connected = await api.login(this.password)
if (connected) {
this.$store.commit('CONNECTED', true);
this.$store.commit('CONNECTED', true)
this.$router.push(this.$route.query.redirect || '/')
const infos = await api.getVersion();
const infos = await api.getVersion()
this.$store.commit('YUNOHOST_INFOS', infos.yunohost)
} else {
this.$store.commit('CONNECTED', false);
this.$store.commit('CONNECTED', false)
this.isValid = false
}
}
},
}
// TODO checkInstall
// beforeRouteEnter (to, from, next) {
// },

View file

@ -6,7 +6,7 @@
<h2>{{ user ? user.fullname : '' }}</h2>
</template>
<div class="d-flex align-items-center">
<icon iname="user" class="fa-fw"></icon>
<icon iname="user" class="fa-fw" />
<div class="w-100">
<template v-if="user">
<b-row>
@ -15,7 +15,9 @@
</b-row>
<b-row>
<b-col><strong>{{ $t('user_email') }}</strong></b-col>
<b-col class="font-italic">{{ user.mail }}</b-col>
<b-col class="font-italic">
{{ user.mail }}
</b-col>
</b-row>
<b-row>
<b-col><strong>{{ $t('user_mailbox_quota') }}</strong></b-col>
@ -42,18 +44,26 @@
<!-- skeleton -->
<template v-else>
<b-row v-for="(n, index) in 6" :key="index">
<b-col><strong class="rounded"></strong></b-col>
<b-col><span v-if="n <= 4" class="rounded"></span></b-col>
<b-col>
<strong class="rounded" />
</b-col>
<b-col>
<span v-if="n <= 4" class="rounded" />
</b-col>
</b-row>
</template>
</div>
</div>
<template v-slot:footer>
<div class="d-flex d-flex justify-content-end">
<b-button :to="user ? {name: 'user-edit', params: {user: user}} : null" :variant="user ? 'info' : 'dark'" >
<b-button :to="user ? {name: 'user-edit', params: {user: user}} : null"
:variant="user ? 'info' : 'dark'"
>
{{ user ? $t('user_username_edit', {name: user.username}) : '' }}
</b-button>
<b-button :variant="user ? 'danger' : 'dark'" class="ml-2">{{ user ? $t('delete') : '' }}</b-button>
<b-button :variant="user ? 'danger' : 'dark'" class="ml-2">
{{ user ? $t('delete') : '' }}
</b-button>
</div>
</template>
</b-card>
@ -66,15 +76,20 @@ import Breadcrumb from '@/components/Breadcrumb'
export default {
name: 'User',
props: ['name'],
props: {
name: {
type: Object,
required: true
}
},
data: function () {
return {
user: undefined,
user: undefined
}
},
async created () {
const data = await api.get('users/' + this.name)
if (!data) return;
if (!data) return
this.user = data
},
components: {
@ -130,7 +145,6 @@ ul {
h2 {
height: #{2 * 1.2}rem;
}
.col {

View file

@ -10,17 +10,19 @@
<template v-else>
<b-list-group :class="{skeleton: !users}">
<b-list-group-item
class="d-flex justify-content-between align-items-center pr-0"
v-for="(user, index) in (users ? users : 3)"
:key="index"
:to="users ? { name: 'user', params: { name: user.username }} : null"
class="d-flex justify-content-between align-items-center pr-0"
>
<div>
<h5 :class="{rounded: !users}">
{{ user.username }}
<small>({{ user.fullname }})</small>
</h5>
<p :class="{rounded: !users}">{{ user.mail }}</p>
<p :class="{rounded: !users}">
{{ user.mail }}
</p>
</div>
<icon iname="chevron-right" class="lg fs-sm ml-auto" />
</b-list-group-item>
@ -52,7 +54,7 @@ export default {
},
components: {
Breadcrumb
},
}
}
</script>