Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 37 additions & 0 deletions edge-apps/puzzel-dashboard/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# Puzzel Dashboard

A Screenly Edge App that embeds the [Puzzel](https://www.puzzel.com/) admin dashboard in a full-screen iframe and automatically logs in using injected credentials.

## How it works

1. The player loads `index.html`, which renders a full-screen iframe pointing at the configured `dashboard_url`.
2. On each load the player injects `screenly_inject.js` into the dashboard page and supplies the configured credentials via `screenly_settings`.
3. The inject script detects the Puzzel login pages by their input field IDs and fills them automatically — no manual login required on the screen.

## Settings

| Key | Type | Description |
| --------------- | ------------ | -------------------------------------------------------------------------------------------------- |
| `dashboard_url` | string (URL) | The URL of the Puzzel dashboard to display (default: `https://app.puzzel.com/admin/app/dashboard`) |
| `username` | string | Puzzel account email (Puzzel ID) |
| `password` | secret | Puzzel account password (stored encrypted) |

## Login page selectors

The inject script handles Puzzel's two-step login at `https://app.puzzel.com/id/Account/Login`:

| Step | Field | Selector |
| ------------ | ----------------- | -------------------------------------------------- |
| 1 – Username | Puzzel ID (email) | `#Input_Username` |
| 1 – Submit | Next button | `button.submit-button[type="submit"]:not(.hidden)` |
| 2 – Password | Password | `#Input_Password` |
| 2 – Submit | Sign-in button | `button.submit-button[type="submit"]:not(.hidden)` |

The script detects which step is active by checking for the presence of `#Input_Username` or `#Input_Password` — no path matching required.

## Deploying

```shell
screenly edge-app create --name puzzel-dashboard --in-place
screenly edge-app deploy
```
21 changes: 21 additions & 0 deletions edge-apps/puzzel-dashboard/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Puzzel Dashboard - Screenly Edge App</title>
<link rel="stylesheet" href="static/css/style.css" />
</head>

<body>
<iframe
id="dashboard"
src="about:blank"
title="Puzzel Dashboard"
allowfullscreen
></iframe>

<script src="screenly.js?version=1"></script>
<script src="static/js/main.js"></script>
</body>
</html>
40 changes: 40 additions & 0 deletions edge-apps/puzzel-dashboard/screenly.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
---
syntax: manifest_v1
id:
description: Puzzel Dashboard
icon: https://playground.srly.io/edge-apps/puzzel-dashboard/static/img/icon.svg
author: Screenly, Inc.
categories:
- Dashboards
ready_signal: true
settings:
dashboard_url:
type: string
title: Dashboard URL
optional: false
default_value: 'https://app.puzzel.com/admin/app/dashboard'
help_text:
schema_version: 1
properties:
help_text: The URL of the dashboard to display.
type: url
password:
type: secret
title: Password
optional: false
default_value: ''
help_text:
schema_version: 1
properties:
help_text: The password used to log in to the dashboard.
type: string
username:
type: string
title: Puzzel ID
optional: false
default_value: ''
help_text:
schema_version: 1
properties:
help_text: The username used to log in to the dashboard.
type: string
Comment thread
salmanfarisvp marked this conversation as resolved.
51 changes: 51 additions & 0 deletions edge-apps/puzzel-dashboard/screenly_inject.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
// Injected by the player into the dashboard page on every load.
// `screenly_settings` is provided by the player — no import needed.
// This script runs AFTER the page has fully loaded; DOMContentLoaded has
// already fired. Manipulate the DOM directly.

/* global screenly_settings, Event */

// Set an input's value and notify change listeners.
function setValue(selector, value) {
const el = document.querySelector(selector)
if (!el) return false
el.value = value
el.dispatchEvent(new Event('change', { bubbles: true }))
return true
}

// ---- Puzzel (app.puzzel.com) ------------------------------------------------
// Selectors confirmed against https://app.puzzel.com/id/Account/Login
// Two-step login: username first, then password on the next page load.

// Step 1 — username/Puzzel ID field
if (document.querySelector('#Input_Username')) {
if (!setValue('#Input_Username', screenly_settings.username)) {
console.log('[screenly_inject] Username field not found.')
} else {
const submitBtn = document.querySelector(
'button.submit-button[type="submit"]:not(.hidden)',
)
if (submitBtn) {
submitBtn.click()
} else {
console.log('[screenly_inject] Submit button not found.')
}
}
}

// Step 2 — password field
if (document.querySelector('#Input_Password')) {
if (!setValue('#Input_Password', screenly_settings.password)) {
console.log('[screenly_inject] Password field not found.')
} else {
const submitBtn = document.querySelector(
'button.submit-button[type="submit"]:not(.hidden)',
)
if (submitBtn) {
submitBtn.click()
} else {
console.log('[screenly_inject] Submit button not found.')
}
}
}
40 changes: 40 additions & 0 deletions edge-apps/puzzel-dashboard/screenly_qc.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
---
syntax: manifest_v1
id:
description: Puzzel Dashboard
icon: https://playground.srly.io/edge-apps/puzzel-dashboard/static/img/icon.svg
author: Screenly, Inc.
categories:
- Dashboards
ready_signal: true
settings:
dashboard_url:
type: string
title: Dashboard URL
optional: false
default_value: 'https://app.puzzel.com/admin/app/dashboard'
help_text:
schema_version: 1
properties:
help_text: The URL of the dashboard to display.
type: url
password:
type: secret
title: Password
optional: false
default_value: ''
help_text:
schema_version: 1
properties:
help_text: The password used to log in to the dashboard.
type: string
username:
type: string
title: Puzzel ID
optional: false
default_value: ''
help_text:
schema_version: 1
properties:
help_text: The username used to log in to the dashboard.
type: string
21 changes: 21 additions & 0 deletions edge-apps/puzzel-dashboard/static/css/style.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
*,
*::before,
*::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}

html,
body {
width: 100%;
height: 100%;
overflow: hidden;
}

iframe {
display: block;
width: 100%;
height: 100%;
border: none;
}
1 change: 1 addition & 0 deletions edge-apps/puzzel-dashboard/static/img/icon.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
14 changes: 14 additions & 0 deletions edge-apps/puzzel-dashboard/static/js/main.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
/* global screenly */

document.addEventListener('DOMContentLoaded', async () => {
const settings = screenly.settings
const url = settings.dashboard_url

if (!url) {
console.error('Please specify a dashboard URL')
return
}
Comment thread
salmanfarisvp marked this conversation as resolved.

document.getElementById('dashboard').src = url
screenly.signalReadyForRendering()
})