primo-explore-custom-requests

1.0.5 • Public • Published

primo-explore-custom-requests

Customized item requests in Primo NUI

CircleCI Coverage Status npm version

Usage

  1. Install yarn add primo-explore-custom-requests --dev
  2. Add as an angular dependency
let app = angular.module('viewCustom', [
  //... other dependencies
  'primoExploreCustomRequests',
]);
  1. Add components to appropriate prmAfter components:
app
  // 1. Inject in the <prm-location-item-after> component of the DOM, which exists after each holding entry WITHIN a specific location.
  .component('prmLocationItemAfter', {
    template: `<primo-explore-custom-requests></primo-explore-custom-requests>`,
      // 1a. Use this trick to implement the customization as a SIBLING of the item details, as opposed to its CHILD. Otherwise, styling of injected components will not match the styling of the elements it intends to replace. The CSS that has been included with the module will assume that this has been implemented.
    controller: ['$element', function($element) {
      const ctrl = this;
      ctrl.$postLink = () => {
        const $target = $element.parent().query('div.md-list-item-text');
        const $el = $element.detach();
        $target.append($el);
        $element.addClass('layout-row flex-sm-30 flex-xs-100');
      };
    }]
  })
  // 2. Optional: Inject the <primo-explore-custom-login> peer dependency in order to capture currently logged in user via PDS
  .component('prmUserAreaExpandableAfter', {
    template: `<primo-explore-custom-login></primo-explore-custom-login>`
  })
  1. Configure
app
  .constant('primoExploreCustomRequestsConfig', {
    // ... my large configuration object
  })

See configuration schema

If using <primo-explore-custom-login>, be sure to configure this as well according to that module's documentation.

Configuration Schema

name type usage
buttonIds Array List of keys that for conditionally rendered buttons.
buttonGenerators Object Key-value reference of functions used generate button properties for custom buttons.
noButtonsText String (optional) Message to show if no buttons were generated from buttonGenerators, the default buttons are hidden, and the PDS user API didn't fail. Default: Request not available.
userFailureText String (optional) Message to show if the user API fetch failed. Default: Unable to retrieve request options.
userLoadingText String (optional) Message to show while user API fetch is in-progress. Default: Retrieving request options....
hideDefaultRequests Function (optional) Used to determine whether to hide any default, out-of-the-box request buttons for specific holdings within a location. Functions return an array of booleans. Default: hide none ([false, false, false...]).
showCustomRequests Object (optional) Used to determine whether to show a specific custom request button for specific holdings within a location. Functions return an array of booleans. Default: shows all ([true, true, true...]).
values Object (optional) Dictionary used for arbitrary data and utility functions that may be used in other aspects of your configuration.

config.buttonIds

Example

{
  buttons: ['login', 'ezborrow', 'ill']
}

config.buttonGenerators

Keys refer to buttonIds.

Functions take the following named parameters via a POJO:

  • item: $ctrl.item object from the <prm-location-items> controller
  • config: The configuration object itself for internal references.
  • user: Object representation of a PDS user as taken from the primoExploreCustomLoginService. undefined if when user is not logged in, or the optional peer dependency has not been installed. null if a user is logged in, but the PDS API fetch failed.

Functions should be pure and return an Object with the following schema:

  • label: The button text
  • href: Opens link in a new window when button is clicked.
  • action: Performs custom JS, with access to angular's $injector object.
  • prmIconBefore: Optionally adds icon before the action.
  • prmIconAfter: Optionally adds icon after the action.

prmIcon schema: Object that defines the icon for the link. Must be chosen from https://material.io/icons/. Needs to specify both the name of the action "set" (see link) and the icon itself, in the form "ic_person_outline_24px". Note that all icons do not work so you may have to experiment some. You can also inspect existing Primo icons for insipration and consistency. "attributes" accepts an object which leverages existing attributes for better styling.

{
  label: `My button`
  href: `http://example.com`,
  action: ($injector) => $injector.get('$window').alert('The button was pushed!'),
  prmIconBefore: {
    set: "primo-ui",
    icon: "sign-in",
    attributes: { 'custom-requests': '' },
  },
}

For example:

{
  buttonGenerators: {
    ill: ({ item, config }) => ({
      href: `${config.values.baseUrls.ill}?${item.delivery.GetIt2.link.match(/resolve?(.*)/)}`,
      label: 'Request ILL',
      prmIconAfter: {
        icon: "ic_open_in_new_24px",
        set: "action",
        attributes: { 'custom-requests': '' },
      }
    }),
  },
}

