Skip to content

Commit bd52584

Browse files
ghyskaikreuzer
authored andcommitted
Cosmetic changes, handle static files in UIService (openhab#180)
* Cosmetic changes, handle static files in UIService Restore the serving of static files through the UIService (the Jetty handler doesn't seem to take precedence). Add missing images for Basic UI and CometVisu, cleanup temporary screenshot images. Add description and author info for the Cordova app. Rename "default UI" to "main UI". Add version info in webapp initialization. Adjust HABPanel dependencies. Update README.md and CONTRIBUTING.md files. Signed-off-by: Yannick Schaus <[email protected]>
1 parent 0999145 commit bd52584

File tree

21 files changed

+146
-101
lines changed

21 files changed

+146
-101
lines changed
+50
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
# Contributing to the openHAB UI
2+
3+
The [standard contributing and community guidelines for the openHAB project](https://github.com/openhab/openhab-core/blob/master/CONTRIBUTING.md), including signing off your commits, also apply for the development of the UI.
4+
5+
The repository for web user interfaces, including this project, is located at https://github.com/openhab/openhab-webui and the code of this project, including this file, is found in the `bundles/org.openhab.ui` folder.
6+
7+
## Prerequisites
8+
9+
This project is built using [Vue.js](https://vuejs.org/), [webpack](https://webpack.js.org/) and [Framework7](https://framework7.io).
10+
11+
You need Node 8.10.0 or later and npm 5.6.0. Change to the `web` directory, gather the necessary dependencies with `npm install` then the scripts below will be available.
12+
13+
## NPM Scripts
14+
15+
* `npm start` - run the development server (see below)
16+
* `npm run build-prod` - build web app for production (note: no need to prepare a production version when submitting a PR, the build server will do it)
17+
* `npm run build-cordova-prod` - build cordova's `www` folder from source and build a Cordova app
18+
* `npm run test:unit` - start the Jest test runner and run the unit tests
19+
* `npm run test:unit:watch` - start the Jest test runner, run the unit tests, keep running and watch for changes
20+
* `npm run test:e2e` - start Cypress and run the e2e tests
21+
* `npm run test:e2e:gui` - open the Cypress GUI
22+
23+
## Development server
24+
25+
Before starting the development server with `npm start`, you should have an instance of openHAB (either a complete distribution or the demo app) running on _localhost:8080_.
26+
The development server will run on the next available port (for instance, 8081) and proxy requests to well-known openHAB URLs like the REST API or icon servlet, forwarding them to their equivalent on port 8080.
27+
If you wish to change the target of these forwards, allowing to target a remote instance, look for `const apiBaseUrl` in `build/webpack.config.js` and change it accordingly before starting the server.
28+
Don't commit changes to the base URL to avoid confusing others!
29+
30+
You can also run the unit tests (`test/jest`) and e2e (`test/cypress`) tests using the abovementioned commands.
31+
Cypress is configured to assume the development server is running on port 8081 - you can change that in `cypress.json` but again, remember not to commit.
32+
You can also use Majestic GUI to run the unit tests and temporarily collect code coverage and view coverage reports (it is disabled by default for performance reasons): install it globally with `npm install -g majestic`, and run `majestic` in the root web folder to open Majestic in a browser window.
33+
34+
## PWA
35+
36+
This is a PWA. Don't forget to check what is inside of your `service-worker.js`. It is also recommended that you disable the service worker (or enable "Update on reload") in your browser's dev tools during development.
37+
38+
## Cordova
39+
40+
The Cordova project is located in the `cordova` folder. You shouldn't modify content of the `cordova/www` folder. Its content will be correctly generated when you call `npm run cordova-build-prod`.
41+
42+
## Documentation & Resources
43+
44+
### Framework7
45+
46+
* [Framework7 Core Documentation](https://framework7.io/docs/)
47+
* [Framework7 Vue Documentation](https://framework7.io/vue/)
48+
49+
* [Framework7 Icons Reference](https://framework7.io/icons/)
50+
* [Community Forum](https://forum.framework7.io)

bundles/org.openhab.ui/README.md

+4-2
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1-
# Default UI
1+
# openHAB UI
22

3-
This is openHAB's default UI.
3+
This is openHAB's main UI.
4+
5+
See [CONTRIBUTING](CONTRIBUTING.md) for more information about developing this web application.

bundles/org.openhab.ui/pom.xml

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
</parent>
99

1010
<artifactId>org.openhab.ui</artifactId>
11-
<name>openHAB UI :: Bundles :: Default UI</name>
11+
<name>openHAB UI :: Bundles :: Main UI</name>
1212

1313
<dependencies>
1414
<dependency>

bundles/org.openhab.ui/src/main/java/org/openhab/ui/internal/UIService.java

+42-3
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,15 @@
1212
*/
1313
package org.openhab.ui.internal;
1414

15+
import java.io.IOException;
16+
import java.net.MalformedURLException;
17+
import java.net.URL;
1518
import java.util.Map;
1619

20+
import javax.servlet.http.HttpServletRequest;
21+
import javax.servlet.http.HttpServletResponse;
22+
23+
import org.openhab.core.config.core.ConfigConstants;
1724
import org.openhab.core.net.HttpServiceUtil;
1825
import org.osgi.framework.BundleContext;
1926
import org.osgi.service.component.ComponentContext;
@@ -33,18 +40,50 @@
3340
* @author Yannick Schaus - Initial contribution
3441
*/
3542
@Component(immediate = true, name = "org.openhab.ui")
36-
public class UIService {
43+
public class UIService implements HttpContext {
44+
45+
private static final String APP_BASE = "app";
46+
private static final String STATIC_PATH = "/static";
47+
private static final String STATIC_BASE = ConfigConstants.getConfigFolder() + "/html";
3748

3849
private final Logger logger = LoggerFactory.getLogger(UIService.class);
3950

4051
protected HttpService httpService;
52+
protected HttpContext defaultHttpContext;
53+
54+
@Override
55+
public boolean handleSecurity(HttpServletRequest request, HttpServletResponse response) throws IOException {
56+
return defaultHttpContext.handleSecurity(request, response);
57+
}
58+
59+
@Override
60+
public URL getResource(String name) {
61+
if (name.startsWith(APP_BASE + STATIC_PATH) && !name.endsWith("/")) {
62+
try {
63+
URL url = new java.io.File(STATIC_BASE + name.substring(new String(APP_BASE + STATIC_PATH).length()))
64+
.toURI().toURL();
65+
logger.trace("Serving static file from {}", url);
66+
return url;
67+
} catch (MalformedURLException e) {
68+
logger.error("Error while serving static content: {}", e.getMessage());
69+
return defaultHttpContext.getResource(name);
70+
}
71+
} else {
72+
return defaultHttpContext.getResource(name);
73+
}
74+
}
75+
76+
@Override
77+
public String getMimeType(String name) {
78+
return defaultHttpContext.getMimeType(name);
79+
}
4180

4281
@Activate
4382
protected void activate(ComponentContext componentContext, Map<String, Object> properties) {
4483
BundleContext bundleContext = componentContext.getBundleContext();
45-
HttpContext httpContext = httpService.createDefaultHttpContext();
84+
defaultHttpContext = httpService.createDefaultHttpContext();
4685
try {
47-
httpService.registerResources("/", "app", httpContext);
86+
httpService.registerResources("/", APP_BASE, this);
4887
if (HttpServiceUtil.getHttpServicePort(bundleContext) > 0) {
4988
logger.info("Started UI on port {}", HttpServiceUtil.getHttpServicePort(bundleContext));
5089
} else {

bundles/org.openhab.ui/web/README.md

-68
This file was deleted.

bundles/org.openhab.ui/web/cordova/config.xml

+5-3
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,12 @@
22
<widget id="org.openhab.ui" version="3.0.0" xmlns="http://www.w3.org/ns/widgets" xmlns:cdv="http://cordova.apache.org/ns/1.0">
33
<name>openHAB</name>
44
<description>
5-
A sample Apache Cordova application that responds to the deviceready event.
5+
This is a version of the openHAB user interface packaged as an app.
6+
The open Home Automation Bus (openHAB) project aims at providing a universal integration platform for all things around home automation.
7+
It is designed to be absolutely vendor-neutral as well as hardware/protocol-agnostic.
68
</description>
7-
<author email="[email protected].org" href="http://cordova.io">
8-
Apache Cordova Team
9+
<author email="info@openhab.org" href="https://openhab.org">
10+
Contributors to the openHAB project
911
</author>
1012
<content src="index.html" />
1113
<plugin name="cordova-plugin-whitelist" spec="1" />

bundles/org.openhab.ui/web/jest.config.js

+2-1
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,8 @@ module.exports = {
4646
'^framework7$': '<rootDir>/node_modules/framework7/framework7.esm.bundle.js',
4747
'^f7vue$': '<rootDir>/node_modules/framework7-vue/framework7-vue.esm.bundle.js',
4848
'^src/(.*)$': '<rootDir>/src/$1',
49-
'.*css$': '<rootDir>/test/jest/utils/stub.css'
49+
'^@/(.*)$': '<rootDir>/src/$1',
50+
// '.*css$': '<rootDir>/test/jest/utils/stub.css'
5051
},
5152
transform: {
5253
'.*\\.(vue)$': '<rootDir>/node_modules/vue-jest',

bundles/org.openhab.ui/web/src/components/app.vue

+1
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,7 @@ export default {
153153
f7params: {
154154
id: 'org.openhab.ui', // App bundle ID
155155
name: 'openHAB', // App name
156+
version: '3.0.0', // App version, TODO retrieve from the server (with the build information)
156157
theme: theme || 'auto',
157158
// theme: (document.documentURI && document.documentURI.indexOf('?theme=ios') > 0) ? 'ios'
158159
// : (document.documentURI && document.documentURI.indexOf('?theme=md') > 0) ? 'md'

bundles/org.openhab.ui/web/src/components/config/controls/parameter-options.vue

+1-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ export default {
1616
data () {
1717
return {
1818
smartSelectParams: {
19-
view: this.$f7.view.main
19+
view: (this.$f7) ? this.$f7.view.main : null
2020
}
2121
}
2222
},

bundles/org.openhab.ui/web/src/components/home/other-apps.vue

+24-13
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,28 @@
11
<template>
2-
<div class="row app-links">
3-
<f7-link class="app-link col-50 medium-33 large-33 xlarge-25" v-for="app in apps" :key="app.url" :href="app.url.replace(/^\.\./, '')" external target="_blank">
4-
<f7-card class="app-card">
5-
<f7-card-content :padding="false">
6-
<!-- <img :src="'res/img/dashboard-tiles-tmp/basicui.png'" width="100%"> -->
7-
<img :src="app.imageUrl.replace(/^\.\./, '')" width="100%">
8-
</f7-card-content>
9-
<f7-card-footer>
10-
<div class="app-card-name">{{app.name}}</div>
11-
</f7-card-footer>
12-
</f7-card>
13-
</f7-link>
14-
</div>
2+
<f7-block class="block-narrow" v-show="apps && apps.length">
3+
<f7-row>
4+
<f7-col>
5+
<div class="row app-links">
6+
<div class="app-link col-50" v-for="app in apps" :key="app.url" :href="app.url.replace(/^\.\./, '')" external target="_blank">
7+
<f7-link class="app-link" :href="app.url.replace(/^\.\./, '')" external target="_blank">
8+
<f7-card class="app-card">
9+
<f7-card-content :padding="false" :style="{
10+
'height': '200px',
11+
'background-image': 'url(' + app.imageUrl.replace(/^\.\./, '') + ')',
12+
'background-size': 'cover',
13+
'background-repeat': 'no-repeat'
14+
}">
15+
</f7-card-content>
16+
<f7-card-footer>
17+
<div class="app-card-name">{{app.name}}</div>
18+
</f7-card-footer>
19+
</f7-card>
20+
</f7-link>
21+
</div>
22+
</div>
23+
</f7-col>
24+
</f7-row>
25+
</f7-block>
1526
</template>
1627

1728
<script>

bundles/org.openhab.ui/web/src/pages/about.vue

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<template>
22
<f7-page name="about" class="page-about">
3-
<f7-navbar title-large="About" title="About" back-link="Back"></f7-navbar>
3+
<f7-navbar large title-large="About" title="About" back-link="Back"></f7-navbar>
44
<f7-block class="block-narrow after-big-title">
55
<f7-row>
66
<f7-col>

bundles/org.openhab.ui/web/src/pages/home.vue

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<template>
22
<f7-page stacked name="HomePage" class="page-home" @page:init="onPageInit">
3-
<f7-navbar :large-transparent="true">
3+
<f7-navbar :large="$f7.data.themeOptions.homeNavbar !== 'simple'" :large-transparent="true">
44
<f7-nav-left>
55
<f7-link icon-ios="f7:menu" icon-aurora="f7:menu" icon-md="material:menu" panel-open="left"></f7-link>
66
</f7-nav-left>

bundles/org.openhab.ui/web/src/pages/settings/settings-menu.vue

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<template>
22
<f7-page @page:init="onPageInit" @page:afterin="onPageAfterIn" class="page-settings">
3-
<f7-navbar :large-transparent="false" title-large="Settings" title="Settings" back-link="Back" back-link-url="/home/" back-link-force>
3+
<f7-navbar large :large-transparent="false" title-large="Settings" title="Settings" back-link="Back" back-link-url="/home/" back-link-force>
44
<f7-nav-right>
55
<f7-link
66
class="searchbar-enable"
Loading
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading

bundles/org.openhab.ui/web/test/jest/__tests__/config-parameter.test.js

+12-5
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,8 @@ describe('ConfigParameter', () => {
1111
name: 'test',
1212
description: 'Test Parameter',
1313
type: 'TEXT',
14-
options: ['choice', 'choice2']
14+
options: ['choice', 'choice2'],
15+
limitToOptions: true
1516
}
1617
const wrapper = shallowMount(ConfigParameter, {
1718
propsData: {
@@ -23,11 +24,17 @@ describe('ConfigParameter', () => {
2324
it('is a Vue instance', () => {
2425
expect(wrapper.isVueInstance()).toBeTruthy()
2526
})
26-
it('shows a list of options', () => {
27-
expect(wrapper.vm.smartSelectParams).toBeDefined()
28-
expect(wrapper.vm.smartSelectParams.openIn).toBe('popover')
27+
it('is an option control', () => {
28+
expect(wrapper.vm.control).toBeDefined()
29+
console.log(wrapper.vm.control.data())
30+
expect(wrapper.vm.control.data().smartSelectParams).toBeDefined()
31+
// expect(wrapper.vm.control.data().smartSelectParams.openIn).toBe('popover')
2932
})
33+
// it('shows a list of options', () => {
34+
// expect(wrapper.vm.smartSelectParams).toBeDefined()
35+
// expect(wrapper.vm.smartSelectParams.openIn).toBe('popover')
36+
// })
3037
it('renders the description', () => {
31-
expect(wrapper.find('.param-description').text()).toBe(configDescription.description)
38+
expect(wrapper.find('.param-description').text()).toBe(configDescription.description)
3239
})
3340
})

features/src/main/feature/feature.xml

+1-1
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@
7777

7878
<feature name="openhab-ui-habpanel" description="HABPanel" version="${project.version}">
7979
<feature>openhab-core-ui</feature>
80-
<feature>openhab-io-webaudio</feature>
80+
<feature>openhab-iconset-classic</feature>
8181
<bundle>mvn:org.openhab.ui.bundles/org.openhab.ui.habpanel/${project.version}</bundle>
8282
</feature>
8383

0 commit comments

Comments
 (0)