logo dile-components dile-components

Resource Configuration Object

The more advanced components in the CRUD library require a configuration object that provides various properties and methods necessary for customizing their functionality.

This configuration object is typically used for each API resource you want to manage with the CRUD system.

Generating CRUD Resource Config

Using the Dile CLI, you can quickly generate the configuration object for CRUD system components.

  1. Install the CLI as indicated on this page
  2. Run the command dile g-resource-config <resource>

Example:

dile g-resource-config country --endpoint https://example.com/api/countries

Find more information on g-resource-config configurations using the following help command:

dile g-resource-config --help

Default Configuration

There are default definitions for the configuration object, which can be found in the lib/defaultConfig.js file. See the default config file on GitHub.

It is entirely possible to follow the format defined in that file to create a custom configuration object. However, the library offers a class called CrudConfigBuilder that simplifies this task.

CrudConfigBuilder Class

This class allows you to build a configuration object more easily. By invoking the class constructor, you can define specific configuration values for a resource. The constructor accepts two arguments:

import { CrudConfigBuilder } from '@dile/crud/lib/CrudConfigBuilder';
const countryConfig = new CrudConfigBuilder('https://example.com/api/countries', {});

These two argument values will be merged with the default configurations, so if you do not specify any value in the second argument, the default values will always be set.

Additionally, any value in the configuration object provided as the second argument will override the values in the default configuration object.

Once the CrudConfigBuilder instance is created, you can call the getConfig() method to obtain the configuration object.

countryConfig.getConfig();

Creating a Configuration Module for Each Resource

Since the configuration object is usually the same for each resource, it may be useful to create an independent module for each resource. This same configuration object can be used across different components, such as the listing component, the item detail component, or a complete CRUD component.

Here is an example of creating a configuration module that exports the object to access the configuration of a resource:

import { html } from 'lit';
import { CrudConfigBuilder } from '@dile/crud/lib/CrudConfigBuilder';

export const countryConfig = new CrudConfigBuilder('https://timer.escuelait.com/api/countries', {
  templates: {
    item: (country) => html`<demo-country-item .country=${country}></demo-country-item>`,
    insertForm: () => html`<demo-country-form id="insertform"></demo-country-form>`,
    updateForm: () => html`<demo-country-form id="updateform"></demo-country-form>`,
  },
  customization: {
    disablePagination: true,
  },
  sort: {
    options: [
      {
        name: 'name',
        label: 'Name',
        direction: 'desc'
      },
    ],
    initialSortField: 'name',
  },
  availableFilters: [
    {
      name: 'essential',
      label: 'Is essential',
      active: false,
      value: false,
      type: 'boolean',
    },
    {
      name: 'continent',
      label: 'Continent',
      active: false,
      value: false,
      type: 'select',
      options: [
        {
          value: 'Europe',
          label: 'Europe'
        },
        {
          value: 'Africa',
          label: 'Africa'
        },
        {
          value: 'Asia',
          label: 'Asia'
        },
      ]
    },
  ],
});

This module can be used to define configurations specific to the countries resource, including templates for items and forms, pagination settings, sorting options, and filters.

Adapting to API Responses

The responseAdapter property in the configuration object is an object that defines how the CRUD system will extract data from the REST API responses.

The default configuration object for the resource provides a responseAdapter that works with typical REST API responses. However, you can create a custom version of this object by extending the base ResponseApiAdapter class.

For more information, refer to the page dedicated to the responseAdapter object.

Configuration properties

Here is a complete list of the configuration object properties that can be supplied for the resource.

Quick Reference

Property Type Description
availableFilters Array Configure filters to narrow down the list of items
sort Object Define sorting options and initial sort field
pageSize Object Configure pagination options for list views
insertOperation Object Customize the behavior of the insert button
updateOperation Object Customize the behavior of the edit/update operation
actions Object Define batch actions for lists and individual actions for single items
maxBatchActionItems Number Set the maximum number of items for batch actions
customization Object Customize the behavior and visibility of UI elements
templates Object Define template functions for rendering different parts of the CRUD interface
labels Object Customize labels for buttons, titles, and other UI text
formIds Object Define HTML id attributes for form elements
requestAdapter Object Adapt requests sent to API endpoints
responseAdapter Object Adapt API responses to the CRUD system
computeItemId Function Determine the identifier value for each resource element
isItemEditable Function Determine if a specific item can be edited
isItemDeletable Function Determine if a specific item can be deleted
destructiveActionNames Array List of action names that are destructive and prevent component refresh
onActionListSuccess Function Handle successful completion of batch actions in dile-crud
onActionSingleSuccess Function Handle successful completion of actions in dile-crud-single

