Skip to content

InverterOfControl/dashly

Repository files navigation

Dashly

Configurable Vue 3 dashboard: drag-and-resize tiles on a grid, persist layout in the browser, and extend with new tile types. Built with Vite, TypeScript, vue-ts-responsive-grid-layout, and AJV for JSON Schema validation on API tiles.

Run locally

npm install
npm run dev
npm run build
npm run preview

Display vs edit

The dashboard opens in Display mode: tiles cannot be moved or resized, and tile chrome has no Configure/Remove actions. Use Edit dashboard to change layout and settings; Done returns to Display mode. The active mode is stored in localStorage under dashly-dashboard-mode (display or edit).

TV mode (toolbar): hides tile chrome (title / configure / remove) and Refresh on API, API + Markdown, and API-number tiles for a cleaner wall display; text tiles hide their header only (body stays). Switches to Display mode automatically. Persisted under dashly-tv-mode (1 / 0). Use Exit TV mode to restore.

Dark mode: Toolbar icons — Moon switches to dark theme, Sun switches back to light. Preference is stored under dashly-theme (dark / light).

Features

  • Grid: In Edit mode, drag tiles by the header (.tile-drag-handle) and resize from the corner handle. Display mode locks layout and hides tile edit actions. TV mode (toolbar) hides tile chrome on all tiles and the refresh bar on API / API + Markdown / API-number tiles only. Layout and tile settings are stored under localStorage key dashly-dashboard-v1.
  • Export / Import: In Edit mode, use the toolbar JSON dropdown (Export JSON, Import JSON). Export JSON is also in that menu on Display mode for backups. Writes or reads a JSON document (version, colNum, rowHeight, margin, tiles).
  • API tile: GET/POST/… to a URL with optional headers/body, optional polling, optional JSON Schema (draft 2020-12) validation (AJV + ajv-formats), and optional property display: newline-separated JSON Pointers (e.g. /id, /title) in configure — leave empty to show the full JSON body.
  • API + Markdown tile: Same HTTP options and optional JSON Schema validation as the API tile. Markdown is first rendered as a Nunjucks template (json contains the full response, top-level object keys are exposed directly), then converted with marked and sanitized with DOMPurify before v-html. Legacy JSON Pointer placeholders {{/path}} (RFC 6901) still work and are interpolated before Nunjucks.
  • API number tile: Same HTTP options as the API tile, but the JSON response must yield one finite number — either the root value (42) or a field addressed by an optional JSON Pointer (e.g. /id). The value is shown large in the tile body with an optional label above the number (valueTitle); the chrome title is separate static text.

API + Markdown template examples

Assume your API response has fields like:

{
  "title": "Deploy completed",
  "publishedAt": "2026-05-07T14:36:22Z",
  "createdAtUnix": 1778164582,
  "meta": {
    "tz": "Europe/Berlin"
  }
}

Basic fields and conditionals:

## {{ title }}

{% if json.meta %}
Has metadata.
{% else %}
No metadata.
{% endif %}

Legacy JSON Pointer placeholder still works:

### Same title via pointer
{{ /title }}

Date parsing and formatting:

Published (ISO): {{ publishedAt | dateISO }}
Published (US short): {{ publishedAt | dateFormat("en-US", "datetime", "short,short") }}
Published (German long): {{ publishedAt | dateFormat("de-DE", "datetime", "long,short") }}
Published (Berlin TZ): {{ publishedAt | dateFormat("de-DE", "datetime", "long,short", "Europe/Berlin") }}

Unix timestamp support (fromUnix):

Created (unix seconds): {{ createdAtUnix | fromUnix("s") | dateFormat("en-GB", "datetime", "medium,short") }}

The available date helpers are:

  • dateISO: parse value and output ISO string
  • dateFormat(locale, preset, styles, timeZone?): locale-aware formatting
  • fromUnix(unit): convert Unix timestamp to Date ("s" or "ms")

CORS and proxies

Browsers only allow cross-origin fetch when the target API sends appropriate CORS headers. For development, this project includes a Vite proxy: URLs starting with /api-proxy/... are forwarded to https://jsonplaceholder.typicode.com (see vite.config.ts). Point an API tile at e.g. /api-proxy/posts/1 while running npm run dev.

For production, serve the app and APIs from the same origin or put a gateway in front.

Add a new tile type

  1. Create a Vue component under src/tiles/types/<name>/ that accepts config: Record<string, unknown> and emits configure and remove (see TextTile.vue).
  2. Add a defaultConfig() factory in src/tiles/tileConfigs.ts if you want typed defaults.
  3. Register the type in src/tiles/registry.ts.
  4. Teach TileConfigureDialog.vue how to edit that tile’s config (forms or JSON fields).

The grid renders getTileDefinition(tile.type).component dynamically, so new types show up in Add tile automatically after registration.

Dashboard JSON shape

{
  "version": 1,
  "colNum": 12,
  "rowHeight": 36,
  "margin": [10, 10],
  "tiles": [
    {
      "id": "uuid",
      "type": "text",
      "layout": { "x": 0, "y": 0, "w": 4, "h": 4 },
      "config": { "title": "", "body": "" }
    },
    {
      "id": "uuid",
      "type": "api",
      "layout": { "x": 0, "y": 0, "w": 4, "h": 4 },
      "config": {
        "title": "",
        "url": "https://…",
        "displayPathsText": "/id\n/title",
        "responseSchemaText": "{ … }"
      }
    },
    {
      "id": "uuid",
      "type": "apiMarkdown",
      "layout": { "x": 0, "y": 0, "w": 4, "h": 4 },
      "config": {
        "title": "",
        "url": "https://…",
        "markdownTemplate": "## {{ /title }}\n\n{% if body %}{{ body }}{% else %}_No body_{% endif %}",
        "responseSchemaText": "{ … }"
      }
    }
  ]
}

Notes

  • The grid package lists style.css in exports but ships vue-ts-responsive-grid-layout.css; the app imports the CSS file from node_modules directly in src/main.ts.
  • Upstream typings use a misspelled "typeings" field in package.json, so src/env.d.ts declares the module for vue-tsc.

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors