> For the complete documentation index, see [llms.txt](https://docs.iynxdev.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.iynxdev.com/addon-api/getting-started/dashboard-config-editor.md).

# Dashboard Config Editor

This page explains how to make your plugin config editable in Athena’s dashboard with a dashboard schema file.

***

## 1. Required files

For a config named `hello`, you need both files:

* `/plugins/<plugin_name>/data/configs/en-hello.json5`
* `/plugins/<plugin_name>/data/dashboard/en-hello.json`

If the dashboard schema file is missing, your config is still loaded, but it is not editable in the dashboard config editor.

***

## 2. Enabling dashboard editing

To make your config editable in the dashboard, add the `dashboardConfigurable: true` flag to your config interface constructor:

```js
const helloConfig = new this.heart.core.discord.core.config.interface(
  this.heart,
  { name: 'hello', plugin: this.getName(), dashboardConfigurable: true },
  {
    config: {
      // your config structure
    }
  },
);
```

> Without this flag, even if you provide a dashboard schema file, your config will not appear in the dashboard config editor. This flag is required to enable dashboard integration for your config.

***

## 3. Schema basics

Your dashboard schema file maps config keys to UI field definitions.

```json
{
  "bot_name": {
    "type": 0,
    "name": "Bot Name",
    "description": "Display name used by your plugin",
    "autocomplete": []
  },
  "bot": {
    "type": 2,
    "name": "Bot Enabled",
    "description": "Enable or disable plugin features globally",
    "autocomplete": [true, false]
  }
}
```

### Common field settings

* `name`: UI label shown in the editor.
* `description`: Help text shown under the field.
* `extra`: Optional markdown details shown in the info popover.
* `autocomplete`: Suggested values for supported field types.

***

## 4. Useful config types

The dashboard supports many built-in types. For custom plugin schemas, the most common are:

* `type 0`: string input
* `type 1`: number input
* `type 2`: boolean toggle or choice
* `type 3`: array of strings
* `type 4`: array of numbers
* `type 5`: array of booleans
* `type 10`: group of related settings
* `type 1000`: array of objects (schema-driven)
* `type 1001`: dynamic object where each key maps to an array of schema-driven objects
* `type 1002`: dynamic object where each key maps to a single object (schema-driven)

***

## 5. Schema-driven types

### Type 1000: Array of objects

Use this when users should add multiple objects with one fixed structure.

```json
{
  "dashboard_panels": {
    "type": 1000,
    "name": "Dashboard Panels",
    "value_schema": {
      "name": { "type": 0, "label": "Panel Name", "autocomplete": ["Welcome", "Rules"] },
      "channel_id": { "type": 0, "label": "Channel ID" },
      "enabled": { "type": 2, "label": "Enabled", "autocomplete": [true, false] },
      "tags": { "type": 3, "label": "Tags", "autocomplete": ["staff", "public"] }
    },
    "autocomplete": []
  }
}
```

Example data structure:

```json5
dashboard_panels: [
  {
    name: "Welcome",
    channel_id: "000000000000000001",
    enabled: true,
    tags: ["public", "rules"]
  },
  {
    name: "Staff",
    channel_id: "000000000000000002",
    enabled: false,
    tags: ["staff"]
  }
]
```

### Type 1001: Dynamic object of arrays

Use this when users should create named groups and each group contains an array of objects.

```json
{
  "alert_rules": {
    "type": 1001,
    "name": "Alert Rules",
    "value_schema": {
      "role_id": { "type": 0, "label": "Role ID" },
      "threshold": { "type": 1, "label": "Threshold", "autocomplete": [1, 3, 5, 10] },
      "enabled": { "type": 2, "label": "Enabled", "autocomplete": [true, false] },
      "notes": { "type": 3, "label": "Notes", "autocomplete": ["Escalate", "Soft warning"] }
    },
    "autocomplete": []
  }
}
```

Example data structure:

```json5
alert_rules: {
  "moderation": [
    {
      role_id: "111111111111111111",
      threshold: 3,
      enabled: true,
      notes: ["Escalate"]
    },
    {
      role_id: "222222222222222222",
      threshold: 5,
      enabled: false,
      notes: ["Soft warning"]
    }
  ],
  "security": [
    {
      role_id: "333333333333333333",
      threshold: 10,
      enabled: true,
      notes: ["Escalate", "Notify admin"]
    }
  ]
}
```

### Type 1002: Dynamic object of single objects

Use this when users should create named groups and each group contains a single configured object.

```json
{
  "service_configs": {
    "type": 1002,
    "name": "Service Configurations",
    "value_schema": {
      "api_key": { "type": 0, "label": "API Key" },
      "endpoint": { "type": 0, "label": "Endpoint URL" },
      "timeout": { "type": 1, "label": "Timeout (ms)", "autocomplete": [1000, 3000, 5000] },
      "enabled": { "type": 2, "label": "Enabled", "autocomplete": [true, false] }
    }
  }
}
```

Example data structure:

```json5
service_configs: {
  "service_a": {
    api_key: "key123",
    endpoint: "https://api.example.com",
    timeout: 5000,
    enabled: true
  },
  "service_b": {
    api_key: "key456",
    endpoint: "https://api2.example.com",
    timeout: 3000,
    enabled: false
  }
}
```

***

## 6. Keep config and schema in sync

Your `data/configs/en-hello.json5` defaults and `data/dashboard/en-hello.json` schema should describe the same keys.

For example:

* schema key `dashboard_panels` should exist in the default config as `config.dashboard_panels`
* schema key `alert_rules` should exist in the default config as `config.alert_rules`

If key names diverge, the editor can show empty values or reject edits.
