e1-bsd/omni-common-ui

View on GitHub
src/domain/BreadcrumbsBuilder/index.js

Summary

Maintainability
A
1 hr
Test Coverage
import log from 'domain/log';
import is from 'is_js';

const ACCEPTABLE_LABELS_TYPES = new Set(['string', 'object', 'function']);
const ALWAYS_APPLIED_PARAMS = { mode: '' };

export default {
  buildWithProps: (props) => {
    const { params, routes, buildRoute } = props;

    const getRouteSegments = () =>
      routes.filter((route) => is.string(route.path));

    const buildRouteHref = (toRouteIdx) => {
      const paths = getRouteSegments()
        .slice(0, toRouteIdx + 1)
        .map((route) => route.path);
      const path = paths.join('/');
      return buildRoute(path,
          Object.assign({}, params, ALWAYS_APPLIED_PARAMS || {}));
    };

    const breadcrumbs = [];

    getRouteSegments().forEach((routeDescriptor, routeIdx) => {
      let labels = routeDescriptor.breadcrumbLabels;
      if (! ACCEPTABLE_LABELS_TYPES.has(typeof labels)) return;
      if (is.function(labels)) {
        try {
          labels = labels(props);
        } catch (err) {
          log.warn(`Error in \`breadcrumbLabels\` in route \`${routeDescriptor.path}\``, err);
        }
      }
      labels = is.array(labels) ? labels : [labels];
      Array.prototype.push.apply(breadcrumbs,
        labels.filter((l) => l).map((labelOrObject) => ({
          label: labelOrObject.label || labelOrObject,
          href: labelOrObject.href || buildRouteHref(routeIdx),
          clickable: is.boolean(labelOrObject.clickable) ? labelOrObject.clickable : true,
          backLinkHref: is.string(labelOrObject.backLinkHref) ? labelOrObject.backLinkHref : null,
        })));
    });

    // the last one shouldn't be clickable
    if (breadcrumbs.length > 1) {
      breadcrumbs[breadcrumbs.length - 1].clickable = false;
    }

    return breadcrumbs;
  },
};