import { Meta, Canvas, ArgsTable, Description } from '@storybook/addon-docs'
import { Source } from '@storybook/addon-docs'
import RenderWithTheme from 'theme/RenderWithTheme'

import ListMaker from '../index'
import { EXTRA_STRUCTURE, DATA_STRUCTURE } from './data'
import { listMakerExtraData, listMakerMockData } from 'utils/dataSet'

<Meta
  title="Specific Component/ListMaker/Documentation"
  component={ListMaker}
  parameters={{ transcludeMarkdown: true }}
/>

# ListMaker Documentation

ListMaker is a fully configurable data display component that follows a list style approach to show different kinds of key and value pairs.

This documentation is meant to explain all the different properties that we can configure on this component.

<h2>List of properties</h2>
An exhaustive list of all the properties available for listmaker. Please see the
examples below for more concrete examples of their usage.

<table>
  <thead>
    <tr>
      <th>Property</th>
      <th>Type</th>
      <th>Description</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>properties</td>
      <td>Array</td>
      <td>
        Includes property objects that can be used to express values from the
        <b>"data"</b> prop
      </td>
    </tr>
    <tr>
      <td>items</td>
      <td>Array</td>
      <td>
        Includes item objects that can be used to fetch relation data from the
        <b>"extra"</b> prop. You can use this object recursively to follow complex
        relations
      </td>
    </tr>
    <tr>
      <td>property</td>
      <td>Object</td>
      <td>
        A property is an object containing information about what label to show
        and to which data key we want to point to
      </td>
    </tr>
    <tr>
      <td>label</td>
      <td>String</td>
      <td>
        The text key of a line, may be templated with <b>${'{dataKey}'}</b> if
        you wish to use text coming from your data set
      </td>
    </tr>
    <tr>
      <td>key</td>
      <td>String</td>
      <td>
        The path or pointer to the data you want to use for a given label. For a
        complext object you may chain the property names like{' '}
        <b>displayData.lastname</b> for example
      </td>
    </tr>
    <tr>
      <td>template</td>
      <td>String</td>
      <td>
        This property allows you to template data sets with custom text such as{' '}
        <b>Hi, my name is ${'{displayData.firstName}'}</b>. You may use as many
        templates as you wish for as long as the data is available on the
        <b>"data"</b> prop
      </td>
    </tr>
    <tr>
      <td>formatter</td>
      <td>String</td>
      <td>
        The name of a formatting function available through the{' '}
        <b>formatters</b> prop. To be used in conjunction with a <b>key</b>{' '}
        property. Allows you to format, for example, an ISO date into a more
        standard one.
      </td>
    </tr>
    <tr>
      <td>renderer</td>
      <td>String</td>
      <td>
        The name of a renderer function available through the <b>renderers</b>{' '}
        prop. This function has access to all the data within the <b>data</b>{' '}
        prop.
      </td>
    </tr>
    <tr>
      <td>values</td>
      <td>Array</td>
      <td>
        Group of multiple properties that is useful when you want to show data
        such as an address which is composed of different data sets but that
        ultimately are needed to be visually close.
      </td>
    </tr>
    <tr>
      <td>relation</td>
      <td>String</td>
      <td>
        The name of the relation that is found within the <b>relations</b>{' '}
        property in the <b>extra</b> prop.
      </td>
    </tr>
    <tr>
      <td>direction</td>
      <td>String</td>
      <td>
        The direction of the relation specified by the <b>relation</b> property.
        The default value is "in" which means that for example,
        "NATURAL_PERSON_HAS_ADDRESS" will find the address of the entity found
        in the <b>data</b> prop using the "oid" property that is found within.
        In contrast, the "out" option would fetch the Natural Person itself.
      </td>
    </tr>
    <tr>
      <td>optional</td>
      <td>Boolean</td>
      <td>
        Whether you want to display a property whose key is undefined or null.
      </td>
    </tr>
    <tr>
      <td>columns</td>
      <td>Integer, Object</td>
      <td>
        Columns is used to adapt the list to a different disposition on a given
        screen's available width. By the default, the value is 12 which means
        each property/line occupies the full width of the parent's component. If
        you only specify an integer, it will be assigned to every screen
      </td>
    </tr>
    <tr>
      <td>multiline</td>
      <td>Boolean, String</td>
      <td>
        This property allows you to change the overflow of a property's text.
        When using a boolean, it will allow the full text of both the label and
        the value. You may also specifiy, as a string, if you want only the
        "value" or the "label" to be multiline.
      </td>
    </tr>
    <tr>
      <td>labelWidth</td>
      <td>Integer</td>
      <td>
        The label width specifies the total width of the list's label, allowing
        you to control how much width you need for a given line. By default,
        this value is 50.
      </td>
    </tr>
    <tr>
      <td>labelAlign</td>
      <td>String</td>
      <td>
        To be used in conjuction with a label. Not supported within properties.
        View{' '}
        <a
          target="_blank"
          href="https://developer.mozilla.org/en-US/docs/Web/CSS/text-align"
        >
          mdm web docs
        </a>{' '}
        for more information.
      </td>
    </tr>
    <tr>
      <td>maxEntities</td>
      <td>Integer</td>
      <td>
        How many entities are shown directly on the list from the <b>items</b>{' '}
        property. If a relation finds 5 different entities but you specifiy{' '}
        <b>maxEntities</b> to 3, the 2 others will be hidden under a "View more"
        button.
      </td>
    </tr>
    <tr>
      <td>maxProps</td>
      <td>Integer</td>
      <td>
        How many properties are shown directly on the list from the{' '}
        <b>properties</b> property. If you specifiy 5 different properties but
        you specifiy <b>maxProps</b> to 3, the 2 others will be hidden under a
        "View more" button.
      </td>
    </tr>
    <tr>
      <td>fallback</td>
      <td>Object</td>
      <td>
        To be used within the "items" object. Allows listmaker to show a message
        when no entities are found. Within this object, the <b>label</b> and
        <b>labelAlign</b> properties may be used.
      </td>
    </tr>
  </tbody>
</table>

<h2>Standard data structure</h2>
ListMaker is by default a component that works directly with our MDM Graph Data structure.
There are 2 different data entries for the ListMaker component. The <b>
  data
</b> prop that usually contains an entity's data and the <b>extra</b> prop which
contains data for all entities and their relations for a given entity. While it can
work with custom data, it's best used with the following standard data structure:
<br />
<br />

<h3>
  <i>data</i> prop object
</h3>
The data prop object is often a singular entity object that was fetched from the
MDM. The data object may be any data structure as it does not rely on any relation
logic to fetch a given entity, allowing us to use pretty much any object we wish
to display data.
<Source language="json" code={DATA_STRUCTURE} />

<h3>
  <i>extra</i> prop object
</h3>
In order for the extra prop object to work seamlessly, the <b>entities</b> and <b>
  relations
</b> properties must be present. An entity must always have an oid so that the relation
fetcher knows to which entity we are pointing to. A relation must always have a startEntityOid
and an endEntityOid. When working with relation based data with the <b>items</b> property,
you have access to the relation object by pointing to the injected relation object
within the configuration.
<Source language="json" code={EXTRA_STRUCTURE} />

<h2>Examples</h2>
In this section we will go through different means of implementation for this component.
Most of the examples use the data shown above.

<h2>Use of the properties with custom data</h2>
Here we solely use the <b>properties</b> property alongside some custom data. An
undefined key/value pair was set up for "Clearly undefined data" to show how ListMaker
reacts.

<Canvas>
  <RenderWithTheme>
    <ListMaker
      conf={{
        properties: [
          { label: 'Greeting label', key: 'hi' },
          { label: 'Deeply nested data', key: 'deep.objectName.keyName' },
          {
            label: 'Clearly undefined data',
            key: 'deep.objectName.keyDoesntExist',
          },
        ],
      }}
      data={{
        hi: 'Hello there',
        deep: { objectName: { keyName: 'This is a key name' } },
      }}
    />
  </RenderWithTheme>
</Canvas>

<h2>Use of the items with a single property</h2>
In this example <b>properties</b> property alongside some custom data.

<Canvas>
  <RenderWithTheme>
    <ListMaker
      conf={{
        properties: [{ label: 'Firstname', key: 'displayData.firstName' }],
        items: [
          {
            relation: 'HAS_ID_DOCUMENT',
            direction: 'in',
            properties: [
              {
                label: 'Document type',
                key: 'displayData.documentType',
              },
            ],
          },
        ],
      }}
      data={listMakerMockData}
      extra={listMakerExtraData}
    />
  </RenderWithTheme>
</Canvas>
