Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Dashboard: Allow control over whether it's possible to install Dashboard as a PWA #1616

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open
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
27 changes: 26 additions & 1 deletion docs/nodes/config/ui-base.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,13 @@ _Example of how the 'App Icon' looks on a browser tab_
![Example of how the 'App Icon' looks](/images/node-examples/ui-base-app-icon-launcher.png "Example of how the 'App Icon' looks"){data-zoomable style="max-width: 200px; margin: auto"}
_Example of how the 'App Icon' appears when installed onto an iPhone_

## Title Bar Style Options <AddedIn version="1.10.0" />
## Allow Install <AddedIn version="1.23.0" />

It is possible to install any FlowFuse Dashboard applications as a Progressive Web App onto a desktop or mobile device, giving the appearance and user-experience of a native mobile application. You can read more about that functionality [here](../../user/pwa.md).

The "Allow Install" option provides the capability to enable/disable the option to "Install" your Dashboard as an application. If you are using FlowFuse authentication, this is recommended, as the PWA workers cache content separate from authentication sessions.

## Header Style Options <AddedIn version="1.10.0" />

### Title Bar - Default

Expand All @@ -61,6 +67,25 @@ The title bar is not visible at all. Note that it is still possible to see the n
![Example of how the 'Hidden' option looks](/images/node-examples/ui-base-appbar-hidden.png "Example of how the 'Hidden' option looks"){data-zoomable}
_Example of how the 'Hidden' option looks_

## Header Content Options <AddedIn version="1.10.0" />

Defines the text that is shown in the main page title.

### Page Name

This will show the active page's name. Between each page change, this will be updated to reflect the new page's name.

### Dashboard Name

This will use the Dashboard's name, and be consistent across all pages in your application.

### Dashboard Name (Page Name)

This will combine the previous two options, and display both the Dashboard name and Page name, with the latter inside brackets.

### None

