Skip to content

EA Script API Reference

All methods below are available inside your script.js plugin registration function via this.

js
plugins["my-plugin"] = function () {
    // this.addLanguage(...)
    // this.addRole(...)
    // etc.
}

addLanguage(code, key, value)

Registers i18n translation strings for your plugin. Will not overwrite a namespace that is already registered.

ParameterTypeDescription
code"ar" | "en"Locale code
keystringNamespace (e.g. "music", "form")
valueobjectKey/value translation pairs
js
this.addLanguage("en", "music", {
    name: "Music",
    playlist: "Playlist"
});

this.addLanguage("ar", "music", {
    name: "الموسيقى",
    playlist: "قائمة التشغيل"
});

In Vue templates, use translations with $t("namespace.key"):

vue
<h5>{{ $t("music.name") }}</h5>

addRole(role)

Registers a permission role for your plugin. Roles control access to actions (create, save, delete, etc.) and are configurable by administrators.

ParameterTypeDescription
role.idstringUnique role identifier
role.textstringDisplay name
role.keystringi18n key for the role label
role.rolesobjectMap of permission keys to permission definitions

Each permission inside role.roles:

PropertyTypeDescription
textstringDisplay name
keystringi18n key
valuebooleanDefault value (false = denied by default)
js
this.addRole({
    id: "music",
    text: "Music",
    key: "music.name",
    roles: {
        create: { text: "Create", key: "button.create", value: false },
        save:   { text: "Save",   key: "button.save",   value: false },
        delete: { text: "Delete", key: "button.delete", value: false }
    }
});

In Vue components, check permissions with the role() helper:

vue
<Button v-if="role('music', 'delete')" icon="pi pi-trash" />

addWidget(item)

Mounts a Vue component onto the EA dashboard as a widget tile. This is what you use for the standard widget.vue file — it shows up in the draggable widget grid on the home dashboard, and users can resize/remove it in dashboard edit mode.

ParameterTypeDescription
item.namestringUnique component route name
item.idstringWidget identifier
item.filestring[]File path array passed to loadModule
js
this.addWidget({
    name: "/[music]widget.vue",
    id: "init-music",
    file: ["music", "widget.vue"]
});

The file array resolves relative to the plugin's version folder. ["music", "widget.vue"] loads 1.0.0/widget.vue from the music plugin.

addTask(item)

Registers a background task component, shown in the app's task panel — a different UI surface from the dashboard widget grid. Use this for long-running or status-style components rather than the main widget tile.

ParameterTypeDescription
item.namestringUnique component name
item.idstringTask identifier
item.filestring[]File path array passed to loadModule
js
this.addTask({
    name: "/[music]sync-task.vue",
    id: "init-music-sync",
    file: ["music", "sync-task.vue"]
});

addToSetting(route)

Adds a navigation entry to the Settings sidebar in the EA application.

ParameterTypeDescription
route.labelstringSidebar display label
route.keystringi18n key for the label
route.iconstringIcon class (MDI or PrimeIcons)
route.tostringRoute path this item navigates to
js
this.addToSetting({
    label: "Music",
    key: "music.name",
    icon: "mdi mdi-book-music",
    to: "/app/setting/music"
});

The to path must match the path you register with addPage(..., "setting").

addToToolbar(route)

Adds a button or link to the application toolbar.

ParameterTypeDescription
routeobjectRoute config pushed to the toolbar array
js
this.addToToolbar({
    icon: "pi pi-music",
    to: "/app/music"
});

addToDashboard(cat, item)

Adds one navigation item inside an existing dashboard category — internally it does navigation[cat].items[item.to] = item and app.adminRoute[cat].push(item.to), so cat must already exist in both, or this throws.

ParameterTypeDescription
catstringCategory key — see the built-in list below, or a category name a plugin already created via addToDashboardRoot
item.tostringRoute path — also used as the item's key in navigation[cat].items
item.labelstringDisplay label
item.keystringi18n key for the label
item.iconstringIcon class (MDI or PrimeIcons)
item.itemsarray?Optional sub-menu items (each {label, key, icon, to}), for a flyout under this entry
js
this.addToDashboard("System", {
    label: "Music",
    key: "music.name",
    icon: "mdi mdi-book-music",
    to: "/app/music"
});

Built-in category keys

These are always present (defined in app/src/router/navigation.js), so they're safe to target from any plugin regardless of load order:

catSidebar labelExisting items
HomeHomeDashboard, Tasks
ExplorerExplorerFile Explorer, Shortcut
UsersUsersUsers, Roles, Sessions
SystemSystemStore, Profile, License, Setting
AboutAboutContact, Info, Website

You can also target a category a plugin created earlier via addToDashboardRoot (e.g. "cashir") — but that only works if that plugin has already run, so prefer creating your own root category with addToDashboardRoot unless you specifically mean to extend a category owned by another known plugin.

addToDashboardRoot(cat, item, routes)

Creates (or replaces) a root-level sidebar category — a top-level entry in the main navigation, with its own set of menu items, sitting alongside the built-in categories (Home, Explorer, Users, System, About). Use addToDashboard instead if you just want to add one item into an existing category.

ParameterTypeDescription
catstringCategory key. Becomes the key under both navigation (sidebar) and app.adminRoute (route access) — must be unique
item.labelstringCategory display label
item.keystringi18n key for the label
item.ordernumber?Optional position among the other sidebar categories (see below)
item.itemsobjectMenu entries for this category, keyed by route path. Each entry is { label, key, icon, to }, and can itself have a nested items: [] array for a sub-menu (see suppliers below)
routesstring[]Route path prefixes this category owns, used for role-based access (see below)

item.items is required if you want the category to actually show any menu entries — it becomes navigation[cat].items, the same shape addToDashboard and addToSetting read from. Skipping it (as a bare {label, icon, order}) creates an empty category.

order controls where the category sits in the sidebar. If you pass it, both navigation and app.adminRoute are re-keyed so the category lands at that index and everything else shifts — keeping sidebar order and role/route data in sync. If you omit it, the category is just appended (or, if cat already exists, replaced in place without moving it).

routes feeds app.adminRoute[cat], which the router's role guard (checkRouter) uses to decide whether a non-admin user may open a given path — it checks path.startsWith(...) against every entry. In practice you only need to list each top-level page path once; nested sub-pages (like suppliers/add below) are already covered because they start with an already-listed prefix (suppliers).

Real example, trimmed from the bundled cashir plugin (plugins/cashir/script.js):

js
this.addToDashboardRoot(
    "cashir",
    {
        label: "Cashir",
        key: "cashir.name",
        order: 2,
        items: {
            "/app/cashir/addBill": {
                to: "/app/cashir/addBill",
                label: "Add Bill",
                key: "cashir.bills",
                icon: "mdi mdi-receipt-text-outline"
            },
            "/app/cashir/suppliers": {
                label: "Suppliers",
                key: "cashir.suppliers",
                icon: "mdi mdi-account-hard-hat-outline",
                // Sub-menu under "Suppliers" — note this is an array, unlike the outer `items` map
                items: [
                    { label: "List", key: "menu.list", icon: "mdi mdi-format-list-group", to: "/app/cashir/suppliers" },
                    { label: "Add", key: "menu.add", icon: "mdi mdi-plus", to: "/app/cashir/suppliers/add" }
                ]
            },
            "/app/cashir/setting": {
                key: "menu.setting",
                label: "setting",
                icon: "pi pi-fw pi-cog",
                to: "/app/cashir/setting"
            }
        }
    },
    // routes: one prefix per top-level item above — "/app/cashir/suppliers/add" is
    // covered automatically since it starts with the already-listed "/app/cashir/suppliers"
    ["/app/cashir/addBill", "/app/cashir/suppliers", "/app/cashir/setting"]
);

addRole() is separate from this — routes/app.adminRoute gates which pages a role can open, while addRole() gates individual actions (create/save/delete) inside those pages.

addToExplorer(data)

Registers your plugin with the application explorer, making it discoverable as an installed application.

ParameterTypeDescription
data.idstringUnique key in the application registry
dataobjectFull application descriptor
js
this.addToExplorer({
    id: "music",
    label: "Music",
    icon: "mdi mdi-book-music"
});

addPage(page, to)

Registers a Vue component as a routed page inside the EA application.

ParameterTypeDescription
page.namestringUnique route name
page.pathstringRoute path
page.filestring[]File path array passed to loadModule
tostringParent route name. Defaults to "app". Use "setting" for settings pages

If a route with page.name already exists, the registration is skipped silently.

js
// Register a settings page
this.addPage({
    name: "/[music]setting.vue",
    path: "/app/setting/music",
    file: ["music", "setting.vue"]
}, "setting");

// Register a main app page
this.addPage({
    name: "/[music]index.vue",
    path: "/app/music",
    file: ["music", "index.vue"]
}, "app");

Typical plugin registration pattern

js
plugins["music"] = function () {
    // 1. Register translations
    this.addLanguage("en", "music", { name: "Music", playlist: "Playlist" });
    this.addLanguage("ar", "music", { name: "الموسيقى", playlist: "قائمة التشغيل" });

    // 2. Register roles
    this.addRole({
        id: "music",
        text: "Music",
        key: "music.name",
        roles: {
            create: { text: "Create", key: "button.create", value: false },
            save:   { text: "Save",   key: "button.save",   value: false },
            delete: { text: "Delete", key: "button.delete", value: false }
        }
    });

    // 3. Mount dashboard widget
    this.addWidget({
        name: "/[music]widget.vue",
        id: "init-music",
        file: ["music", "widget.vue"]
    });

    // 4. Add Settings sidebar entry
    this.addToSetting({
        label: "Music",
        key: "music.name",
        icon: "mdi mdi-book-music",
        to: "/app/setting/music"
    });

    // 5. Register settings page route
    this.addPage({
        name: "/[music]setting.vue",
        path: "/app/setting/music",
        file: ["music", "setting.vue"]
    }, "setting");
}