Skip to content

Instantly share code, notes, and snippets.

@qmateub
Last active April 16, 2019 09:30
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save qmateub/bb818007b1279835da8c018bcb6d6237 to your computer and use it in GitHub Desktop.
Save qmateub/bb818007b1279835da8c018bcb6d6237 to your computer and use it in GitHub Desktop.

Custom fields

Description

A component for rendering UIs based on attrbiuteDefinitions or typeDefinitions.

What is a type definition? https://docs.commercetools.com/http-api-projects-types

What is an attribute definition? https://docs.commercetools.com/http-api-projects-productTypes#attributedefinition

Requirements

This component was made taking into account some technical decisions that we will explain later on, but for good usage this component needs:

Usage

import { CustomFields } from '@commercetools-local/core/components/custom-fields';

<CustomFields
  languages={this.props.languages}
  currencies={this.props.currencies}
  language={this.props.language}
  fieldDefinitions={definitions}
  values={attributesValues}
  errors={formikProps.errors}
  onChange={formikProps.handleChange}
  onBlur={formikProps.handleBlur}
/>

Properties

Props Type Required Description
languages Array languages for the localized inputs
currencies Array currencies for the money types
language String language for localized inputs
fieldDefinitions Array Definitions for rendering inputs depending on the type/attribute
values Array values for the definitions
errors Object - errors in case the UI is a form
onChange func - Called with an event holding the new value. Required when input is not read only. Parent should pass it back as value-
onBlur func - Called when field is blurred
isDisabled bool - Render the component in disabled mode
isReadOnly bool - Render the component in read only mode

Technical decisions

  • The idea here is to treat product.attributes as they are customFields. Given this, we have a single resource requiring mapping from attributes -> customFields
  • The more resource types (e.g Store) we add in the API, its customFields requires no mapping anymore.
  • The implementation is attached to the usage of Formik as FieldArray plays an important role for set types.
  • The component do NOT support for now nested attributes nor nested definitions (Set of sets)
  • When passing the values to the component (look values prop), is needed to provide the whole entity containing the custom fields (eg LineItem, Order, Channel, etc). In other words, you cannot pass the values directly as the component is made under the assumption that custom.fields exists.
+--------------------+                           +--------------------+
|                    |                           |                    |
| ProductDetails     |                           | *Details           |
|                    |                           |                    |
+--------------------+                           +--------------------+
          |                                                |
          |                                                |
          |                                                |
          |                                                |
          |                                                |
          |                                                |
+---------v----------+                           +---------v----------+
|                    |                           |                    |
| ProductAttributes  +--map to custom fields-----> CustomFields       |
|                    |                           |                    |
+-----------------^--+                           +--------------------+
                  |                                        |
                  |                                        |
                  |                                        |
                  +-----map to attributes------------------+

The relation between types/attributes and UIKit inputs are:

Type Input Notes
text TextInput In case is multiline we render MultilineTextInput
number NumberInput -
localizedstring, ltext LocalizedTextInput In case is multiline we render LocalizedMultilineTextInput
money MoneyInput -
boolean SelectInput -
enum, localizedenum, lenum SelectInput -
reference TextInput In case the resource is for a category we use an AsyncSelectInput
time TimeInput -
datetime DateTimeInput -
date DateInput -

In the case of set types we use a combination of the inputs above with FieldArray from Formik for handling array values. The only exception is for set of localizedstring, ltext as its designs is WIP.

This component also contains two utilities that are needed in case we want:

Conversions (required)

import { parseCustomFieldsValues } from  '@commercetools-local/core/components/custom-fields';
...
...
this.props.orderUpdater.execute(formValuesToDoc(parseCustomFieldsValues(orderDraft)))

Specific conversions are needed specially for the set types so the empty values are filtered out when sending the request to CTP.

Validation (optional)

import { validateCustomFields } from  '@commercetools-local/core/components/custom-fields';
....
....
<Formik
  validate={formValues => validateCustomFields(formValues, this.props.language)}
  ...
/>

Measure of completion

This component is now present in:

  • Orders custom fields tab
  • Orders Line Items modal (custom fields and attributes)
  • Customers custom fields tab
  • Channels custom fields tab
  • Categories custom fields
  • Product attributes (variant attributes)
  • Price Custom fields

Long terms & ideas

  • Add this component to application-kit so user can reuse this for custom applications
  • Add animation for expanding/collapse array values
  • Render boolean types with checkboxes instead of with SelectInput
  • Add unit tests
  • Add integration test
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment