[wip] Reconfigure - bettyblocks/cli GitHub Wiki

Add child

With the add child option it is possible to define a set of prefabs (which can be added by the pagebuilder user) to a parent component.

For example, a dataTableColumn (child) to a dataTable (parent)

To define the children, you can create a variable in the structure options the like this:

  const childrenArray = [
    DataTableColumn({
      options: {
        ...dataTableColumnOptions,
        property: property('Property', {
          value: '',
          showInAddChild: true,
        }),
      },
    }),
  ],

Make sure that the DatableColumn and the dataTableColumnOptions are imported from structures like this:

  import { DataTableColumn } from '../../DataTableColumn';
  import { dataTableColumnOptions } from '../../DataTableColumn/options';

And property is imported from the @betty-blocks/component-sdk package like this:

  import { property } from '@betty-blocks/component-sdk';

To show the add child option in the component's options, you can add the addChild option to the structure's options.

First make sure that addChild is imported from the @betty-blocks/component-sdk package like this:

  import { addChild } from '@betty-blocks/component-sdk';

Then add the option like this:

  addChild: addChild('Add Column', {
    value: { children: childrenArray, addChildWizardType: 'ChildSelector' },
  }),

An example of the addChild can be found in the material-ui-component-set datatable: src/prefabs/structures/DataTable/options/index.ts


AddChildWizardType

The addChildWizardType determines what kind of modal should be opened. Currently it is possible to use the PropertySelector or the ChildSelector.

PropertySelector

This opens a modal with a property to select. For this modal it's required to have a parent component with a model selected (datacontainer, datatable) or else you cannot select a property.

ChildSelector

This opens a modal with options marked with the showInAddChild key. Any option of the defined child can be shown here.


Reconfigure

To reconfigure the children in the parent, you can enable this with the reconfigure option. This gives the user a clear overview of all children in the parent.

  const childrenArray = [
    DataTableColumn({
      options: {
        ...dataTableColumnOptions,
        property: property('Property', {
          value: '',
          showInReconfigure: true,
        }),
      },
    }),
  ],

Make sure that the DatableColumn and the dataTableColumnOptions are imported from structures like this:

  import { DataTableColumn } from '../../DataTableColumn';
  import { dataTableColumnOptions } from '../../DataTableColumn/options';

And property is imported from the @betty-blocks/component-sdk package like this:

  import { property } from '@betty-blocks/component-sdk';

To show the reconfigure option in the component's options, you can add the reconfigure option.

First make sure that reconfigure is imported from the @betty-blocks/component-sdk package like this:

  import { reconfigure } from '@betty-blocks/component-sdk';

Then add the option like this:

  reconfigure: reconfigure('Reconfigure', {
    value: { children, reconfigureWizardType: 'PropertiesSelector' },
  }),

reconfigureWizardType

To show a modal for displaying the reconfigure, a reconfigureWizardType must be described. This determines what kind of modal should be opened. Currently it is only possible to use PropertiesSelector or ChildrenSelector.

PropertiesSelector

This shows a modal where the user can only select properties of the selected model of the parent component.

ChildrenSelector

This shows a modal that displays a list of children and their options. These options can be marked with the key showInReconfigure:


Wrapper in reconfigure

The ChildrenSelector and the ChildSelector can also handle a wrapper as a child.

The children array would look like this:

  const childrenArray = [
    wrapper(
      {
        label: 'Wrapper',
        options: {
          buttonText: linked({
            label: 'Button text',
            value: {
              ref: {
                componentId: '#button',
                optionId: '#buttonText',
              },
            },
            showInReconfigure: true,
            showInAddChild: true,
          }),
        },
      },
      [
        Box({}, [
          Button(
            {
              ref: { id: '#button' },
              options: {
                ...buttonOptions,
                buttonText: variable('Button text', {
                  value: ['Button'],
                  ref: { id: '#buttonText' },
                }),
              },
            },
            [],
          ),
        ]),
      ],
    ),
  ],

And the options like this:

  reconfigure: reconfigure('Reconfigure', {
    value: { children: childrenArray, reconfigureWizardType: 'ChildrenSelector' },
  }),
  addChild: addChild('Add Wrapper', {
    value: { children: childrenArray, addChildWizardType: 'ChildSelector' },
  }),

OptionRef

To have options inherit meta data (label, name) of a model property you can use the optionRef key on a property option and target options like this:

Linked property option on a wrapper:

  property: linked({
    label: 'Question',
    value: {
      ref: {
        componentId: '#dropdownInput',
        optionId: '#dropdownInputProperty',
      },
    },
    optionRef: { 
      id: '#dropdownInputPropertyRef', // this will be the identifier of the option which sets a value to distribute to options with the same id as sourceId
    },
    configuration: {
      showOnDrop: true,
    },
  }),

The original property option:

  property: property('Question', {
    value: '',
    ref: {
      id: '#dropdownInputProperty',
    },
    showInAddChild: true,
  }),

In the target option:

  label: variable('Label', {
    value: [''],
    ref: { id: '#dropdownInputLabel' },
    optionRef: {
      sourceId: '#dropdownInputPropertyRef', // this sourceId is the same as the optionRef id defined in the linked option above
      inherit: 'name', // the name of the model property will be used to set the value of the label
    },
    configuration: {
      allowPropertyName: true,
    },
  }),

Now, when you select a property and save the component via the addChild or onDrop, the name of the model property will be set in the variable option value.

The inherit key can have different values:

  • name: this will use the database name of the model property. In case of the id property. id will be set to the option value
  • label: this will use the name of the model property. In case of the id property, the value Id (with a capital letter) will be set to the option value

createProperty

If you want to create a new property via the onDrop/addChild modal of a component, you can add the createProperty key to the configuration of a property option like this:

  import { CreatePropertyKind } from '@betty-blocks/component-sdk';
  property: property('Question', {
    value: '',
    ref: { id: '#numberInputProperty' },
    configuration: {
      createProperty: {
        type: CreatePropertyKind.INTEGER,
      },
      allowedKinds: ['INTEGER', 'PRICE'],
      disabled: true,
    },
    showInAddChild: true,
  }),

This key will show an input field instead of the property selector with the option to switch to the property selector. When the user fills in this input, a new property will be created with that name.

When a user wants to select an existing property, allowedKinds will ensure he can only select the defined kinds INTEGER or PRICE in this case.

createAction

To create a new action via the onDrop/addChild modal, you can add the createAction key to the ACTION_JS option. This will create a new action with an update step and permissions inherited from the page. When there are multiple property options on the same component, these will be added to the action as input variables and the assigned in the update step.

  component(
    'Form',
    {
      ref: { id: '#checkboxQuestionForm' },
      options: {
        ...formOptions,
        actionId: option('ACTION_JS', {
          label: 'Action',
          value: '',
          configuration: {
            createAction: {
              name: 'Name of the action',
              template: 'update',
              permissions: 'inherit',
            },
          },
        }),
      },
    }, []);