Property availableFilters

This property is used to define the filters that the dile-crud component will offer.

Filter configuration allows two types of filters that generate different query interfaces, either with checkboxes or select boxes. In the following example, you can see a filter configuration:

availableFilters: [
  {
    type: 'boolean',
    name: 'column',
    label: 'Column',
    active: false,
    value: false,
  },
  {
    type: 'select',
    name: 'column2',
    label: 'Column 2',
    active: false,
    value: false,
    options: [
      {
        value: '1',
        label: 'Value 1'
      },
      {
        value: '2',
        label: 'Value 2'
      },
    ]
  },
],

When filters are enabled in the CRUD component, requests are made to the API sending the filter state through the query string.

Default availableFilters value

By default, availableFilters is an empty array.

availableFilters: []

Property sort

This property configures the sorting options available in the CRUD component, allowing users to sort items by different fields and in different directions (ascending or descending).

The sort property is an object with two main configurations:

options (Array)

An array of available sort options. Each option should be an object with the following properties:

initialSortField (string | null)

The name of the sort field that should be initially selected when the component loads. This value must match one of the name values in the options array.

Example usage

sort: {
  options: [
    {
      name: 'name',
      label: 'Name',
      direction: 'asc'
    },
    {
      name: 'year',
      label: 'Year',
      direction: 'desc'
    },
  ],
  initialSortField: 'year',
},

In this example, two sort options are defined: "Name" (ascending) and "Year" (descending). When the component first loads, it will be sorted by the "year" field in descending order.

Default value

By default, no sort options are available and no initial sort field is set:

sort: {
  options: [],
  initialSortField: null,
},

This means sorting will be disabled unless you provide custom sort options in your resource configuration.


Property pageSize

This property allows you to configure the pagination settings for list views in the CRUD component.

The pageSize property is an object with two main configurations:

available (Array)

An array of page size options that users can select from. These numbers represent how many items should be displayed per page.

initial (Number)

The initial page size that will be selected when the component first loads. This value must be one of the values in the available array.

Example usage

pageSize: {
  available: [10, 25, 50, 100],
  initial: 25,
},

In this example, users can choose to display 10, 25, 50, or 100 items per page, and by default, the component will show 25 items per page.

Default value

By default, the page size configuration includes common pagination options:

pageSize: {
  available: [10, 25, 50],
  initial: 25,
},

Property insertOperation

This property defines how the insert button behaves in the dile-crud component. By default, when the insert button is clicked, a modal opens with the form for inserting the entity being managed. However, you can define any other behavior you wish, such as navigating to another page where the insert content is displayed.

To do this, insertOperation accepts an object with a property called type. By setting the type value to handler, you can define a handler to execute custom code when the Insert button is pressed. Here's an example:

insertOperation: {
  type: "handler",
  handler: (crudComponent) => {
    navigateService.goToUrl('/create-invoice');
  }
},

Note that the handler function receives the dile-crud component itself, allowing you to interact with the panel if needed.

Default value

The default value of insertOperation causes a modal window to open when the insert button is clicked.

insertOperation: {
  type: 'modal'
},

Property updateOperation

The updateOperation property allows you to customize how the CRUD system handles the edit/update operation when a user clicks the edit button on an item.

Default Behavior

By default, the updateOperation is configured to open the update form in a modal dialog:

updateOperation: {
  type: 'modal'
}

Custom Handler

You can override this behavior by providing a custom handler function. This is useful when you want to:

To use a custom handler, configure updateOperation like this:

updateOperation: {
  type: 'handler',
  handler: (itemId, crudComponent, item) => {
    // Your custom logic here
  }
}

Handler Parameters

Handler Example

Here's a practical example that navigates to different edit pages based on the item's type:

import { navigateService } from '@your-app/services';

