Skip to content

Latest commit

 

History

History
150 lines (103 loc) · 10.5 KB

File metadata and controls

150 lines (103 loc) · 10.5 KB

Contributing to the openHAB UI

The standard contributing and community guidelines for the openHAB project, including signing off your commits, also apply for the development of the UI.

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.

Prerequisites

This project is built using Vue.js 3, Vite and Framework7 v7. Pinia is used as store. VitePWA is used to generate a service worker and pre-cache UI assets.

You need Node v24.11.0 or later and npm 11.7.0 or later installed. If you use a Node version manager like nvm, change to the web directory and run nvm use.

Change to the web directory, gather the necessary dependencies with npm install then the scripts below will be available.

NPM Scripts

Production

  • npm run build - build web app for production (note: no need to prepare a production version when submitting a PR, the build server will do it)
  • npm run build:mvn - build web app through Maven for production (note: no need to prepare a production version when submitting a PR, the build server will do it)
  • npm run preview - test the built version using a local static web server that serves the production-ready files

If source maps are needed for debugging, prepend SOURCE_MAPS=1 to the build command and Vite will generate source maps when building the app. The source maps have the .js.map extension and are available from the same path as the deployed .js files, i.e. /assets/example.js.map for /assets/example.js. Note that the source maps have to be manually loaded in the browser, e.g. for Chrome: Right-click in the source file → Add source map... → Enter the URl according to the file name.

Development

  • npm run start / npm run dev - run the development server
  • npm run test:unit - start the Vitest test runner and run the unit tests
  • npm run test:unit:watch - start the Vitest test runner, run the unit tests, keep running and watch for changes
  • npm run lint - run linter to detect code style errors
  • npm run lint:fix - run linter and fix code style errors
  • npm run typescript:check - run TypeScript compiler and check for type errors
  • npm run format - run oxfmt and apply Prettier formatting
  • npm run format:check - run oxfmt to verify Prettier formatting is intact
  • npm run bundle-analyzer - generate both a HTML report and a Webpack JSON report of the bundled assets, e.g., useful for debugging chunking and optimize JS loading

Development server

Before starting the development server with npm run dev, you should have an instance of openHAB (either a complete distribution or the demo app) running on localhost:8080. 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. If you wish to change the target of these forwards and use a remote instance, set the OH_APIBASE environment variable to the desired URL (e.g. OH_APIBASE=http://openhab-dev:8080) before running npm run dev.

Vue DevTools

Since openHAB's MainUI is using Vue, it is really helpful to install the Vue DevTools in your browser. Please note that you can only use the Vue DevTools with the development server.

Some of its very helpful features are:

  • Access to all Vue components of the current page in a tree model (like the Elements tab of the browsers DevTools)
  • Read (and write) props, data and computed of Vue components.
  • Select a component by clicking on it (very helpful when you want to change something in MainUI, but don't know which component you have to edit).
  • Access to the Pinia storage.

Coding Guidelines

  • Vue Reactivity (see Vue.js: Essentials: Reactivity Fundamentals) must be used where possible. No direct DOM manipulation!
  • Props (see Vue.js: Components In-Depth: Props) are a one-way data binding from parent to child and must not be mutated by the child component. Emit events (see Vue.js: Components In-Depth: Events) to share data from child to parent.
  • Computed properties (see Vue.js: Essentials: Computed Properties) should be used instead of method calls for getting prop values in the <template>. Methods re-evaluate on every rerender, negatively impacting performance.
  • Conditional HTML attributes on HTML elements should be unset using null if the condition is false: condition ? true : null. This does not apply for Vue components.
  • All embedded <style> should have a component-specific top-level class as parent to prevent leaking styles to other components.

For new components, additional guidelines apply:

  • TypeScript should be used over plain JavaScript. See Vue.js: TypeScript with Composition API.
  • The Composition API and composables should be used instead of the Options API and mixins. See Vue.js: Introduction: API Styles.
  • Composition API <script setup> code should be ordered according to the following order:
    1. Constants, store instantiation and type definitions
    2. Defines (defineProps, defineEmits, defineModels, defineOptions, defineExpose, ...)
    3. Composables
    4. State/Data
    5. Computed
    6. Watchers
    7. Lifecycle hooks
    8. Methods
  • Components should be imported through <script setup> to make sure Vite doesn't accidentally tree-shake them.

How Do I?

This FAQ tries to provide some guidance on how to start off with some common changes to MainUI.

Edit an existing page?

In general, it is a good start to open the web/src/pages directory. In this directory, open the sub-folders according to the path of the MainUI page.

For example: You want to edit /settings/transformations. Open web/src/pages/settings/transformations. You'll find transformations-list.vue and transformation-edit.vue, it should be self-explaining which page does what.

When you open a .vue file, check out the template tags for the structure of the page. You will note, that several UI structures are packed into Vue components, which you can directly open from the template tags inside your IDE. For example for IntelliJ-based IDEs: To open a component from the template tags, press CTRL and then click on the component name. To follow the example with the transformations, open transformation-edit.vue, and search for transformation-general-settings inside the template tags. CTRL + click on it, and the Vue component will open up.

Instead of following the way described above, you can also use the Vue DevTools to find out which component you need to modify.

Edit or add a widget?

UI widgets are Vue components, not pages, therefore you'll find them in the web/src/components/widgets/standard directory.

When opening one of those widgets you can use in the UI, e.g. oh-clock-card.vue, you'll notice that it basically wraps the oh-clock.vue component from web/src/components/widgets/system. If you now want to modify the functionality or appearance of the clock widget, your changes usually need to be done inside the wrapped component, in this case oh-clock.vue, not oh-clock-card.vue.

In case you want to edit widget parameters, make sure to adjust the widget's parameter definition in web/src/assets/definitions/widgets/system. After editing those definitions, it is required to regenerate the component docs, see Documentation & Resources.

Edit or add Blockly blocks?

Update the FAQ or Quick Start of the developer sidebar's help?

The "How do I..." and "Quick Start" sections are created from JSON definitions located at the web/src/assets/definitions/help directory.

Update the add-on names and documentation links for automation languages?

Edit the web/src/assets/automation-languages.js file.

Update the code snippets, editor mode assignment and documentation links for transformations?

Edit the web/src/assets/transformations.js file.

Documentation & Resources

The openHAB docs provide a Component Reference as well as documentation for each oh- widget component. You can find the component documentation in the doc/components folder. To generate the auto-generated parts of these component docs, run node generate.js inside the doc/components/src folder.

Vue / Pinia

Framework7