There will be no text-based title shown. Often used in partnership with [Teleports](../../nodes/widgets/ui-template.md#teleports) in order to customise the content in this section, e.g. including logos.


## Navigation Style Options <AddedIn version="1.2.0" />
Expand Down
61 changes: 50 additions & 11 deletions nodes/config/locales/en-US/ui_base.html
Original file line number Diff line number Diff line change
@@ -1,27 +1,66 @@
<script type="text/html" data-help-name="ui-base">
<p>UI Base</p>
<a href="https://dashboard.flowfuse.com/nodes/config/ui-base.html" target="_blank" style="display: block; margin-bottom: 6px;">Online Documentation</a>
<p>This is the foundational element for a Dashboard in Node-RED Dashboard 2.0</p>
<p>A Dashboard is driven by a baseline layout which can be modified with some of the following settings</p>
<dl class="message-properties">
<dt>
App Icon
<span class="property-type">strong</span>
</dt>
<dd>
You can provide a custom URL for your application's icon, which will be displayed as the app icon and in the browser tab.
</dd>
</dl>
<dl class="message-properties">
<dt>
Allow App Installation
<span class="property-type">boolean</span>
</dt>
<dd>
<p>Permits a user to install the Dashboard as a Progressive Web Application on their mobile or desktop device. This will mimic the behaviour of a native application.</p>
<p>It is recommended to not use this option if you are </p>
</dd>
</dl>
<dl class="message-properties">
<dt>
Header Style
<span class="property-type">option</span>
</dt>
<dd>
<ul>
<li><b>Default: </b>(default) The title bar will appear as the first element, and scroll with the content, meaning that on longer pages, the title bar will not be visible when the page is scrolled.</li>
<li><b>Hidden: </b>The title bar is not visible at all.</li>
<li><b>Fixed: </b>The title bar will always be visible, even when the page is scrolled. </li>
</ul>
</dd>
</dl>
<dl class="message-properties">
<dt>
Header Content
<span class="property-type">option</span>
</dt>
<dd>
<ul>
<li><b>Page Name: </b>(default) This open will shift the entire content of the Dashboard when opened, and not be visible at all when closed.</li>
<li><b>Dashboard Name: </b>Will always remain open. At our mobile breakpoint (768px), this value is overridden, and an "Appear Over" option is used.</li>
<li><b>Dashboard Name (Page Name): </b>Similar to "Collapsing" when opened, but when closed, the icons for each page still show.</li>
<li><b>None: </b>The title bar is not visible at all. </li>
</ul>
</dd>
</dl>
<dl class="message-properties">
<dt>
Sidebar Style
<span class="property-type">option</span>
</dt>
<dd>
<ul>
<li><b>Collapsing: </b>(default) This open will shift the entire content of the Dashboard when opened, and not be visisble at all when closed.</li>
<li><b>Fixed: </b>Will always remain open. At our mobile breakdpoint (768px), this value is overriden, and an "Appear Over" option is used.</li>
<li><b>Collapsing: </b>(default) This open will shift the entire content of the Dashboard when opened, and not be visible at all when closed.</li>
<li><b>Fixed: </b>Will always remain open. At our mobile breakpoint (768px), this value is overridden, and an "Appear Over" option is used.</li>
<li><b>Collapse to icons: </b>Similar to "Collapsing" when opened, but when closed, the icons for each page still show.</li>
<li><b>Appear over content: </b>Not visible when closed, and when open, will appear over the Dashboard content, without shifting it.</li>
<li><b>Always hide: </b>The sidebar will not be visible under any circumstances. All pages are still accesible via their direct links or a <code>ui-control</code> node.</li>
<li><b>Always hide: </b>The sidebar will not be visible under any circumstances. All pages are still accessible via their direct links or a <code>ui-control</code> node.</li>
</ul>
</dd>
</dl>
<dt>
App Icon
<span class="property-type">URL</span>
</dt>
<dd>
You can provide a custom URL for your application's icon, which will be displayed as the app icon and in the browser tab.
</dd>
</script>
4 changes: 3 additions & 1 deletion nodes/config/locales/en-US/ui_base.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,9 @@
"connectionNotifications": "Connection Notifications",
"showReconnect": "Show reconnect notification",
"showDisconnect": "Show disconnect notification",
"notificationDisplayTime": "notification display time (seconds)"
"notificationDisplayTime": "notification display time (seconds)",
"allowInstall": "Allow App Installation",
"installation": "Installation Options"
},
"layout": {
"pages": "Pages",
Expand Down
15 changes: 15 additions & 0 deletions nodes/config/ui_base.html
Original file line number Diff line number Diff line change
Expand Up @@ -406,6 +406,9 @@
},
showDisconnectNotification: {
value: true
},
allowInstall: {
value: true
}
},
label: function () {
Expand Down Expand Up @@ -455,6 +458,11 @@
this.showDisconnectNotification = true
$('#node-config-input-showDisconnectNotification').prop('checked', true)
}
// backward compatibility for allowing PWA install
if (!('allowInstall' in this)) {
this.allowInstall = true
$('#node-config-input-allowInstall').prop('checked', true)
}
},
onpaletteadd: function () {
// add the Dashboard 2.0 sidebar
Expand Down Expand Up @@ -2441,6 +2449,13 @@
<input type="text" id="node-config-input-appIcon">
<span style="display: block; margin-left: 105px; margin-top: 0px; font-style: italic; color: #bbb; font-size: 8pt;">Enter the url of your app icon here</span>
</div>
<div class="form-row" style="margin-bottom: 0;">
<label style="font-weight: 600; width: auto;" data-i18n="ui-base.label.installation"></label>
</div>
<div class="form-row form-row-flex" style="align-items: center;">
<input style="margin: 8px 0 10px 16px; width:20px;" type="checkbox" id="node-config-input-allowInstall">
<label style="width:auto" for="node-config-input-allowInstall"><span data-i18n="ui-base.label.allowInstall"></span></label>
</div>
<div class="form-row" style="margin-bottom: 0;">
<label style="font-weight: 600; width: auto;" data-i18n="ui-base.label.header"></label>
</div>
Expand Down
4 changes: 4 additions & 0 deletions nodes/config/ui_base.js
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,10 @@ module.exports = function (RED) {
config.notificationDisplayTime = 5 // Show for 5 seconds
}

if (!('allowInstall' in config)) {
config.allowInstall = true // Show for 5 seconds
}

// The headerContent replaces the old (boolean) showPageTitle
if (!('headerContent' in config)) {
const showPageTitle = ('showPageTitle' in config) ? config.showPageTitle : true
Expand Down
1 change: 0 additions & 1 deletion ui/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
<link href="data:image/x-icon;base64,AAABAAEAEBAQAAAAAAAoAQAAFgAAACgAAAAQAAAAIAAAAAEABAAAAAAAgAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAsC8qAP+EAACzh1cAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAAAAAAAACAAAAAAAAACAAAAAAAAEiAAAAADAAAiAAAAAAMzAiAAAAAAAAMzAAAAAAAAAiMzMAAAAAAAADAzAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA//8AAP//AAD//wAA" rel="icon" type="image/x-icon">
<link rel="alternate icon" href="/favicon.ico" type="image/png" sizes="16x16">
<link rel="apple-touch-icon" href="/apple-touch-icon.png" sizes="180x180">
<link rel="manifest" crossorigin="use-credentials" href="./manifest.webmanifest">
<!-- Auto light and dark mode switching of status bar -->
<meta name="theme-color" media="(prefers-color-scheme: light)" content="white" />
<meta name="theme-color" media="(prefers-color-scheme: dark)" content="#111" />
Expand Down
19 changes: 19 additions & 0 deletions ui/src/App.vue
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,25 @@ export default {
loading: true
}
},
head () {
const links = []
// get default dashboard
if (this.dashboards) {
const dashboards = Object.keys(this.dashboards)
const id = dashboards.length ? dashboards[0] : undefined
const dashboard = this.dashboards[id]
if (dashboard.allowInstall) {
links.push({
rel: 'manifest',
crossorigin: 'use-credentials',
href: './manifest.webmanifest'
})
}
}
return {
link: links
}
},
computed: {
...mapState('ui', ['dashboards', 'pages', 'widgets']),
...mapState('setup', ['setup', 'error']),
Expand Down
Loading