const countryConfig = new CrudConfigBuilder('https://example.com/api/countries', {
  updateOperation: {
    type: 'handler',
    handler: (itemId, crudComponent, item) => {
      if (item.rectificative_type === 'S') {
        navigateService.goToUrl(`/rectificacion-wizard/${itemId}`);
      } else {
        navigateService.goToUrl(`/invoice-wizard/${itemId}`);
      }
    },
  },
});

Configuration Structure

Property Type Required Description
type String Yes Either 'modal' or 'handler'
handler Function Only if type is 'handler' Custom function to handle the update operation

Property actions

The actions property defines the operations that can be performed on resources through the CRUD system. This object contains two types of actions:

Basic Structure

{
  actions: {
    list: [
      // Batch actions configuration
    ],
    single: [
      // Individual actions configuration
    ]
  }
}

Each action object must include a name (identifier) and a label (display text). Individual actions also support conditional display through the shouldAppear function.

For complete information about configuring actions, including all available properties and examples, see the Actions Configuration page.


Property maxBatchActionItems

This property sets the maximum number of items that can be selected for batch actions in the CRUD component.

It is used to show or hide the component that allows users to select all items in the current page or all items in a resource.

Note: The component itself does not check the number of items the user selects. This validation must be performed on the backend before processing the batch actions.

This is useful to prevent users from performing batch operations on an excessive number of items at once, which could impact performance.

Default value

By default, maxBatchActionItems is set to 100.

maxBatchActionItems: 100

You can override this value in your resource configuration object if you need a different limit for your use case.


Property customization

This property allows you to customize the behavior and visibility of various elements and features in the CRUD component.

The customization property is an object containing multiple boolean flags that control different aspects of the component's functionality and UI.

Available customization options

Example usage

customization: {
  disableKeywordSearch: false,  // Enable keyword search
  hideCountSummary: false,      // Show total count
  hidePageReport: false,        // Show page information
  hideCheckboxSelection: false, // Show selection checkboxes
  disablePagination: false,     // Enable pagination
  disableSort: false,           // Enable sorting
  disableFilter: false,         // Enable filtering
  disableHelp: false,           // Show help
  disableEdit: false,           // Enable editing
  disableDelete: false,         // Enable deletion
},

Default value

The default configuration disables most features and hides selection UI elements:

customization: {
  disableKeywordSearch: true,
  hideCountSummary: false,
  hidePageReport: false,
  hideCheckboxSelection: true,
  hideEmptyInsertButton: false,
  disableInsert: false,
  disableEdit: false,
  disableDelete: false,
  disableRestore: false,
  disablePagination: true,
  disableSort: true,
  disableFilter: true,
  disableHelp: true,
},

Property templates

This property is an object that contains template functions for rendering different parts of the CRUD interface. Each template function uses Lit's html template literal to return the DOM structure for that specific part.

Type: Object

Default Value:

templates: {
  item: () => templatePlaceholder('item'),
  insertForm: (belongsTo, relationId) => templatePlaceholder('insertForm'),
  updateForm: () => templatePlaceholder('updateForm'),
  help: () => templatePlaceholder('help'),
  detail: () => templatePlaceholder('detail'),
  formActions: (actionName) => html`
    <dile-pages attrForSelected="action" selected="${actionName}">
      <dile-crud-delete-action  action="DeleteAction"></dile-crud-delete-action>
    </dile-pages>
  `,
  relations: () => '',
  formSingleActions: () => '',
}

Template Functions

item

Renders each individual item in the list view.

Parameters:

Returns: Lit html template result

insertForm

Renders the form for creating new items.

Parameters:

Returns: Lit html template result

updateForm

Renders the form for editing existing items.

Parameters:

Returns: Lit html template result

help

Renders the help content shown to users.

Parameters: None

Returns: Lit html template result

detail

Renders the detail view of a single item.

Parameters:

Returns: Lit html template result

formActions

Renders the action buttons that appear in the item form (edit/delete operations).

Parameters:

Returns: Lit html template result

relations

Renders related resources or relationships for an item.

Parameters:

Returns: Lit html template result

formSingleActions

Renders custom action buttons for a specific item (in addition to standard CRUD actions).

Parameters:

Returns: Lit html template result

Example

import { html } from 'lit';
import { CrudConfigBuilder } from '@dile/crud/lib/CrudConfigBuilder';

