'use strict'
const { hasProp } = require('sesajstools')
const { getBaseUrl, getComponents } = require('sesatheque-client/dist/server/sesatheques')
const appConfig = require('../config')
const myBaseId = appConfig.application.baseId
const routes = appConfig.components.ressource.constantes.routes
module.exports = function (component) {
component.service('$routes', function ($accessControl) {
/**
* Service pour récupérer les routes d'affichage des ressources
* @service $routes
*/
const $routes = {}
/**
* Retourne url complétée avec du (?|&)key=value (encode value au passage)
* @param {string} url
* @param {string} key
* @param {string|number} value
* @return {string}
*/
$routes.addParam = function addParam (url, key, value) {
url += (url.indexOf('?') === -1) ? '?' : '&'
url += key + '=' + encodeURIComponent(value)
return url
}
/**
* Retourne la route (sans préfixe de controleur ni slash de début) d'une action
* Les arguments supplémentaires sont concaténé avec /
* @memberOf $routes
* @param {string} action
* @returns {string} La route
*/
$routes.get = function (action) {
let route = routes[action]
for (let i = 1; i < arguments.length; i++) {
if (arguments[i]) route += (route ? '/' : '') + arguments[i]
}
return route
}
/**
* Retourne la route absolue (commence par /) d'une action (avec public ou ressource au début suivant la ressource)
* Les arguments supplémentaires sont concaténé avec /
* @memberOf $routes
* @param {string} action (display|describe|preview)
* @param {Ressource|string} [ressource] ressource ou oid ou rid
* @param {Context} [context] pour vérifier que l'on est authentifié
* @returns {string} La route absolue
*/
$routes.getAbs = function (action, ressource, context) {
let route
if (hasProp(routes, action)) {
route = '/'
let id
let isPublic = true
if (ressource) {
let rid
if (typeof ressource === 'string' && ressource.indexOf('/') !== -1) {
rid = ressource
} else if (typeof ressource === 'object') {
// si c'est un alias, on veut la destination seulement pour afficher la ressource,
// (c'est l'alias qu'on veut décrire ou modifier)
if (ressource.aliasOf && (action === 'display' || action === 'preview')) rid = ressource.aliasOf
else rid = ressource.rid
} else {
id = ressource
}
if (rid) {
const [baseId, oid] = getComponents(rid)
if (baseId !== myBaseId) route = getBaseUrl(baseId)
id = oid
}
if (!id) {
log.dataError('ressource invalide', ressource)
// on plante pas pour ça mais on arrête là
return route
}
if (ressource.restriction || $accessControl.isAuthenticated(context)) isPublic = false
} else if (context && $accessControl.isAuthenticated(context)) {
isPublic = false
}
if (action === 'api') route += 'api/' // pour l'api faut ajouter un préfixe
// ce qui concerne l'édition est toujours sur /ressource
if (['create', 'delete', 'edit'].indexOf(action) > -1) route += 'ressource/'
else route += isPublic ? 'public/' : 'ressource/'
// on ajoute l'oid éventuel
route += $routes.get(action, id)
} else {
log.error(new Error('appel de $routes.getAbs avec une action non gérée : ' + action))
}
// log.debug(`getAbs ${action} va retourner ${route}`)
return route
}
/**
* Retourne un tag html a avec une url locale absolue (qui commence avec /)
* @memberOf $routes
* @param actionName
* @param ressource
* @param {string} [label=ressource.nom] Le texte du lien
* @returns {string} Le code html du lien
*/
$routes.getTagA = function (actionName, ressource, label) {
let html
const route = $routes.getAbs(actionName, ressource)
if (route) {
html = '<a href="' + route + '">'
html += label || ressource.titre || 'sans titre'
html += '</a>'
}
return html
}
return $routes
})
}