Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Misc fixes, especially in the installation form and some other in the config panel #552

Merged
merged 3 commits into from
Mar 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 4 additions & 9 deletions app/src/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
<b-navbar-nav class="ml-auto">
<li class="nav-item">
<b-button
href="/yunohost/sso"
:href="ssoLink"
variant="primary" size="sm" block
>
{{ $t('user_interface_link') }} <icon iname="user" />
Expand Down Expand Up @@ -100,7 +100,8 @@ export default {
'transitions',
'transitionName',
'waiting',
'theme'
'theme',
'ssoLink'
])
},

Expand All @@ -112,13 +113,7 @@ export default {

// This hook is only triggered at page first load
created () {
// From this hook the value of `connected` always come from the localStorage.
// This state may be `true` but session may have expired, by querying
// yunohost infos, api may respond with `Unauthorized` in which case the `connected`
// state will be automaticly reseted and user will be prompt with the login view.
if (this.connected) {
this.$store.dispatch('GET_YUNOHOST_INFOS')
}
this.$store.dispatch('ON_APP_CREATED')
},

mounted () {
Expand Down
29 changes: 16 additions & 13 deletions app/src/helpers/yunohostArguments.js
Original file line number Diff line number Diff line change
Expand Up @@ -79,16 +79,19 @@ export function adressToFormValue (address) {
* @param {Object} forms - A nested form used in config panels.
* @return {Boolean} - expression evaluation result.
*/
export function evaluateExpression (expression, forms) {
export function evaluateExpression (expression, form, nested = true) {
if (!expression) return true
if (expression === '"false"') return false

const context = Object.values(forms).reduce((ctx, args) => {
Object.entries(args).forEach(([id, value]) => {
ctx[id] = isObjectLiteral(value) && 'file' in value ? value.content : value
})
return ctx
}, {})
const context = nested
? Object.values(form).reduce((merged, next) => ({ ...merged, ...next }))
: form

for (const key in context) {
if (isObjectLiteral(context[key]) && 'file' in context[key]) {
context[key] = context[key].content
}
}

// Allow to use match(var,regexp) function
const matchRe = /match(\s*(\w+)\s*,\s*"([^"]+)"\s*)/g
Expand All @@ -107,9 +110,9 @@ export function evaluateExpression (expression, forms) {
}

// Adds a property to an Object that will dynamically returns a expression evaluation result.
function addEvaluationGetter (prop, obj, expr, ctx) {
function addEvaluationGetter (prop, obj, expr, ctx, nested) {
Object.defineProperty(obj, prop, {
get: () => evaluateExpression(expr, ctx)
get: () => evaluateExpression(expr, ctx, nested)
})
}

Expand Down Expand Up @@ -357,12 +360,12 @@ export function formatYunoHostArguments (args, forms) {
if (validation) validations[arg.id] = validation
errors[arg.id] = error

if ('visible' in arg && ![false, '"false"'].includes(arg.visible)) {
addEvaluationGetter('visible', field, arg.visible, forms)
if ('visible' in arg && typeof arg.visible === 'string') {
addEvaluationGetter('visible', field, arg.visible, forms || form, forms !== undefined)
}

if ('enabled' in arg) {
addEvaluationGetter('enabled', field.props, arg.enabled, forms)
if ('enabled' in arg && typeof arg.enabled === 'string') {
addEvaluationGetter('enabled', field.props, arg.enabled, forms || form, forms !== undefined)
}
}

Expand Down
4 changes: 4 additions & 0 deletions app/src/router/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,10 @@ router.beforeEach((to, from, next) => {
if (store.getters.error) {
store.dispatch('DISMISS_ERROR', true)
}

if (to.name === 'post-install' && store.getters.installed) {
return next('/')
}
// Allow if connected or route is not protected
if (store.getters.connected || to.meta.noAuth) {
next()
Expand Down
38 changes: 31 additions & 7 deletions app/src/store/info.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { timeout, isEmptyValue, isObjectLiteral } from '@/helpers/commons'
export default {
state: {
host: window.location.host, // String
installed: null,
connected: localStorage.getItem('connected') === 'true', // Boolean
yunohost: null, // Object { version, repo }
waiting: false, // Boolean
Expand All @@ -22,6 +23,10 @@ export default {
},

mutations: {
'SET_INSTALLED' (state, boolean) {
state.installed = boolean
},

'SET_CONNECTED' (state, boolean) {
localStorage.setItem('connected', boolean)
state.connected = boolean
Expand Down Expand Up @@ -106,23 +111,38 @@ export default {
},

actions: {
'CHECK_INSTALL' ({ dispatch }, retry = 2) {
async 'ON_APP_CREATED' ({ dispatch, state }) {
await dispatch('CHECK_INSTALL')

if (!state.installed) {
router.push({ name: 'post-install' })
} else {
dispatch('CONNECT')
}
},

async 'CHECK_INSTALL' ({ dispatch, commit }, retry = 2) {
// this action will try to query the `/installed` route 3 times every 5 s with
// a timeout of the same delay.
// FIXME need testing with api not responding
return timeout(api.get('installed'), 5000).then(({ installed }) => {
try {
const { installed } = await timeout(api.get('installed'), 5000)
commit('SET_INSTALLED', installed)
return installed
}).catch(err => {
} catch (err) {
if (retry > 0) {
return dispatch('CHECK_INSTALL', --retry)
}
throw err
})
}
},

'CONNECT' ({ commit, dispatch }) {
async 'CONNECT' ({ commit, dispatch }) {
// If the user is not connected, the first action will throw
// and login prompt will be shown automaticly
await dispatch('GET_YUNOHOST_INFOS')
commit('SET_CONNECTED', true)
dispatch('GET_YUNOHOST_INFOS')
await dispatch('GET', { uri: 'domains', storeKey: 'domains' })
},

'RESET_CONNECTED' ({ commit }) {
Expand Down Expand Up @@ -350,6 +370,7 @@ export default {

getters: {
host: state => state.host,
installed: state => state.installed,
connected: state => state.connected,
yunohost: state => state.yunohost,
error: state => state.error,
Expand All @@ -363,6 +384,9 @@ export default {
},
routerKey: state => state.routerKey,
breadcrumb: state => state.breadcrumb,
transitionName: state => state.transitionName
transitionName: state => state.transitionName,
ssoLink: (state, getters) => {
return `//${getters.mainDomain ?? state.host}/yunohost/sso`
}
}
}
20 changes: 6 additions & 14 deletions app/src/views/Login.vue
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
<template #buttons>
<b-button
type="submit" variant="success"
:disabled="disabled" form="ynh-form"
:disabled="!installed" form="ynh-form"
>
{{ $t('login') }}
</b-button>
Expand All @@ -22,6 +22,7 @@
</template>

<script>
import { mapGetters } from 'vuex'
import { validationMixin } from 'vuelidate'
import { alphalownumdot_, required, minLength } from '@/helpers/validators'

Expand All @@ -31,13 +32,11 @@ export default {
mixins: [validationMixin],

props: {
skipInstallCheck: { type: Boolean, default: false },
forceReload: { type: Boolean, default: false }
},

data () {
return {
disabled: !this.skipInstallCheck,
serverError: '',
form: {
username: '',
Expand All @@ -63,6 +62,10 @@ export default {
}
},

computed: {
...mapGetters(['installed'])
},

validations () {
return {
form: {
Expand All @@ -86,17 +89,6 @@ export default {
this.serverError = this.$i18n.t('wrong_password_or_username')
})
}
},

created () {
if (this.skipInstallCheck) return
this.$store.dispatch('CHECK_INSTALL').then(installed => {
if (installed) {
this.disabled = false
} else {
this.$router.push({ name: 'post-install' })
}
})
}
}
</script>
10 changes: 1 addition & 9 deletions app/src/views/PostInstall.vue
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@
<p class="alert alert-success">
<icon iname="thumbs-up" /> {{ $t('installation_complete') }}
</p>
<login skip-install-check />
<login />
</template>
</div>
</template>
Expand Down Expand Up @@ -201,14 +201,6 @@ export default {
confirmation: { required, passwordMatch: sameAs('password') }
}
}
},

created () {
this.$store.dispatch('CHECK_INSTALL').then(installed => {
if (installed) {
this.$router.push({ name: 'home' })
}
})
}
}
</script>
2 changes: 1 addition & 1 deletion app/src/views/_partials/ReconnectingDisplay.vue
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
<template v-if="status === 'success'">
<b-alert variant="success" v-t="'api.reconnecting.success'" />

<login-view skip-install-check force-reload />
<login-view force-reload />
</template>
</b-card-body>
</template>
Expand Down