export const countryConfig = new CrudConfigBuilder('https://example.com/api/countries', {
  templates: {
    item: (country) => html`<demo-country-item .country=${country}></demo-country-item>`,
    insertForm: () => html`<demo-country-form id="insertform"></demo-country-form>`,
    updateForm: () => html`<demo-country-form id="updateform"></demo-country-form>`,
    help: () => html`<p>This is the help provided to the countries resource.</p>`,
    detail: (country) => html`<demo-country-detail .country="${country}"></demo-country-detail>`,
    relations: (country) => html`
      <p>${country.name}</p>
      <demo-country-relations .country=${country}></demo-country-relations>
    `,
    formSingleActions: (actionName, country) => html`
      <dile-pages attrForSelected="action" selected="${actionName}">
        <demo-set-europe-as-continent-action action="SetEurope" .country=${country}></demo-set-europe-as-continent-action>
        <demo-set-asia-as-continent-action action="SetAsia" .country=${country}></demo-set-asia-as-continent-action>
      </dile-pages>
    `,
  },
});

All template functions must return Lit html template results to work properly with the Web Components used by the CRUD system.


Property labels

This property is an object that contains custom labels for various UI elements in the CRUD interface. Labels are used for buttons, window titles, and other user-facing text throughout the components.

Each label is optional. If not provided, the system will fall back to translated values (if translations are available) or default English text.

Type: Object

Default Value:

labels: {
  // All properties are optional
}

Available Labels

insertAction

Label for the button that opens the insert/create form.

Default fallback: translations.insert_label'Insert'

insertWindowTitle

Title shown in the modal window when creating a new item.

Default fallback: translations.insert_label'Insert'

updateAction

Label for the save/update button in the edit form.

Default fallback: translations.update_label'Save'

updateWindowTitle

Title shown in the modal window when editing an existing item.

Default fallback: translations.update_label'Save'

startUpdateAction

Label for the button that opens the edit form for an existing item.

Default fallback: translations.start_update_label'Edit'

helpTitle

Title for the help section/modal.

Default fallback: translations.help_label'Help'

helpButtonLabel

Label for the help button.

Default fallback: translations.help_label'Help'

How Labels Are Computed

The CRUD system uses a fallback chain when rendering labels. For each label, it checks:

  1. Custom label value - If a value is provided in config.labels, it will be used
  2. Translation - If no custom label is provided, the system looks for a translated value (e.g., translations.insert_label)
  3. Default text - If neither a custom label nor translation is found, a default English value is used

This allows you to:

Example

import { html } from 'lit';
import { CrudConfigBuilder } from '@dile/crud/lib/CrudConfigBuilder';

export const countryConfig = new CrudConfigBuilder('https://example.com/api/countries', {
  labels: {
    helpTitle: 'Countries Help',
    insertAction: 'Add Country',
    insertWindowTitle: 'Create New Country',
    updateAction: 'Save Changes',
    updateWindowTitle: 'Edit Country',
    startUpdateAction: 'Edit',
    helpButtonLabel: 'Show Help',
  },
});

In this example, all the custom labels will be used throughout the CRUD interface instead of the default values or translations.

Minimal Example

You only need to define the labels you want to customize:

export const countryConfig = new CrudConfigBuilder('https://example.com/api/countries', {
  labels: {
    helpTitle: 'Country help',
  },
});

In this case, only helpTitle will be customized, and all other labels will use the translation fallback or default English values.


Property formIds

This property contains the HTML id attribute values that are used to identify form elements in the DOM. The CRUD system uses these identifiers to locate and interact with the form components.

Type: Object

Default Value:

formIds: {
  insertForm: 'insertform',
  updateForm: 'updateform',
}

Properties

insertForm

The HTML id attribute value of the form component used for creating new items.

Default Value: 'insertform'

Type: String

updateForm

The HTML id attribute value of the form component used for editing existing items.

Default Value: 'updateform'

Type: String

How Form IDs Work

When you define your templates, the form elements must have an id attribute that matches the corresponding value in formIds. The CRUD components (dile-crud-insert, dile-crud-update) use these IDs to locate the form elements and manage their data.

templates: {
  insertForm: () => html`
    <demo-country-form id="insertform"></demo-country-form>
  `,
  updateForm: () => html`
    <demo-country-form id="updateform"></demo-country-form>
  `,
}

The id attribute (insertform, updateform) must match the values specified in formIds.