config.hideDefaultRequests (optional)

Determines whether to hide default buttons/text on a per-item basis. By default, hides none.

A function which takes the following named parameters via a POJO:

  • user: Object representation of a PDS user as taken from the primoExploreCustomLoginService. undefined if when user is not logged in, or the optional peer dependency has not been installed. null if a user is logged in, but the PDS API fetch failed.
  • items: the array of items in $ctrl.currLoc.items from the <prm-location-items> component.
  • config: The configuration object itself for internal references.

Functions should have no side-effects and return an Array of Booleans that correspond to each holding in items. For example, to hide the default request actions of only the second of three holdings, return [false, true, false].

hideDefaultRequests: ({ items, config, user }) => {
  if (user === undefined) {
    return items.map(() => true);
  }

  const { checkAreItemsUnique, checkIsAvailable } = config.values.functions;

  const availabilityStatuses = items.map(checkIsAvailable);
  const itemsAreUnique = checkAreItemsUnique(items);
  const allUnavailable = availabilityStatuses.every(status => status === false);

  return availabilityStatuses.map(isAvailable => allUnavailable || (itemsAreUnique && !isAvailable));
}

config.showCustomRequests (optional)

Determines whether to show the custom buttons/text on a per-holding basis. By default, shows all.

Keys refer to buttonIds.

Each function takes the following named parameters via a POJO:

  • user: Object representation of a PDS user as taken from the primoExploreCustomLoginService. undefined if when user is not logged in, or the optional peer dependency has not been installed. null if a user is logged in, but the PDS API fetch failed.
  • items: An array of holdings data. $ctrl.currLoc.items from the <prm-location-items> component.
  • item: Record data. $ctrl.item object from the <prm-location-items> component.
  • config: The configuration object itself for internal references.

Functions should have no side-effects and return an Array of Booleans that correspond to each element in items. For example, to show the custom request actions for only the second of three holdings, return [false, true, false].

showCustomRequests: {
  login: ({ user, items }) => items.map(() => user === undefined),
  afc: ({ item, items, config, user}) => {
    if (!user) return items.map(() => false);
    const afcEligible = config.values.authorizedStatuses.afc.indexOf(user['bor-status']) > -1;
    const isBAFCMainCollection = item.delivery.holding.some(({ subLocation, libraryCode}) => {
      return libraryCode === "BAFC" && subLocation === "Main Collection";
    });

    return items.map(() => afcEligible && isBAFCMainCollection);
  }
},

config.noButtonsText (optional)

The text to show when no buttons are rendered. By default, renders Request not available

Note: Has access to custom backoffice values via {backoffice.key.value} syntax:

{
  noButtonsText: '{item.request.blocked}',
}

config.userFailureText (optional)

The text to show when no buttons are rendered. By default, renders Unable to retrieve request options

Note: Has access to custom backoffice values via {backoffice.key.value} syntax.

{
  userFailureText: '{item.request.failure}',
}

config.userLoadingText (optional)

The text to show when no buttons are rendered. By default, renders Retrieving request options...

Note: Has access to custom backoffice values via {backoffice.key.value} syntax:

{
  userLoadingText: '{item.request.loading}',
}

config.values (optional)

A dictionary of arbitrary functions and values to be referred to within your functions. This is useful for more complex logic that you may want to test against, or reuse in multiple functions.

Styles

/* Imitates prm-service-button styles */
button[class*="custom-request-"] {
  padding: .5em .35em !important;
}

/* Automatically shrinks empties on large view, overriding flex-sm-30  */
@media not all and (max-width: 599px) {
  prm-location-item-after {
    flex: 0 0 auto !important;
  }
}

/* On the smaller views, restores flex-grow */
@media (max-width: 599px) {
  primo-explore-custom-requests {
    flex: 1 1 100%;
  }
}

/* Useful for the 'attributes' in prmIconBefore/prmIconAfter to make it fit in button appropriately */
[custom-requests] md-icon {
  height: 15px;
  width: 15px;
  min-height: 15px;
  min-width: 15px;
  top: -1px;
  position: relative;
}

Readme

Keywords

Package Sidebar

Install

npm i primo-explore-custom-requests

Weekly Downloads

4

Version

1.0.5

License

MIT

Unpacked Size

47.2 kB

Total Files

8

Last publish

Collaborators

  • etgrieco