Portal Community

Pattern 1: Invoice Line Items with Quick-Add

The most common data table pattern. The table captures line items; action buttons add preset service types with one click.

// Data Table
{
  "id": "invoice-lines",
  "type": "data-table",
  "label": "Invoice Lines",
  "width": "full",
  "settings": {
    "binding": { "source": "$json", "path": "invoice.lines" },
    "addable": true,
    "deletable": true,
    "reorderable": true,
    "addLabel": "Add Line",
    "minRows": 1,
    "newRowDefaults": { "qty": 1, "unit-price": 0 },
    "columns": [
      { "id": "description", "label": "Service / Item", "type": "text",   "width": "40%", "required": true },
      { "id": "qty",         "label": "Qty",             "type": "number", "width": "10%", "settings": { "min": 1, "precision": 0 } },
      { "id": "unit-price",  "label": "Unit Price",      "type": "number", "width": "20%", "settings": { "format": "currency", "min": 0 } },
      { "id": "vat",         "label": "VAT %",           "type": "number", "width": "10%", "settings": { "min": 0, "max": 100, "precision": 1 } },
      { "id": "total",       "label": "Total",           "type": "number", "width": "20%", "readOnly": true, "settings": { "format": "currency", "computedValue": "row.qty * row['unit-price'] * (1 + row.vat / 100)" } }
    ]
  }
},

// Quick-Add action buttons (in actions[]):
{
  "id": "add-consulting",
  "type": "addQuickItems",
  "label": "Add Consulting",
  "settings": {
    "tableId": "invoice-lines",
    "items": [{ "description": "Consulting Services", "qty": 1, "unit-price": 150, "vat": 20 }]
  }
},
{
  "id": "add-expenses",
  "type": "addQuickItems",
  "label": "Add Travel",
  "settings": {
    "tableId": "invoice-lines",
    "items": [{ "description": "Travel Expenses", "qty": 1, "unit-price": 0, "vat": 0 }]
  }
}

Pattern 2: Reminder Schedule with Bulk Delete

A schedule of days and notes. Rows can be selected and deleted in bulk. Quick-Add inserts standard reminder intervals.

// Data Table
{
  "id": "reminders",
  "type": "data-table",
  "label": "Reminder Schedule",
  "settings": {
    "binding": { "source": "$json", "path": "policy.reminders" },
    "selectable": true,
    "addable": true,
    "deletable": false,
    "addLabel": "Add Reminder",
    "emptyMessage": "No reminders configured. Click 'Add Reminder' or use Quick-Add.",
    "columns": [
      { "id": "day",  "label": "Days Before Due",  "type": "number", "width": "30%", "settings": { "min": 1, "max": 365 }, "required": true },
      { "id": "time", "label": "Time",             "type": "select", "width": "25%", "settings": { "options": [{ "value": "09:00", "label": "9:00 AM" }, { "value": "17:00", "label": "5:00 PM" }] } },
      { "id": "note", "label": "Message Template", "type": "text",   "width": "45%", "settings": { "placeholder": "Payment reminder..." } }
    ]
  }
},

// Quick-Add: Standard intervals
{
  "id": "add-standard-reminders",
  "type": "addQuickItems",
  "label": "Add Standard Reminders",
  "settings": {
    "tableId": "reminders",
    "items": [
      { "day": 30, "time": "09:00", "note": "Payment due in 30 days" },
      { "day": 14, "time": "09:00", "note": "Payment due in 14 days" },
      { "day": 7,  "time": "09:00", "note": "Payment due in 7 days" },
      { "day": 1,  "time": "09:00", "note": "Payment due tomorrow" }
    ]
  }
},

// Delete Selected action
{
  "id": "delete-reminders",
  "type": "deleteSelected",
  "label": "Delete Selected",
  "settings": { "tableId": "reminders" },
  "disabledRule": "!values['reminders'] || !values['reminders'].some(r => r._selected)"
}

Pattern 3: Team Member List with Role Selection

A list of team members where each row has a name, email, and role dropdown. A minimum of one Owner is enforced via validation.

{
  "id": "team-members",
  "type": "data-table",
  "label": "Team Members",
  "settings": {
    "binding": { "source": "$json", "path": "team.members" },
    "addable": true,
    "deletable": true,
    "reorderable": false,
    "addLabel": "Add Member",
    "minRows": 1,
    "newRowDefaults": { "role": "member" },
    "columns": [
      {
        "id": "name",
        "label": "Full Name",
        "type": "text",
        "width": "30%",
        "required": true
      },
      {
        "id": "email",
        "label": "Email",
        "type": "email",
        "width": "35%",
        "required": true
      },
      {
        "id": "role",
        "label": "Role",
        "type": "select",
        "width": "25%",
        "required": true,
        "settings": {
          "options": [
            { "value": "owner",  "label": "Owner" },
            { "value": "admin",  "label": "Admin" },
            { "value": "member", "label": "Member" },
            { "value": "viewer", "label": "Viewer" }
          ]
        }
      }
    ]
  }
}

Pattern 4: Link Action — Navigate from Row

In list forms, data-table rows can trigger navigation to a detail form. Set selectable and configure a link action with keyField:

{
  "id": "policies-table",
  "type": "data-table",
  "settings": {
    "selectable": true,
    "keyField": "policyId",
    "columns": [
      { "id": "policyId",   "label": "ID",     "type": "text", "width": "15%", "readOnly": true },
      { "id": "policyName", "label": "Policy", "type": "text", "width": "50%", "readOnly": true },
      { "id": "status",     "label": "Status", "type": "text", "width": "20%", "readOnly": true }
    ]
  }
},

// Link action navigates to detail form when a row is selected:
{
  "id": "open-policy",
  "type": "link",
  "label": "Open Policy",
  "settings": {
    "targetFormId": 13001,
    "keyField": "policyId",
    "tableId": "policies-table"
  }
}
Design Tip Always set minRows: 1 on invoice line items to ensure at least one row exists on submit. Combine with a required validation on the description column to prevent empty line items from being submitted.