Implementing Form Components

Form components used in the CRUD system must implement the DileForm mixin from @dile/ui/mixins/form. This mixin provides essential form methods and functionality required by the CRUD system:

import { LitElement, html, css } from 'lit';
import { DileForm } from '@dile/ui/mixins/form';

export class DemoCountryForm extends DileForm(LitElement) {
  static styles = [
    css`
      :host {
        display: block;
      }
    `
  ];

  render() {
    return html`
      <dile-input label="Name" name="name" id="name" hideErrorOnInput></dile-input>
      <dile-input label="Slug" name="slug" id="slug" hideErrorOnInput></dile-input>
      <dile-select name="continent" id="continent" label="Continent" hideErrorOnInput>
        <select slot="select">
          <option value="">Select...</option>
          <option value="Europe">Europe</option>
          <option value="Asia">Asia</option>
        </select>
      </dile-select>
    `;
  }
}

customElements.define('demo-country-form', DemoCountryForm);

The DileForm mixin provides methods like:

Customizing Form IDs

You can customize the form identifiers if you prefer different names:

export const countryConfig = new CrudConfigBuilder('https://example.com/api/countries', {
  formIds: {
    insertForm: 'country-add-form',
    updateForm: 'country-edit-form',
  },
  templates: {
    insertForm: () => html`
      <demo-country-form id="country-add-form"></demo-country-form>
    `,
    updateForm: () => html`
      <demo-country-form id="country-edit-form"></demo-country-form>
    `,
  },
});

Important: The id attribute values in your templates must exactly match the values defined in formIds.


Property requestAdapter

This property allows adapting the requests sent from the CRUD system to the API endpoints, so that it can communicate with the web service in the required way.

There is a detailed page with explanations about the request adapter.

Default requestAdapter value

The default configuration creates a generic request adapter using an instance of the RequestApiAdapter class.

new RequestApiAdapter()

Property responseAdapter

This property allows adapting the API responses that the CRUD system communicates with. Thanks to this object, the components can work with any API, regardless of how its responses are structured.

On this site you can find a detailed page explaining how to create the response adapter.

Default responseAdapter value

The default configuration creates a generic response adapter using an instance of the ResponseApiAdapter class.

new ResponseApiAdapter()

Property computeItemId

This property is a function that determines the identifier value for each resource element in the CRUD system.

The function receives the resource element as a parameter and should return the value that uniquely identifies that element. While the default implementation returns the id property, you can customize this to use other identifiers such as uuid, slug, or any other unique property your API provides.

Type: Function

Parameters:

Returns: The unique identifier value for the element

Default Value:

computeItemId(element) {
  return element.id;
}

Example:

Using a UUID identifier:

const countryConfig = new CrudConfigBuilder('https://example.com/api/countries', {
  computeItemId(country) {
    return country.uuid;
  },
});

Using a slug identifier:

const articleConfig = new CrudConfigBuilder('https://example.com/api/articles', {
  computeItemId(article) {
    return article.slug;
  },
});

This function is crucial for the CRUD system to properly track and manage individual resource items throughout operations like fetching details, updating, and deleting.


Property isItemEditable

This property is a function that determines whether a specific item can be edited or not. It allows you to implement custom logic to enable or disable the edit action on a per-item basis.

The function receives the item element as a parameter and should return a boolean value:

This works in conjunction with the customization.disableEdit boolean property. An item is considered editable only if:

  1. customization.disableEdit is false (editing is globally enabled)
  2. AND isItemEditable(item) returns true (the specific item is editable)

Example usage

isItemEditable(item) {
  // Only allow editing of items with status 'active' or 'draft'
  return ['active', 'draft'].includes(item.status);
}

Default value

By default, the function always returns true, allowing all items to be edited (as long as customization.disableEdit is false).

isItemEditable(element) {
  return true;
}

Property isItemDeletable

This property is a function that determines whether a specific item can be deleted or not. It allows you to implement custom logic to enable or disable the delete action on a per-item basis.

The function receives the item element as a parameter and should return a boolean value:

This works in conjunction with the customization.disableDelete boolean property. An item is considered deletable only if:

  1. customization.disableDelete is false (deletion is globally enabled)
  2. AND isItemDeletable(item) returns true (the specific item is deletable)

Example usage

