Skip to content

Commit

Permalink
Add-on Store: Add sub menu items & various improvements (openhab#2381)
Browse files Browse the repository at this point in the history
Resolves openhab#2047.

- Installed addons are grouped by category in the main Add-on Store section.
- Search in the main "Add-on Store" menu will search all types of addons.
- Search in the corresponding section will only search for add-ons for that category.

The subsections are implemented as routable tabs, so switching around the different sections is fast.

---------

Also-by: Florian Hotze <[email protected]>
Signed-off-by: Jimmy Tanagra <[email protected]>
  • Loading branch information
jimtng authored Feb 23, 2024
1 parent bfa2d4a commit 6b7e1c4
Show file tree
Hide file tree
Showing 8 changed files with 231 additions and 147 deletions.
39 changes: 36 additions & 3 deletions bundles/org.openhab.ui/web/src/assets/addon-store.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,46 @@
export const AddonIcons = {
automation: 'wand_stars',
binding: 'circle_grid_hex_fill',
persistence: 'download_circle',
automation: 'wand_stars',
transformation: 'function',
misc: 'rectangle_3_offgrid',
persistence: 'download_circle',
ui: 'play_rectangle',
misc: 'rectangle_3_offgrid',
voice: 'chat_bubble_2_fill'
}

export const AddonTitles = {
binding: 'Bindings',
automation: 'Automation',
transformation: 'Transformations',
persistence: 'Persistence',
ui: 'User Interfaces',
misc: 'System Integrations',
voice: 'Voice & Speech'
}

export const AddonSuggestionLabels = {
binding: {
title: 'Suggested Bindings',
subtitle: 'Suggested bindings, identified from network scan'
},
misc: {
title: 'Suggested System Integration Add-ons',
subtitle: 'Suggested system integrations, identified from network scan'
},
persistence: {
title: 'Suggested Persistence Services',
subtitle: 'Suggested backend connectors to store historical data, identified from network scan'
},
transformation: {
title: 'Suggested Transformation Add-ons',
subtitle: 'Suggested transformation add-ons to translate raw values into processed or human-readable representations, identified from network scan'
},
voice: {
title: 'Suggested Voice &amp; Speech Add-ons',
subtitle: 'Convert between text and speech, interpret human language queries'
}
}

export const ContentTypes = {
'application/java-archive': 'Java Archive',
'application/vnd.openhab.bundle': 'OSGi Bundle',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"title": "1. Install a Binding (Add-on)",
"steps": [
{
"link": "/addons/",
"link": "/addons/binding/",
"title": "Add-on Store",
"text": "Left panel > Settings > Add-on Store or click here <i class=\"f7-icons size-22 add-button-icon\">arrow_right</i>"
},
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<template>
<f7-link v-if="addon" class="addon-card padding-right-half" :href="'/addons/' + addon.uid">
<f7-link v-if="addon" class="addon-card padding-right-half" :href="`/addons/${addon.type}/${addon.uid}`">
<div class="addon-card-inner card">
<div class="addon-card-headline">
<div>{{ headline || autoHeadline || "&nbsp;" }}</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
v-if="addon"
class="addon-list-item padding-right-half"
:title="addon.label"
:link="'/addons/' + addon.uid">
:link="`/addons/${addon.type}/${addon.uid}`">
<div v-if="addon.verifiedAuthor" slot="subtitle">
{{ addon.author }}
<f7-icon v-if="addon.verifiedAuthor" size="15" :color="$f7.data.themeOptions.dark === 'dark' ? 'white' : 'blue'" f7="checkmark_seal_fill" style="margin-top: -3px" />
Expand Down
36 changes: 30 additions & 6 deletions bundles/org.openhab.ui/web/src/components/app.vue
Original file line number Diff line number Diff line change
Expand Up @@ -75,10 +75,19 @@
</li>

<!-- Add-on Store -->
<f7-list-item link="/addons/" :title="$t('sidebar.addOnStore')" panel-close :animate="false"
:class="{ currentsection: currentUrl.indexOf('/addons/') === 0 }">
<f7-list-item link="/addons/" :title="$t('sidebar.addOnStore')" view=".view-main" panel-close :animate="false"
:class="{ currentsection: currentUrl === '/addons/' }">
<f7-icon slot="media" ios="f7:bag_fill" aurora="f7:bag_fill" md="material:shopping_bag" color="gray" />
</f7-list-item>
<li v-if="showAddonsSubmenu && $store.getters.apiEndpoint('addons')">
<ul class="menu-sublinks">
<f7-list-item v-for="section in Object.keys(AddonTitles)" :key="section" :link="`/addons/${section}/`"
:title="AddonTitles[section]" view=".view-main" panel-close :animate="false" no-chevron
:class="{ currentsection: currentUrl.indexOf(`/addons/${section}`) === 0 }">
<f7-icon slot="media" :f7="AddonIcons[section]" color="gray" />
</f7-list-item>
</ul>
</li>

<!-- Developer Tools -->
<f7-list-item link="/developer/" :title="$t('sidebar.developerTools')" panel-close :animate="false"
Expand Down Expand Up @@ -260,6 +269,8 @@ import sseEvents from './sse-events-mixin'
import dayjs from 'dayjs'
import dayjsLocales from 'dayjs/locale.json'
import { AddonIcons, AddonTitles } from '@/assets/addon-store'
export default {
mixins: [auth, i18n, connectionHealth, sseEvents],
components: {
Expand Down Expand Up @@ -368,6 +379,7 @@ export default {
},
showSettingsSubmenu: false,
showAddonsSubmenu: false,
showDeveloperSubmenu: false,
showDeveloperDock: false,
activeDock: 'tools',
Expand Down Expand Up @@ -614,9 +626,19 @@ export default {
ev.stopPropagation()
ev.preventDefault()
}
},
updateUrl (newUrl) {
this.showSettingsSubmenu = newUrl.indexOf('/settings/') === 0
this.showAddonsSubmenu = newUrl.indexOf('/addons/') === 0
this.showDeveloperSubmenu = newUrl.indexOf('/developer/') === 0
this.currentUrl = newUrl
this.$store.commit('setPagePath', this.currentUrl)
}
},
created () {
this.AddonIcons = AddonIcons
this.AddonTitles = AddonTitles
// special treatment for this option because it's needed to configure the app initialization
this.themeOptions.pageTransitionAnimation = localStorage.getItem('openhab.ui:theme.pagetransition') || 'default'
// tell the app to go fullscreen (if the OHApp is supported)
Expand Down Expand Up @@ -679,13 +701,15 @@ export default {
this.$f7.on('pageBeforeIn', (page) => {
if (page.route && page.route.url) {
this.showSettingsSubmenu = page.route.url.indexOf('/settings/') === 0
this.showDeveloperSubmenu = page.route.url.indexOf('/developer/') === 0
this.currentUrl = page.route.url
this.$store.commit('setPagePath', this.currentUrl)
this.updateUrl(page.route.url)
}
})
// needed by updateCurrentUrl() inside addon-store onTabShow()
this.$f7.on('routeUrlUpdate', (newRoute, router) => {
this.updateUrl(newRoute.url)
})
this.$f7.on('sidebarRefresh', () => {
this.loadData()
})
Expand Down
42 changes: 13 additions & 29 deletions bundles/org.openhab.ui/web/src/js/routes.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import store from '@/js/store'
import { authorize, isLoggedIn, enforceAdminForRoute } from '@/js/openhab/auth'

import HomePage from '../pages/home.vue'
import NotFoundPage from '../pages/not-found.vue'
import PageViewPage from '../pages/page/page-view.vue'
import AnalyzerPopup from '../pages/analyzer/analyzer-popup.vue'
import { AddonTitles } from '@/assets/addon-store'

const AboutPage = () => import(/* webpackChunkName: "about-page" */ '../pages/about.vue')
const UserProfilePage = () => import(/* webpackChunkName: "profile-page" */ '../pages/profile.vue')
Expand Down Expand Up @@ -357,8 +357,6 @@ export default [
},
{
path: 'addons',
beforeEnter: [enforceAdminForRoute],
async: loadAsync(AddonsStorePage),
routes: [
{
path: ':addonId',
Expand All @@ -380,34 +378,20 @@ export default [
path: '/addons/',
beforeEnter: [enforceAdminForRoute],
async: loadAsync(AddonsStorePage),
routes: [
{
path: 'bindings/',
beforeEnter: [enforceAdminForRoute],
async: loadAsync(AddonsStorePage, { initialTab: 'bindings' })
},
tabs: [
{
path: 'automation/',
beforeEnter: [enforceAdminForRoute],
async: loadAsync(AddonsStorePage, { initialTab: 'automation' })
},
{
path: 'ui/',
beforeEnter: [enforceAdminForRoute],
async: loadAsync(AddonsStorePage, { initialTab: 'ui' })
},
{
path: 'other/',
beforeEnter: [enforceAdminForRoute],
async: loadAsync(AddonsStorePage, { initialTab: 'other' })
},
{
path: 'search/',
beforeEnter: [enforceAdminForRoute],
async: loadAsync(AddonsStorePage, { initialTab: 'search' })
},
path: '/',
id: 'main'
}
].concat(Object.keys(AddonTitles).map((section) => {
return {
path: section,
id: section
}
})),
routes: [
{
path: ':addonId',
path: ':section/:addonId',
beforeEnter: [enforceAdminForRoute],
async: loadAsync(AddonDetailsPage)
}
Expand Down
Loading

0 comments on commit 6b7e1c4

Please sign in to comment.