yunohost-admin/app/src/store/data.js

312 lines
8.7 KiB
JavaScript
Raw Normal View History

import Vue from 'vue'
2020-10-12 17:36:47 +02:00
import api from '@/api'
import { isEmptyValue } from '@/helpers/commons'
2022-02-01 17:21:35 +01:00
import { stratify } from '@/helpers/data/tree'
2024-02-24 18:25:12 +01:00
export function getParentDomain(domain, domains, highest = false) {
2022-02-01 17:21:35 +01:00
const method = highest ? 'lastIndexOf' : 'indexOf'
let i = domain[method]('.')
while (i !== -1) {
const dn = domain.slice(i + 1)
if (domains.includes(dn)) return dn
i = domain[method]('.', i + (highest ? -1 : 1))
}
return null
}
export default {
state: () => ({
main_domain: undefined,
2022-02-01 17:21:35 +01:00
domains: undefined, // Array
domains_details: {},
users: undefined, // basic user data: Object {username: {data}}
users_details: {}, // precise user data: Object {username: {data}}
groups: undefined,
2024-02-24 18:25:12 +01:00
permissions: undefined,
}),
2020-07-27 20:46:27 +02:00
mutations: {
2024-02-24 18:25:12 +01:00
SET_DOMAINS(state, [{ domains, main }]) {
2020-07-16 16:30:19 +02:00
state.domains = domains
state.main_domain = main
2020-07-16 16:30:19 +02:00
},
2020-07-27 20:46:27 +02:00
2024-02-24 18:25:12 +01:00
SET_DOMAINS_DETAILS(state, [name, details]) {
Vue.set(state.domains_details, name, details)
},
2024-02-24 18:25:12 +01:00
UPDATE_DOMAINS_DETAILS(state, payload) {
// FIXME use a common function to execute the same code ?
this.commit('SET_DOMAINS_DETAILS', payload)
},
2024-02-24 18:25:12 +01:00
DEL_DOMAINS_DETAILS(state, [name]) {
Vue.delete(state.domains_details, name)
if (state.domains) {
Vue.delete(state.domains, name)
}
},
2024-02-24 18:25:12 +01:00
ADD_DOMAINS(state, [{ domain }]) {
2020-08-04 22:11:30 +02:00
state.domains.push(domain)
},
2024-02-24 18:25:12 +01:00
DEL_DOMAINS(state, [domain]) {
state.domains.splice(state.domains.indexOf(domain), 1)
},
// Now applied thru 'SET_DOMAINS'
// 'SET_MAIN_DOMAIN' (state, [response]) {
// state.main_domain = response.current_main_domain
// },
2024-02-24 18:25:12 +01:00
UPDATE_MAIN_DOMAIN(state, [domain]) {
state.main_domain = domain
},
2024-02-24 18:25:12 +01:00
SET_USERS(state, [users]) {
state.users = users || null
},
2020-07-27 20:46:27 +02:00
2024-02-24 18:25:12 +01:00
ADD_USERS(state, [user]) {
if (!state.users) state.users = {}
Vue.set(state.users, user.username, user)
},
2020-07-27 20:46:27 +02:00
2024-02-24 18:25:12 +01:00
SET_USERS_DETAILS(state, [username, userData]) {
Vue.set(state.users_details, username, userData)
2020-07-27 20:46:27 +02:00
if (!state.users) return
const user = state.users[username]
2022-10-09 17:00:48 +02:00
for (const key of ['fullname', 'mail']) {
2020-07-27 20:46:27 +02:00
if (user[key] !== userData[key]) {
Vue.set(user, key, userData[key])
}
}
},
2024-02-24 18:25:12 +01:00
UPDATE_USERS_DETAILS(state, payload) {
// FIXME use a common function to execute the same code ?
this.commit('SET_USERS_DETAILS', payload)
},
2024-02-24 18:25:12 +01:00
DEL_USERS_DETAILS(state, [username]) {
Vue.delete(state.users_details, username)
if (state.users) {
Vue.delete(state.users, username)
if (Object.keys(state.users).length === 0) {
state.users = null
}
}
},
2024-02-24 18:25:12 +01:00
SET_GROUPS(state, [groups]) {
state.groups = groups
},
2024-02-24 18:25:12 +01:00
ADD_GROUPS(state, [{ name }]) {
2020-08-02 14:23:25 +02:00
if (state.groups !== undefined) {
Vue.set(state.groups, name, { members: [], permissions: [] })
}
},
2024-02-24 18:25:12 +01:00
UPDATE_GROUPS(state, [data, { groupName }]) {
Vue.set(state.groups, groupName, data)
},
2024-02-24 18:25:12 +01:00
DEL_GROUPS(state, [groupname]) {
2020-08-02 15:34:38 +02:00
Vue.delete(state.groups, groupname)
},
2024-02-24 18:25:12 +01:00
SET_PERMISSIONS(state, [permissions]) {
state.permissions = permissions
},
2024-02-24 18:25:12 +01:00
UPDATE_PERMISSIONS(state, [_, { groupName, action, permId }]) {
// FIXME hacky way to update the store
const permissions = state.groups[groupName].permissions
if (action === 'add') {
permissions.push(permId)
} else if (action === 'remove') {
const index = permissions.indexOf(permId)
if (index > -1) permissions.splice(index, 1)
}
2024-02-24 18:25:12 +01:00
},
},
2020-07-27 20:46:27 +02:00
actions: {
2024-02-24 18:25:12 +01:00
GET(
{ state, commit, rootState },
2024-02-24 18:25:12 +01:00
{
uri,
param,
storeKey = uri,
humanKey,
noCache,
options,
...extraParams
},
) {
const currentState = param ? state[storeKey][param] : state[storeKey]
2020-07-16 19:18:01 +02:00
// if data has already been queried, simply return
const ignoreCache = !rootState.cache || noCache || false
if (currentState !== undefined && !ignoreCache) return currentState
2024-02-24 18:25:12 +01:00
return api
.fetch('GET', param ? `${uri}/${param}` : uri, null, humanKey, options)
.then((responseData) => {
// FIXME here's an ugly fix to be able to also cache the main domain when querying domains
const data =
storeKey === 'domains'
? responseData
: responseData[storeKey]
? responseData[storeKey]
: responseData
commit(
'SET_' + storeKey.toUpperCase(),
[param, data, extraParams].filter((item) => !isEmptyValue(item)),
)
return param ? state[storeKey][param] : state[storeKey]
})
},
2024-02-24 18:25:12 +01:00
POST(
{ state, commit },
{ uri, storeKey = uri, data, humanKey, options, ...extraParams },
) {
return api
.fetch('POST', uri, data, humanKey, options)
.then((responseData) => {
// FIXME api/domains returns null
if (responseData === null) responseData = data
responseData = responseData[storeKey]
? responseData[storeKey]
: responseData
commit(
'ADD_' + storeKey.toUpperCase(),
[responseData, extraParams].filter((item) => !isEmptyValue(item)),
)
return state[storeKey]
})
2020-07-27 20:46:27 +02:00
},
2024-02-24 18:25:12 +01:00
PUT(
{ state, commit },
{ uri, param, storeKey = uri, data, humanKey, options, ...extraParams },
) {
return api
.fetch('PUT', param ? `${uri}/${param}` : uri, data, humanKey, options)
.then((responseData) => {
const data = responseData[storeKey]
? responseData[storeKey]
: responseData
commit(
'UPDATE_' + storeKey.toUpperCase(),
[param, data, extraParams].filter((item) => !isEmptyValue(item)),
)
return param ? state[storeKey][param] : state[storeKey]
})
},
2024-02-24 18:25:12 +01:00
DELETE(
{ commit },
{ uri, param, storeKey = uri, data, humanKey, options, ...extraParams },
) {
return api
.fetch(
'DELETE',
param ? `${uri}/${param}` : uri,
data,
humanKey,
options,
)
.then(() => {
commit(
'DEL_' + storeKey.toUpperCase(),
[param, extraParams].filter((item) => !isEmptyValue(item)),
)
})
},
2024-02-24 18:25:12 +01:00
RESET_CACHE_DATA({ state }, keys = Object.keys(state)) {
for (const key of keys) {
if (key === 'users_details') {
state[key] = {}
} else {
state[key] = undefined
}
}
2024-02-24 18:25:12 +01:00
},
},
2020-07-27 20:46:27 +02:00
getters: {
2024-02-24 18:25:12 +01:00
users: (state) => {
if (state.users) return Object.values(state.users)
return state.users
},
2020-10-23 18:15:41 +02:00
2024-02-24 18:25:12 +01:00
userNames: (state) => {
if (state.users) return Object.keys(state.users)
return []
2020-10-23 18:15:41 +02:00
},
2024-02-24 18:25:12 +01:00
user: (state) => (name) => state.users_details[name], // not cached
2020-10-30 13:58:44 +01:00
2024-02-24 18:25:12 +01:00
domains: (state) => state.domains,
2020-10-23 18:15:41 +02:00
2024-02-24 18:25:12 +01:00
orderedDomains: (state) => {
2022-02-01 17:21:35 +01:00
if (!state.domains) return
2024-02-24 18:25:12 +01:00
const splittedDomains = Object.fromEntries(
state.domains.map((domain) => {
// Keep the main part of the domain and the extension together
// eg: this.is.an.example.com -> ['example.com', 'an', 'is', 'this']
domain = domain.split('.')
domain.push(domain.pop() + domain.pop())
return [domain, domain.reverse()]
}),
)
return state.domains.sort(
(a, b) => splittedDomains[a] > splittedDomains[b],
)
2022-02-01 17:21:35 +01:00
},
domainsTree: (state, getters) => {
// This getter will not return any reactive data, make sure to assign its output
// to a component's `data`.
// FIXME manage to store the result in the store to allow reactive data (trigger an
// action when state.domain change)
const domains = getters.orderedDomains
if (!domains) return
2024-02-24 18:25:12 +01:00
const dataset = domains.map((name) => ({
2022-02-01 17:21:35 +01:00
// data to build a hierarchy
name,
parent: getParentDomain(name, domains),
// utility data that will be used by `RecursiveListGroup` component
to: { name: 'domain-info', params: { name } },
2024-02-24 18:25:12 +01:00
opened: true,
2022-02-01 17:21:35 +01:00
}))
return stratify(dataset)
},
2024-02-24 18:25:12 +01:00
domain: (state) => (name) => state.domains_details[name],
2022-02-01 17:21:35 +01:00
2024-02-24 18:25:12 +01:00
highestDomainParentName: (state, getters) => (name) => {
2022-02-01 17:21:35 +01:00
return getParentDomain(name, getters.orderedDomains, true)
},
2024-02-24 18:25:12 +01:00
mainDomain: (state) => state.main_domain,
2020-10-23 18:15:41 +02:00
2024-02-24 18:25:12 +01:00
domainsAsChoices: (state) => {
const mainDomain = state.main_domain
2024-02-24 18:25:12 +01:00
return state.domains.map((domain) => {
return {
value: domain,
text: domain === mainDomain ? domain + ' ★' : domain,
}
})
2024-02-24 18:25:12 +01:00
},
},
}