isItemDeletable(item) {
  // Prevent deletion of items that have child relationships
  return !item.hasChildren;
}

Default value

By default, the function always returns true, allowing all items to be deleted (as long as customization.disableDelete is false).

isItemDeletable(element) {
  return true;
}

Property destructiveActionNames

This property defines which action names are considered destructive operations on a resource. Destructive actions are those that modify or delete resource data, such as deletion or archiving operations.

When an action is listed in destructiveActionNames, the dile-crud-single component will skip the automatic refresh of the item detail view after the action completes. This prevents unnecessary API calls when the resource state has been fundamentally altered.

Type: Array<String>

Default Value: ['DeleteAction']

Example:

const countryConfig = new CrudConfigBuilder('https://example.com/api/countries', {
  destructiveActionNames: ['DeleteAction', 'ArchiveAction', 'ReviewAndDeleteAction'],
});

In this example, any of these three actions will prevent the component from refreshing the item details after completion. The component assumes the resource no longer needs to be displayed in its current state.


Property onActionListSuccess

This property accepts a callback function that is executed when a batch action in the dile-crud component completes successfully.

The callback function receives an actionSuccessDetail object containing information about the completed action. This is useful for performing additional logic based on the action result, such as refreshing related data or displaying custom messages.

Type: Function

Parameters:

Default Value:

onActionListSuccess(actionSuccessDetail) {}

Example

import { html } from 'lit';
import { CrudConfigBuilder } from '@dile/crud/lib/CrudConfigBuilder';

export const countryConfig = new CrudConfigBuilder('https://example.com/api/countries', {
  // ... other config properties
  
  onActionListSuccess(actionDetail) {
    console.log(`Action "${actionDetail.action}" completed successfully`);
    console.log(`Server message: ${actionDetail.msg}`);
    
    if(actionDetail.action === 'PublishAction') {
      // Refresh related data after publishing
      this.refreshPublishedItems();
    }
  },
});

Context

When the callback is executed, the this context refers to the dile-crud component instance. This allows you to access component methods and properties if needed.

Alternative: Using Custom Events

Instead of using the onActionListSuccess callback, you can listen to the crud-action-success custom event dispatched by the dile-crud component:

const crudElement = document.querySelector('dile-crud');
crudElement.addEventListener('crud-action-success', (event) => {
  const { msg, action, data } = event.detail;
  console.log(`Action "${action}" completed:`, msg);
});

For more information about custom events, see the dile-crud-actions documentation.


Property onActionSingleSuccess

This property accepts a callback function that is executed when an action in the dile-crud-single component completes successfully.

The callback function receives an actionSuccessDetail object containing information about the completed action. This is useful for performing additional logic based on the action result, such as refreshing related data or triggering dependent operations.

Type: Function

Parameters:

Default Value:

onActionSingleSuccess(actionSuccessDetail) {}

Example

import { html } from 'lit';
import { CrudConfigBuilder } from '@dile/crud/lib/CrudConfigBuilder';

export const countryConfig = new CrudConfigBuilder('https://example.com/api/countries', {
  // ... other config properties
  
  onActionSingleSuccess(detail) {
    console.log(`Action on single process defined with onActionSingleSuccess and this detail`, detail, this);
    
    if(detail.action === 'SetEurope') {
      // Refresh relationships after setting continent
      this.refreshRelations();
    }
  },
});

Context

When the callback is executed, the this context refers to the dile-crud-single component instance. This allows you to access component methods and properties such as refresh() to reload the item details after an action completes.

onActionSingleSuccess(detail) {
  if(detail.action === 'ArchiveAction') {
    // Trigger a navigation after archiving
    window.history.back();
  }
}

Alternative: Using Custom Events

Instead of using the onActionSingleSuccess callback, you can listen to the crud-action-success custom event dispatched by the dile-crud-single component:

const singleElement = document.querySelector('dile-crud-single');
singleElement.addEventListener('crud-action-success', (event) => {
  const { msg, action, data } = event.detail;
  console.log(`Single action "${action}" completed:`, msg);
});

You can also listen for error events using crud-action-error:

singleElement.addEventListener('crud-action-error', (event) => {
  const { msg } = event.detail;
  console.error(`Action failed:`, msg);
});

For more information about custom events, see the dile-crud-actions documentation.


Documentation in progress

This documentation is a work in progress.