Skip to content

Dashboard Config Editor

Zeroknights edited this page Apr 9, 2026 · 8 revisions

This page explains how to make your plugin config editable in Athena's dashboard using 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:

const helloConfig = new this.heart.core.discord.core.config.interface(
	this.heart,
	{ name: 'hello', plugin: this.getName(), dashboardConfigurable: true }, // Add this flag
	{
		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.

{
  "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 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/choice
  • type 3: array of strings
  • type 4: array of numbers
  • type 5: array of booleans
  • type 10: This type is used to define a new 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.

{
  "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": []
  }
}

Data structure (Example):

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.

{
  "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": []
  }
}

Data structure (Example):

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 (not an array).

{
  "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] }
    }
  }
}

Data structure (Example):

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 default config as config.dashboard_panels
  • schema key alert_rules should exist in default config as config.alert_rules

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

Clone this wiki locally