Switch branches/tags
Nothing to show
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Failed to load latest commit information.
examples
src
test
.babelrc
.env.example
.flowconfig
.gitignore
.travis.yml
README.md
deploy.example.sh
package-lock.json
package.json
webpack.config.js

README.md

blackwidow Build Status

dashboard. works best with quicksilver server, but you can use any backend to get data for widgets

setup

npm install   # install dependencies
npm start     # recompile (or `npm start` to start watcher)
npm test      # run tests

Demo

Example dashboards

Dashboard API

Dashboard is a table (10×10 by default) described by JSON object:

{
  "container": {
    "size": [16, 9]
  },
  "widgets": {
    "bam": {
      "type": "text" // ...
    }
  }
}

⚠️ Any undocumented attributes are prone to changes. A lot of changes ⚠️

  • Object.<string, Object> dashboard: full dashboard
  • DashContainer dashboard.container: dashboard container object
    • number[] DashContainer.size: dashboard size in [x, y] format ([10, 10] by default)
    • Object? DashContainer.style: inline style attribute of dash in react.js format
  • Object.<string, Widget> dashboard.widgets: object with widgets. keys are used to identify widgets
  • Widget dashboard.widgets[key]: widget description
    • string Widget.type: widget type. available values: "text", "image"

    • Container Widget.container: widget container object

        for default case dashboard.container.size = [10, 10]
             x →
       [0, 0]__1__2__3__4__5__6__7__8__9__[10, 0]
        y   |                             |
        ↓   1                             |
            |                             |
            2     ..........              |      `.` => {size: [3, 1], position [3, 2]}
            |     ..........              |
            3     ..........              |
            |                             |
            4                             |
            |                             |
            5#####################        |      `#` => {size: [7, 1], position [0, 5]}
            |#####################        |
            6#####################        |
            |                             |
            7                             |
            |                             |
            8xxxxxx                       |      `x` => {size: [2, 2], position [0, 8]}
            |xxxxxx                       |
            9xxxxxx                       |
            |xxxxxx                       |
      [0, 10]xxxxxx_______________________|
      
      • number[] Container.size: widget size in [x, y] format (see example above)
      • number[] Container.position: position of top left corner of a widget in [x, y] format (see example above)
      • string Container.fontSize: font size for text in widget. em values are recommended
    • WidgetData Widget.data: widget displayed information. keys depend on Widget.type

      • string? WidgetData.note: text if lower right corner of a widget. its fontSize is equal half of Container.fontSize
      • string? WidgetData.text: text for Widget.type = "text"
      • string? WidgetData.src: image url for Widget.type = "image"
    • Endpoint Widget.endpoint: widget's HTTP(S) endpoint object

      • string Endpoint.url: url with WidgetData
      • string? Endpoint.method: HTTP method for WidgetData requests. "GET" by default
      • Object?|string? Endpoint.body: POST request body. If body is an Object, it is passed to JSON.stringify before sending a request
      • Schedule? Endpoint.schedule: schedule for updating WidgetData
        • number? Schedule.timeInterval: interval between requests in seconds
      • Object.<WidgetData[key], PayloadFieldMapping>? Endpoint.map: mapping of endpoint payload to widget data fields. keys are the names of WidgetData field (for example, "note")
        • Object|string PayloadFieldMapping: mapping rules for a single WidgetData field. string-y PayloadFieldMapping's value is a shortcut for {"_expr": value}
          • string PayloadFieldMapping._expr: source of WidgetData field value. See Endpoint Expressions for more details
          • * PayloadFieldMapping[key]: base scope for endpoint expression
    • Local Widget.local: widget's local updates object. Useful for random (yet to be implemented) or date/time widgets. Analogous to Endpoint without HTTP(S) fields

      • Schedule? Local.schedule: schedule for updating WidgetData
        • number? Schedule.timeInterval: interval between requests in seconds
      • Object.<WidgetData[key], PayloadFieldMapping>? Local.map: mapping of endpoint payload to widget data fields. keys are the names of WidgetData field (for example, "note")
        • Object|string PayloadFieldMapping: mapping rules for a single WidgetData field. string-y PayloadFieldMapping's value is a shortcut for {"_expr": value}
          • string PayloadFieldMapping._expr: source of WidgetData field value. See Endpoint Expressions for more details
          • * PayloadFieldMapping[key]: base scope for endpoint expression

Endpoint Expressions

Endpoint Expressions are evaluated via angular-expressions. Expression scope is an object, merged from the response value and the PayloadFieldMapping of the expression. Plus, full response value is available in $ key of the scope

"map": {
  "src": "text"
}

// is equivalent to

"map": {
  "src": {
    "_expr": "text"
  }
}

// is equivalent to

"map": {
  "src": "$.text"
}

// is equivalent to

"map": {
  "src": {
    "_expr": "$[_key]",
    "_key": "text"
  }
}

Expression Filters

A few filters are available for manipulating response before rendering. Some of them are:

  • format:[template] formats template with basic Python-like syntax

    "map": {
      "src": "values | format:'http://example.com/{1}.{2}'"
    }
    
    // for response == {"values": ["how", "are", "you"]}, widget will receive data
    
    {
      "src": "http://example.com/are.you"
    }
  • match:[pattern]:[flags?] matches expression with pattern via RegExp. ⚠️ use four backslashes for escaping

    "map": {
      "text": "text | match:'\\\\d{4}-(\\\\d{2})-(\\\\d{2})' | format:'{2}.{1}'"
    }
    
    // for response == {"text": "2015-09-13"}, widget will receive data
    
    {
      "text": "13.09"
    }
  • map:[mapping] maps items of array expressions with passed mapping

    "map": {
      "values": {
        "_expr": "text | match:'[a-z]+':'ig' | map:_map",
        "_map": {"value": "$"}
      }
    }
    
    // for response == {"text": "Mal|Zoe|Wash"}, widget will receive data
    
    {
      "values": [
        {"value": "Mal"},
        {"value": "Zoe"},
        {"value": "Wash"}
      ]
    }
  • get:[key] for getting specific keys from already filtered expressions

    "map": {
      "text": "text | match:'[a-z]+':'ig' | get:0"
    }
    
    // for response == {"text": "Mal|Zoe|Wash"}, widget will receive data
    
    {
      "text": "Mal"
    }
  • timeSince:[units?] returns time interval since received date (parsed via new Date()) in units ('days' by default). Possible units: 's', 'm', 'h', 'd', 'seconds', 'minutes', 'hours', 'days'

    "map": {
      "text": "0 | timeSince:'seconds'"
    }
    
    // widget will receive, for example
    
    {
      "text": 1455091752
    }
  • timeUntil:[units?] returns time interval until received date (parsed via new Date()) in units ('days' by default). Possible units: 's', 'm', 'h', 'd', 'seconds', 'minutes', 'hours', 'days'

    "map": {
      "text": "'2016-09-13' | timeUntil:'days'"
    }
    
    // widget will receive, for example
    
    {
      "text": 215
    }