All Downloads are FREE. Search and download functionalities are using the official Maven repository.

components.view.utils.links.js Maven / Gradle / Ivy

import merge                             from 'deepmerge'
import { getTranslator }                 from 'hooks/translator'
import Report                            from 'helpers/report'
import Settings                          from 'helpers/settings'
import { decomposeRefPath }              from "utils/path"
import { isUrl }                         from "utils/utils"

export const getEnabledLinks = (links) => {
  if (Array.isArray(links))
    return links.filter(link => !link.hasOwnProperty('enabled') || link.enabled)
  else return []
}

export const createLabelLinks = (translator, context, runtimeLinks) => {
  return runtimeLinks.map(link => ({ label: toLinkLabel(translator, context, link) }))
}

export const createTipLinks = (translator, links, menuItems) => {
  return links.map(link => ({ tip: toLinkTip(translator, link, menuItems) }))
}

export const createOnClickHandler = (meta, link) => {
  if (!link.ref)
    notifier.error("A view link does not have a ref")

  const { key } = decomposeRefPath(link.ref)
  switch (toLinkType(link)) {
    case "external": return createExternalOnClick(meta, link.href || key)
    case "internal": return createInternalOnClick(meta, link.href || key)
    case "process":  return createProcessOnClick(meta, { key }, link.kind)
    default:         return createDefaultOnClick(meta)
  }
}

const createDefaultOnClick = (meta) => {
  return (_e) => meta.notifier.error("No link was set")
}

const createExternalOnClick = (_meta, href) => {
  return (e) => {
    e.preventDefault()
    window.location = href
  }
}

const createInternalOnClick = ({ navigate }, href) => {
  return (e) => {
    e.preventDefault()
    navigate(href)
  }
}

const createProcessOnClick = ({ startProcess }, pd, kind) => {
  switch (kind) {
    case 'PROCESS_OPEN':
      return (e) => {
        e.preventDefault()
        startProcess(e, pd, kind)
      }

    case 'PROCESS_FILL':
      return (e) => {
        e.preventDefault()
        startProcess(e, pd, kind)
      }

    case 'PROCESS_SUBMIT':
      return (e, valuesPromise) => {
        e.preventDefault()
        startProcess(e, pd, kind, valuesPromise)
      }

    default:
      alert("Unsupported link kind: " + JSON.stringify(kind))
  }
}

export const toLinkTip = (translator, runtimeLink, menuItems) => {
  switch (toLinkType(runtimeLink)) {
    case "external": 
      return translator.translate('view.drawer.link.href', {variables: {link: runtimeLink.href}})
    case "internal": 
      return toInternalTip(translator, runtimeLink, menuItems)
    case "process":  
      const { key: processKey } = decomposeRefPath(runtimeLink.ref)
      const label               = translator.toProcessTitle(processKey, runtimeLink.label)
      return translator.translate('view.drawer.link.process', {variables: {process: label}})
    default: return undefined
  }
}

const toInternalTip = (translator, link, menuItems) => {
  const href = link.href
  const info = menuItems.find(info => info.href == href)
  const variables = info ? { link: info.label } : { link: link.href }
  return translator.translate('view.drawer.link.href', { variables })
}

export const toLinkLabel = (translator, context, link) =>{
  if (context.context == "list") {
    if (context.parent == "contextmenu")
      return translator.toDetailLink(context.props.detailKey, link.key, link.label)
    else
      return translator.toListLink(context.props.listKey, link.key, link.label)
  } 
  else if (context.context == "detail")
    return translator.toDetailLink(context.props.detailKey, link.key, link.label)

  throw new Error("unexpected state")
}

export const toLinkType = (link) => {
  const href = link.href
  if (href) {
    return isUrl(href) ? "external" : "internal"
  } else {
    return decomposeRefPath(link.ref)?.domain
  }
}

export const prepareLinkFormValues = (client, notifier, request, path, kind) => {
  switch (kind) {
    case "PROCESS_FILL":
      return prepareProcessFillFormValues(client, notifier, request, path, kind)

    case "PROCESS_SUBMIT":
      return getLinkFormValues(client, notifier, request, path) 

    default:
      return new Promise(() => {})
  }
}

export const prepareProcessFillFormValues = (client, notifier, request, path, kind) => {
  return getLinkFormValues(client, notifier, request, path)
    .then(values => { storeFormValuesLocally(values, kind) })
}

function getLinkFormValues(client, notifier, request, path) {
  const { translator } = getTranslator()

  const success = result => {
    const formValues = _.get(result, path)
    if (formValues) {
      return formValues
    } else {
      console.error("Failed to get form values from result: %o", result)
      const report = Report.from(error, translator, { category: Report.backend })
      report.addToNotifier(notifier)
      return null
    }
  }

  const failure = error => {
    console.error("Failed to get form values: %o", error.message)
    notifier.error("Failed to get form values.")
  }

  const catchFailure = reason => {
    console.error("The frontend has an issue with retrieving form values: " + reason)
    notifier.error("Failed to get form values.")
  }

  return client
    .query(request)
    .then(success, failure)
    .catch(catchFailure)
}

export const storeFormValuesLocally = (formValues, kind) => {
  console.log("Store values for %s: %o", kind, formValues)
  Settings.session.write("FORM.VALUES", formValues)
  Settings.session.write("FORM.KIND", kind)
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy