Admin panel

Quickly prototype admin pages without writing code

Pages

To create frontend page just add new file

./pages/my-custom-page.json
{
  "id": "my-custom-page",
  "name": "My Page",
  "components": [
  ]
}

You can start adding components to it

{
  "id": "my-custom-id-empty-page",
  "name": "Empty page",
  "components": [
    {
      "type": "button",
      "id": "do_some_funky_logic",
      "label": "CLICK ME NOW!",
      "onClick": []
    }
  ]
}

You can attach some logic to it

{
  "id": "my-custom-id-empty-page",
  "name": "Empty page",
  "components": [
    {
      "type": "button",
      "id": "do_some_funky_logic",
      "label": "CLICK ME NOW!",
      "onClick": [
        {
          "type": "query",
          "query": "mysql-post-delete",
          "dataKeyName": "deletePost",
          "params": [
            {
              "name": "id",
              "value": "window.appGlobalState.postsList.filter(item => { return item.internalFieldRowSelected }).map(item => {return item.id})"
            }
          ]
        }
      ],
      "onClickSuccess": [
        {
          "type": "notification",
          "message": "Show me!"
        }
      ]
    }
  ]
}

Events

View page source to view

Frontend

You can access all data fetched from backend by viewing

console.log(window.appGlobalState)

Executing onXError & onXSuccess & onXFinally

Javascript

{
  "type": "javascript",
  "javascript": [ //you can provide javascript as array of strings or string
    "console.log('first line');",
    "console.log('second line');"
  ]
}
{
  "type": "javascript",
  "javascript": "console.log('first line'); console.log('second line');"
}

Notification

{
  "type": "notification",
  "message": "this is sample notification"
}

Query

{
  "type": "query",
  "query": "estate-types",
  //query id that you want to run
  "dataKeyName": "myCustomQueryResponse",
  "params": [
    {
      "name": "name",
      "value": "appGlobalState.inputValue"
    },
    {
      "name": "limit",
      "value": 200
    }
  ],
  "isErrorResponse": "response.statusCode !== 200 || response.data.Data.length > 0", //that way you can start error logic
  "processResponse": "",
  "extractResponseData": [
    "return response.data.Data.map(item => { return {\"name\" : item.code, \"value\" : item.id  }) })"
  ]
}

All data from running that query will be saved here

console.log(window.appGlobalState.myCustomQueryResponseSuccess)
console.log(window.appGlobalState.myCustomQueryResponseError)

Reload

{
  "type": "reload",
  "component": "estate-list-table" //componentId that you would like to reload
}

Example

{
  "id": "pagination-page",
  "name": "Pagination page",
  "components": [
    {
      "type": "pagination",
      "id": "samplePagination",
      "onClick": []
    },
    {
      "type": "input",
      "id": "samplePaginationItemsCount",
      "default": 10,
      "onChange": [
        {
          "type": "reload",
          "component": "samplePagination"
        }
      ]
    },
    {
      "type": "input",
      "id": "samplePaginationItemsPerPage",
      "default": 10,
      "onChange": [
        {
          "type": "reload",
          "component": "samplePagination"
        }
      ]
    }
  ]
}

Static data

{
  "type": "static-data",
  "id": "static-data-page-size",
  "dataKeyName": "staticPaginationData",
  "data": [
    {
      "value": 66,
      "name": 66
    },
    {
      "value": 10,
      "name": 10
    },
    {
      "value": 15,
      "name": 15
    },
    {
      "value": 30,
      "name": 30
    }
  ]
}

Example usage

{
  "type": "select",
  "id": "devicesPaginationItemsPerPage",
  "dataKeyName": "staticPaginationData",
  "valueKeyName": "value",
  "labelKeyName": "name",
  "default": 15,
  "onSelect": [
    {
      "type": "javascript",
      "javascript": [
        "appGlobalState.devicesPaginationCurrentPage = 1"
      ]
    },
    {
      "type": "reload",
      "component": "devicesTable"
    },
    {
      "type": "reload",
      "component": "devicesPagination"
    }
  ],
  "onInit": [
    {
      "type": "static-data",
      "id": "static-data-page-size",
      "dataKeyName": "staticPaginationData",
      "data": [
        {
          "value": 5,
          "name": 5
        },
        {
          "value": 10,
          "name": 10
        },
        {
          "value": 15,
          "name": 15
        },
        {
          "value": 30,
          "name": 30
        }
      ]
    }
  ]
}

Components

Button

{
  "type": "button",
  "id": "someButtonId",
  "label": "Delete selected",
  "btnActive": " return 1=1 ", //dynamic condition to determine if btn is clickable
  "visibilityCondition": "",
  "onClick": [],
  "onClickSuccess": [],
  "onClickError": [],
  "onClickFinally": []
}

Details table

Html Tag

Textarea

Form

{
  "type": "form",
  "id": "addEditForm",
  "x": 10,
  "y": 0,
  "width": 550,
  "height": 550,
  "visibilityCondition": "return true",
  "components": []
}

Input

{
  "type": "input",
  "id": "search",
  "default": "",
  "x": 0,
  "y": 10,
  "label": "Search",
  "onChange": [],
  "onFocus": [],
  "onFocusFinally": []
}
    {
      "type": "modal",
      "id": "dataForm",
      "title": "Add / Edit",
      "width": 800,
      "height": 800,
      "visibilityCondition": "true",
      "components": [],
      "onInit": [],
      "onInitSuccess": [],
      "onInitError": [],
      "onInitFinally": []
    }

Pagination

{
  "type": "pagination",
  "id": "pagination",
  "itemsPerPage": 15,
  "visibilityCondition": "true",
  "active": "true",
  "x": 0,
  "y": 780,
  "onClick": [],
  "onClickSuccess": [],
  "onClickError": [],
  "onClickFinally": []
}

Select

{
  "type": "select",
  "id": "orderStatus",
  "valueKeyName": "value", //value from privided data (see data below)
  "labelKeyName": "name", //those values must match
  "label": "Order status",
  "default": "new",
  "multiSelect": false,
  "visibilityCondition": "true",
  "dataKeyName": "orderStatus",
  "x": 900,
  "y": 80,
  "onInit": [
    { //data will be avilable in window.appGlobalState.orderStatus
      "type": "static-data",
      "data": [
        {
          "value": "new",
          "name": "New"
        },
        {
          "value": "paid",
          "name": "Paid"
        },
        {
          "value": "returned",
          "name": "Returned"
        }
      ]
    }
  ],
  "onInitSuccess": [],
  "onInitError": [],
  "onInitFinally": [],
  "onSelect": [],
  "onSelectSuccess": [],
  "onSelectError": [],
  "onSelectFinally": []
}

Table

{
  "type": "table",
  "id": "resultsTable",
  "multiSelect": true,
  "dataKeyName": "orders",
  "visibilityCondition": "return true",
  "x": 10,
  "y": 80,
  "width": 800,
  "defaultRowsSelector": [
    "return [];"
  ],
  "onInit": [],
  "onInitSuccess": [],
  "onInitError": [],
  "onInitFinally": [],
  "onRowSelect": [],
  "onRowSelectFinally": [],
  "fields": [
    {
      "label": "ID",
      "data": "row.id",
      "type": "text"
    },
    {
      "label": "Tokens",
      "data": "{{row.tokens + ' some text'}}",
      "type": "text"
    }
  ]
}

Page components

Actions that you can execute within:

  • onClick
  • onClickSuccess
  • onClickError
  • onClickFinally
  • etc
Last modified April 16, 2024: content fix (a2d9b96)