Source: ressource/serviceRoutes.js


'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
  })
}