Customize the filter

This page describes the way you can customize filters of Fonto Review. The filter form, summary components and (DEV-)CMS are all described here.

You can create your own form UI for filtering the list of annotations (on the CMS side). You can create a component to use for the /editor and /review routes. You could change the form if desired by checking for the value of the injected productContext prop, which can be editor or review.

Whatever input you've given in the form is summarized as a horizontal list of FDS Chip components in the reference configuration. These chips are shown directly above the cards list in the sidebar after the user has set a filter value. You can choose to implement a different summary or a component that renders nothing at all, and you can change things based on productContext just like for the filter form.

The actual filtering is done by the CMS, via the /review/state endpoint. This endpoint receives the current filter form value by name mapping from the front-end, which comes from your custom filter form component: whatever fields you render in the filter form, will determine what is sent to the CMS. If you run your editor locally with FDT, and therefore you are using our dev-cms, you need to customize the filter logic used by the dev-cms as well. Our dev-cms is implemented in NodeJS so it needs a JavaScript implementation of the filter logic.

Customize the filter logic used by FDT (and its dev-cms)

You have to create a JS file at ./dev-cms/configureDevCms.js in your Editor (if you haven't done so already to customize the dev-cms routes).This file should look like this:

JavaScript

// Replace the path below with the path to your version of this package and your version of the
// matchAnnotationToCurrentFilter.js file.
const matchAnnotationToCurrentFilter = require('../packages/%this-or-your-custom-package-name%/src/matchAnnotationToCurrentFilter');

module.exports = (router, config) => {
	return {
		// This key is required, the name and path of your function can be anything you like.
		reviewAnnotationFilter: matchAnnotationToCurrentFilter
		// This key could also be here to customize the dev-cms routes.
		// routes: myCustomRoutes
	};
};

In the configureDevCms.js file we've now registered a custom function that is used to implement the filter logic based on your registered annotation types and your custom filter form UI.

The matchAnnotationToCurrentFilter.js file should implement a function like this:

JavaScript

module.exports = function matchAnnotationToCurrentFilter(filterFormValueByName, annotation) {
	return true;
}

It should return true if the given annotation matches the given filterFormValueByName mapping. The reference configuration contains an example of this code, you can find it here.

Create the filter form using FilterFormComponent

This component should render some sort of form to the user to allow them to filter the cards list. A FilterForm component is designed to work well with an FDS Form and FDS form fields, however, you can also use your own form/UI components.

Note: If you use your own form, take care to still correctly implement/respect all the given props. These help your form integrate with the rest of the /review UI. For example, there is no cancel or submit callback because that is standardized as the "Cancel" + "Set filters" buttons displayed above the filter form, which cannot be customized. They also handle the actual filtering by posting the filter form values to the /review/state endpoint and they pass the values to the FilterFormSummaryChipsComponent for each route.

The example in the reference configuration uses an FDS Form and as you'll see in the code, the props described below (almost) all translate directly towards props on FDS Form.

FilterFormComponent props

Name

Type

Description

error

Error

Errors occur as a result of a submitting the filter form (which also happens when removing one of the summary chips).

feedbackByName

object

A mapping of a form component id/name to its current feedback or null. This starts out as an empty object and will be filled after onInitialize is called and change whenever onFieldChange is called.

isDisabled

boolean

This is true while an annotation is loading/processing a data call or when an annotation has a non-idle busyState, eg. the edit or reply form is opened.

isSubmitting

boolean

This is true when the filter form is being submitted, use this do display a loading/submitting state.

onFieldChange

function({ name: string, value: object, feedback: object })

A callback that should be called whenever the value inside your form component changes.

Make sure it receives all 3 properties; name must be a string but value and feedback can contain whatever you like.

Set feedback to null if there is no feedback, otherwise you cannot submit the form.

onInitialize

function({ feedbackByName, valueByName })

A callback that can be called to initialize an (FDS) Form in one go (as opposed to separately for each field via onFieldChange. Make sure it receives either null or an object mapping for both keys.

Set feedbackByName to null, or to a mapping only containing null values, if there is no feedback, otherwise the user cannot submit the form (via the submit button in the filter form header).

productContext

string

Can be one of: "editor" or "review".

Optionally use this to make anything specific to a specific route/product/app context.

showFeedback

boolean

Whether or not you should display form feedback at this point.

Note: By default, an FDS form shows form feedback as a field changes (while the user changes it). For the fontoxml-feedback add-on, we chose to only display feedback after submitting a form. This is achieved by stripping any feedback from the given feedbackValueByName unless showFeedback is set to true. Which only happens after the form is submitted.

valueByName

object

A mapping of a form component id/name to its current value or default value.

This starts out as an empty object and will be filled after onInitialize is called and change whenever onFieldChange is called.

The FilterFormComponent must be registered in the uiManager in the install.js of a package like the example below.

JavaScript

import uiManager from 'fontoxml-modular-ui/src/uiManager.js';
import MyFilterForm from './MyFilterForm.jsx';

uiManager.registerReactComponent('FilterFormComponent', MyFilterForm);

Register a FilterFormComponent.

Create a summary of the filters using FilterFormSummaryComponent

This component should render some sort of summary to the user to allow them to quickly see what filter values are active without showing the full filter form UI. It could also quickly make edits to the filter form (as shown in this example by providing a remove "x" button for each chip to remove the corresponding filter form value.)

FilterFormSummaryComponent props

Name

Type

Description

error

Error

Errors occur as a result of a submitting the filter form (which also happens when removing one of the summary chips, see the source code for more details TODO LINK).

feedbackByName

object

A mapping of a form component id/name to its current feedback or null.

isSubmitting

boolean

This is true when the filter form is being submitted or when a chip is removed, use this to display a loading/submitting state.

onChange

function(valueByName, feedbackByName)

A callback that should be called whenever you want to change a filter form value from within the summary.

Make sure it receives an object mapping for valueByName containing all the other values, you have to copy (...spread) them from the given valueByName prop.

Omit feedbackByName or set it to null, or to a mapping only containing null values, if there is no feedback, otherwise the user cannot submit the form (via the submit button in the filter form header).

productContext

string

Can be one of: "editor" or "review".

Optionally use this to make anything specific to a specific route/product/app context.

showFeedback

boolean

Whether or not you should display form feedback at this point.

Note: By default, an FDS form shows form feedback as a field changes (while the user changes it). For the fontoxml-feedback add-on, we chose to only display feedback after submitting a form. This is achieved by stripping any feedback from the given feedbackValueByName unless showFeedback is set to true. Which only happens after the form is submitted.

valueByName

object

A mapping of a form component id/name to its current value or default value.

The FilterFormSummaryComponent must be registered in the uiManager in the install.js of a package like the example below.

JavaScript

import uiManager from 'fontoxml-modular-ui/src/uiManager.js';
import MyFilterFormSummary from './MyFilterFormSummary.jsx';

uiManager.registerReactComponent('FilterFormSummaryComponent', MyFilterFormSummary);

Register a FilterFormSummaryComponent.

Set the initial values for your custom FilterForm

Call setInitialFilterFormValues in your install.js file. Give it a valueByName object for each of the filter forms (/editor and /review).

Note: Make sure the keys match the names of the form fields (onFieldChange({ name: 'X' ... })).

This package provides an example that initializes the filter to only show unresolved annotations. This works together with the example FilterForm(Summary) and example reviewAnnotationFilter.