From da2f17e64aeb7bd418e66f05864efb4137bc3279 Mon Sep 17 00:00:00 2001 From: Yannick Schaus Date: Wed, 10 Mar 2021 15:13:25 +0100 Subject: [PATCH] Refactor routes: Move admin pages away from entry point (#948) Load all settings pages, about, profile, empty states, and the HABot control asynchronously. This also moves library dependencies to separate chunks, and thus reduces the entry point by several hundred kb if the user only accesses end-user pages, until they go to these pages. Various other optimizations to reduce the bundle size. Signed-off-by: Yannick Schaus --- .../config/controls/location-picker-popup.vue | 70 ++++ .../config/controls/location-picker.vue | 80 ++--- .../controls/parameter-cronexpression.vue | 38 +- .../config/controls/parameter-location.vue | 14 +- .../pagedesigner/sitemap/sitemap-code.vue | 2 +- .../pagedesigner/widget-code-popup.vue | 2 +- .../components/widgets/modals/oh-popup.vue | 5 +- .../components/widgets/modals/oh-sheet.vue | 5 +- bundles/org.openhab.ui/web/src/js/app.js | 2 - bundles/org.openhab.ui/web/src/js/routes.js | 325 +++++------------- .../pages/developer/widgets/widget-edit.vue | 2 +- .../web/src/pages/home/overview-tab.vue | 4 +- .../web/src/pages/page/page-view.vue | 1 + .../src/pages/settings/addons/addons-list.vue | 1 + .../pages/settings/items/items-list-vlist.vue | 3 + .../items/metadata/item-metadata-edit.vue | 2 +- .../items-add-from-textual-definition.vue | 3 +- .../web/src/pages/settings/model/model.vue | 1 + .../pages/settings/pages/chart/chart-edit.vue | 2 +- .../pages/settings/pages/home/home-edit.vue | 2 +- .../settings/pages/layout/layout-edit.vue | 2 +- .../src/pages/settings/pages/map/map-edit.vue | 2 +- .../src/pages/settings/pages/pages-list.vue | 3 + .../pages/settings/pages/plan/plan-edit.vue | 2 +- .../pages/settings/pages/tabs/tabs-edit.vue | 2 +- .../src/pages/settings/rules/rule-edit.vue | 43 +-- .../src/pages/settings/rules/rules-list.vue | 3 + .../settings/rules/script/script-edit.vue | 2 +- .../src/pages/settings/schedule/schedule.vue | 3 + .../settings/things/add/choose-binding.vue | 3 + .../settings/things/inbox/inbox-list.vue | 3 + .../pages/settings/things/thing-details.vue | 2 +- .../src/pages/settings/things/things-list.vue | 3 + 33 files changed, 281 insertions(+), 356 deletions(-) create mode 100644 bundles/org.openhab.ui/web/src/components/config/controls/location-picker-popup.vue diff --git a/bundles/org.openhab.ui/web/src/components/config/controls/location-picker-popup.vue b/bundles/org.openhab.ui/web/src/components/config/controls/location-picker-popup.vue new file mode 100644 index 000000000..ad96a9dcf --- /dev/null +++ b/bundles/org.openhab.ui/web/src/components/config/controls/location-picker-popup.vue @@ -0,0 +1,70 @@ + + + + + diff --git a/bundles/org.openhab.ui/web/src/components/config/controls/location-picker.vue b/bundles/org.openhab.ui/web/src/components/config/controls/location-picker.vue index ab10fbb52..7df95c519 100644 --- a/bundles/org.openhab.ui/web/src/components/config/controls/location-picker.vue +++ b/bundles/org.openhab.ui/web/src/components/config/controls/location-picker.vue @@ -1,43 +1,19 @@ - - diff --git a/bundles/org.openhab.ui/web/src/components/widgets/modals/oh-sheet.vue b/bundles/org.openhab.ui/web/src/components/widgets/modals/oh-sheet.vue index 46f5c60c3..55dcc0342 100644 --- a/bundles/org.openhab.ui/web/src/components/widgets/modals/oh-sheet.vue +++ b/bundles/org.openhab.ui/web/src/components/widgets/modals/oh-sheet.vue @@ -25,6 +25,9 @@ import modal from './modal-mixin' export default { - mixins: [modal] + mixins: [modal], + components: { + 'empty-state-placeholder': () => import('@/components/empty-state-placeholder.vue') + } } diff --git a/bundles/org.openhab.ui/web/src/js/app.js b/bundles/org.openhab.ui/web/src/js/app.js index 6abc679a9..8d2306d17 100644 --- a/bundles/org.openhab.ui/web/src/js/app.js +++ b/bundles/org.openhab.ui/web/src/js/app.js @@ -8,7 +8,6 @@ import SitemapWidgetGeneric from '../components/sitemap/widget-generic.vue' import OHIconComponent from '../components/widgets/system/oh-icon.vue' import ModelTreeviewItem from '../components/model/treeview-item.vue' import SitemapTreeviewItem from '../components/pagedesigner/sitemap/treeview-item.vue' -import EmptyStatePlaceholder from '../components/empty-state-placeholder.vue' import GenericWidgetComponent from '../components/widgets/generic-widget-component.vue' // Import Framework7 @@ -80,5 +79,4 @@ Vue.component('sitemap-widget-generic', SitemapWidgetGeneric) Vue.component('oh-icon', OHIconComponent) Vue.component('model-treeview-item', ModelTreeviewItem) Vue.component('sitemap-treeview-item', SitemapTreeviewItem) -Vue.component('empty-state-placeholder', EmptyStatePlaceholder) Vue.component('generic-widget-component', GenericWidgetComponent) diff --git a/bundles/org.openhab.ui/web/src/js/routes.js b/bundles/org.openhab.ui/web/src/js/routes.js index 1d2571a6b..e01933663 100644 --- a/bundles/org.openhab.ui/web/src/js/routes.js +++ b/bundles/org.openhab.ui/web/src/js/routes.js @@ -1,44 +1,56 @@ import HomePage from '../pages/home.vue' -import AboutPage from '../pages/about.vue' import NotFoundPage from '../pages/not-found.vue' - -import UserProfilePage from '../pages/profile.vue' - -import SitemapViewPage from '../pages/page/sitemap-view.vue' import PageViewPage from '../pages/page/page-view.vue' -import SettingsMenuPage from '../pages/settings/settings-menu.vue' -import ServiceSettingsPage from '../pages/settings/services/service-settings.vue' -import AddonsListPage from '../pages/settings/addons/addons-list.vue' -import AddonsAddPage from '../pages/settings/addons/addons-add.vue' -import AddonsConfigureBindingPage from '../pages/settings/addons/binding-config.vue' +const AboutPage = () => import(/* webpackChunkName: "about-page" */ '../pages/about.vue') +const UserProfilePage = () => import(/* webpackChunkName: "profile-page" */ '../pages/profile.vue') -import ItemsListPage from '../pages/settings/items/items-list-vlist.vue' -import ItemDetailsPage from '../pages/settings/items/item-details.vue' -import ItemEditPage from '../pages/settings/items/item-edit.vue' -import ItemsAddFromTextualDefinition from '../pages/settings/items/parser/items-add-from-textual-definition.vue' +const SettingsMenuPage = () => import(/* webpackChunkName: "admin-base" */ '../pages/settings/settings-menu.vue') +const ServiceSettingsPage = () => import(/* webpackChunkName: "admin-base" */ '../pages/settings/services/service-settings.vue') +const AddonsListPage = () => import(/* webpackChunkName: "admin-base" */ '../pages/settings/addons/addons-list.vue') +const AddonsAddPage = () => import(/* webpackChunkName: "admin-base" */ '../pages/settings/addons/addons-add.vue') +const AddonsConfigureBindingPage = () => import(/* webpackChunkName: "admin-base" */ '../pages/settings/addons/binding-config.vue') -import ThingsListPage from '../pages/settings/things/things-list.vue' -import ThingDetailsPage from '../pages/settings/things/thing-details.vue' -import AddThingChooseBindingPage from '../pages/settings/things/add/choose-binding.vue' -import AddThingChooseThingTypePage from '../pages/settings/things/add/choose-thing-type.vue' -import AddThingPage from '../pages/settings/things/add/thing-add.vue' +const ItemsListPage = () => import(/* webpackChunkName: "admin-config" */ '../pages/settings/items/items-list-vlist.vue') +const ItemDetailsPage = () => import(/* webpackChunkName: "admin-config" */ '../pages/settings/items/item-details.vue') +const ItemEditPage = () => import(/* webpackChunkName: "admin-config" */ '../pages/settings/items/item-edit.vue') +const ItemMetadataEditPage = () => import(/* webpackChunkName: "admin-config" */ '../pages/settings/items/metadata/item-metadata-edit.vue') +const ItemsAddFromTextualDefinition = () => import(/* webpackChunkName: "admin-config" */ '../pages/settings/items/parser/items-add-from-textual-definition.vue') -import InboxListPage from '../pages/settings/things/inbox/inbox-list.vue' +const ThingsListPage = () => import(/* webpackChunkName: "admin-config" */ '../pages/settings/things/things-list.vue') +const ThingDetailsPage = () => import(/* webpackChunkName: "admin-config" */ '../pages/settings/things/thing-details.vue') +const AddThingChooseBindingPage = () => import(/* webpackChunkName: "admin-config" */ '../pages/settings/things/add/choose-binding.vue') +const AddThingChooseThingTypePage = () => import(/* webpackChunkName: "admin-config" */ '../pages/settings/things/add/choose-thing-type.vue') +const AddThingPage = () => import(/* webpackChunkName: "admin-config" */ '../pages/settings/things/add/thing-add.vue') -import SemanticModelPage from '../pages/settings/model/model.vue' +const InboxListPage = () => import(/* webpackChunkName: "admin-config" */ '../pages/settings/things/inbox/inbox-list.vue') -import RulesListPage from '../pages/settings/rules/rules-list.vue' +const SemanticModelPage = () => import(/* webpackChunkName: "admin-config" */ '../pages/settings/model/model.vue') -import PagesListPage from '../pages/settings/pages/pages-list.vue' +const PagesListPage = () => import(/* webpackChunkName: "admin-pages" */ '../pages/settings/pages/pages-list.vue') +const PageEditors = { + home: () => import(/* webpackChunkName: "admin-pages" */ '../pages/settings/pages/home/home-edit.vue'), + layout: () => import(/* webpackChunkName: "admin-pages" */ '../pages/settings/pages/layout/layout-edit.vue'), + tabs: () => import(/* webpackChunkName: "admin-pages" */ '../pages/settings/pages/tabs/tabs-edit.vue'), + map: () => import(/* webpackChunkName: "admin-pages-leaflet" */ '../pages/settings/pages/map/map-edit.vue'), + plan: () => import(/* webpackChunkName: "admin-pages-leaflet" */ '../pages/settings/pages/plan/plan-edit.vue'), + chart: () => import(/* webpackChunkName: "admin-pages-echarts" */ '../pages/settings/pages/chart/chart-edit.vue'), + sitemap: () => import(/* webpackChunkName: "admin-pages" */ '../pages/settings/pages/sitemap/sitemap-edit.vue') +} -// import SchedulePage from '../pages/settings/schedule/schedule.vue' +const RulesListPage = () => import(/* webpackChunkName: "admin-rules" */ '../pages/settings/rules/rules-list.vue') +const RuleEditPage = () => import(/* webpackChunkName: "admin-rules" */ '../pages/settings/rules/rule-edit.vue') +const ScriptEditPage = () => import(/* webpackChunkName: "admin-rules" */ '../pages/settings/rules/script/script-edit.vue') +const SchedulePage = () => import(/* webpackChunkName: "admin-schedule" */ '../pages/settings/schedule/schedule.vue') -import Analyzer from '../pages/analyzer/analyzer.vue' +const AnalyzerPage = () => import(/* webpackChunkName: "analyzer" */ '../pages/analyzer/analyzer.vue') -import DeveloperToolsPage from '../pages/developer/developer-tools.vue' -import WidgetsListPage from '../pages/developer/widgets/widget-list.vue' -import ApiExplorerPage from '../pages/developer/api-explorer.vue' +const DeveloperToolsPage = () => import(/* webpackChunkName: "admin-devtools" */ '../pages/developer/developer-tools.vue') +const WidgetsListPage = () => import(/* webpackChunkName: "admin-devtools" */ '../pages/developer/widgets/widget-list.vue') +const WidgetEditPage = () => import(/* webpackChunkName: "admin-devtools" */ '../pages/developer/widgets/widget-edit.vue') +const ApiExplorerPage = () => import(/* webpackChunkName: "admin-devtools" */ '../pages/developer/api-explorer.vue') + +const SetupWizardPage = () => import(/* webpackChunkName: "setup-wizard" */ '../pages/wizards/setup-wizard.vue') const checkDirtyBeforeLeave = function (routeTo, routeFrom, resolve, reject) { if (this.currentPageEl && this.currentPageEl.__vue__ && this.currentPageEl.__vue__.$parent && this.currentPageEl.__vue__.$parent.beforeLeave && @@ -49,13 +61,24 @@ const checkDirtyBeforeLeave = function (routeTo, routeFrom, resolve, reject) { } } +const loadAsync = (page, props) => { + return (routeTo, routeFrom, resolve, reject) => { + if (!props) { + page().then((c) => { resolve({ component: c.default }) }) + } else if (typeof props === 'object') { + page().then((c) => { resolve({ component: c.default }, { props }) }) + } else if (typeof props === 'function') { + page().then((c) => { resolve({ component: c.default }, { props: props(routeTo, routeFrom, resolve, reject) }) }) + } + } +} + export default [ { path: '/', component: HomePage, // keepAlive: true, options: { - // animate: false transition: 'f7-dive' } }, @@ -63,88 +86,54 @@ export default [ path: '/page/:uid', component: PageViewPage }, - { - path: '/sitemap/:sitemapId/:pageId', - component: SitemapViewPage - }, { path: '/about/', - component: AboutPage, + async: loadAsync(AboutPage), options: { animate: false } }, { path: '/setup-wizard/', - async (routeTo, routeFrom, resolve, reject) { - // dynamic import component; returns promise - const widgetEditComponent = () => import(/* webpackChunkName: "setup-wizard" */ '../pages/wizards/setup-wizard.vue') - // resolve promise - widgetEditComponent().then((vc) => { - // resolve with component - resolve({ - component: vc.default - }, - (routeTo.params.uid === 'add') ? { - props: { - createMode: true - } - } : {}) - }) - } + async: loadAsync(SetupWizardPage) }, { path: '/profile/', - component: UserProfilePage, + async: loadAsync(UserProfilePage), options: { animate: false } }, { path: '/settings/', - component: SettingsMenuPage, + async: loadAsync(SettingsMenuPage), keepAlive: true, routes: [ { path: 'items', - component: ItemsListPage, + async: loadAsync(ItemsListPage), routes: [ { path: 'add', - component: ItemEditPage, - options: { - props: { - createMode: true - } - } + async: loadAsync(ItemEditPage, { createMode: true }) }, { path: 'add-from-textual-definition', - component: ItemsAddFromTextualDefinition + async: loadAsync(ItemsAddFromTextualDefinition) }, { path: ':itemName', - component: ItemDetailsPage, + async: loadAsync(ItemDetailsPage), routes: [ { path: 'edit', - component: ItemEditPage, - beforeLeave: checkDirtyBeforeLeave + beforeLeave: checkDirtyBeforeLeave, + async: loadAsync(ItemEditPage) }, { path: 'metadata/:namespace', beforeLeave: checkDirtyBeforeLeave, - async (routeTo, routeFrom, resolve, reject) { - // dynamic import component; returns promise - const editorComponent = () => import(/* webpackChunkName: "metadata-edit" */ '../pages/settings/items/metadata/item-metadata-edit.vue') - // resolve promise - editorComponent().then((vc) => { - // resolve with component - resolve({ - component: vc.default - }) - }) - } + async: loadAsync(ItemMetadataEditPage) } ] } @@ -152,54 +141,36 @@ export default [ }, { path: 'pages', - component: PagesListPage, + async: loadAsync(PagesListPage), routes: [ { path: ':type/:uid', beforeLeave: checkDirtyBeforeLeave, async (routeTo, routeFrom, resolve, reject) { - // dynamic import component; returns promise - const editorComponent = () => import(/* webpackChunkName: "[request]" */ `../pages/settings/pages/${routeTo.params.type}/${routeTo.params.type}-edit.vue`) - // resolve promise - editorComponent().then((vc) => { - // resolve with component - resolve({ - component: vc.default - }, - (routeTo.params.uid === 'add') ? { - props: { - createMode: true - } - } : {}) - }) + PageEditors[routeTo.params.type]().then((c) => { resolve({ component: c.default }, (routeTo.params.uid === 'add') ? { props: { createMode: true } } : {}) }) } } ] }, { path: 'things/', - component: ThingsListPage, + async: loadAsync(ThingsListPage), routes: [ { path: 'add', - component: AddThingChooseBindingPage, + async: loadAsync(AddThingChooseBindingPage), routes: [ { path: 'install-binding', - component: AddonsAddPage, - options: { - props: { - addonType: 'binding' - } - } + async: loadAsync(AddonsAddPage, { addonType: 'binding' }) }, { path: ':bindingId', - component: AddThingChooseThingTypePage, + async: loadAsync(AddThingChooseThingTypePage), routes: [ { path: ':thingTypeId', - component: AddThingPage + async: loadAsync(AddThingPage) } ] } @@ -207,75 +178,32 @@ export default [ }, { path: 'inbox', - component: InboxListPage + async: loadAsync(InboxListPage) }, { path: ':thingId', - component: ThingDetailsPage, - beforeLeave: checkDirtyBeforeLeave + beforeLeave: checkDirtyBeforeLeave, + async: loadAsync(ThingDetailsPage) } ] }, { path: 'model', - component: SemanticModelPage - // keepAlive: true - // routes: [ - // { - // path: ':itemName', - // component: ItemDetailsPage, - // routes: [ - // { - // path: 'edit', - // component: ItemEditPage - // } - // ] - // } - // ] + async: loadAsync(SemanticModelPage) }, { path: 'rules/', - component: RulesListPage, + async: loadAsync(RulesListPage), routes: [ { path: ':ruleId', beforeLeave: checkDirtyBeforeLeave, - async (routeTo, routeFrom, resolve, reject) { - // dynamic import component; returns promise - const ruleEditComponent = () => import(/* webpackChunkName: "rule-edit" */ '../pages/settings/rules/rule-edit.vue') - // resolve promise - ruleEditComponent().then((vc) => { - // resolve with component - resolve({ - component: vc.default - }, - (routeTo.params.ruleId === 'add') ? { - props: { - createMode: true - } - } : {}) - }) - }, + async: loadAsync(RuleEditPage, (routeTo) => (routeTo.params.ruleId === 'add') ? { createMode: true } : {}), routes: [ { path: 'script/:moduleId', beforeLeave: checkDirtyBeforeLeave, - async (routeTo, routeFrom, resolve, reject) { - // dynamic import component; returns promise - const ruleEditComponent = () => import(/* webpackChunkName: "rule-script-edit" */ '../pages/settings/rules/script/script-edit.vue') - // resolve promise - ruleEditComponent().then((vc) => { - // resolve with component - resolve({ - component: vc.default - }, - (routeTo.params.ruleId === 'add') ? { - props: { - createMode: true - } - } : {}) - }) - } + async: loadAsync(ScriptEditPage, (routeTo) => (routeTo.params.ruleId === 'add') ? { createMode: true } : {}) } ] } @@ -283,143 +211,76 @@ export default [ }, { path: 'scripts/', - component: RulesListPage, - options: { - props: { - showScripts: true - } - }, + async: loadAsync(RulesListPage, { showScripts: true }), routes: [ { path: ':ruleId', beforeLeave: checkDirtyBeforeLeave, - async (routeTo, routeFrom, resolve, reject) { - // dynamic import component; returns promise - const ruleEditComponent = () => import(/* webpackChunkName: "script-edit" */ '../pages/settings/rules/script/script-edit.vue') - // resolve promise - ruleEditComponent().then((vc) => { - // resolve with component - resolve({ - component: vc.default - }, - (routeTo.params.ruleId === 'add') ? { - props: { - createMode: true - } - } : {}) - }) - } + async: loadAsync(ScriptEditPage, (routeTo) => (routeTo.params.ruleId === 'add') ? { createMode: true } : {}) } ] }, { path: 'schedule/', - async (routeTo, routeFrom, resolve, reject) { - // dynamic import component; returns promise - const scheduleComponent = () => import(/* webpackChunkName: "schedule" */ '../pages/settings/schedule/schedule.vue') - // resolve promise - scheduleComponent().then((vc) => { - // resolve with component - resolve({ - component: vc.default - }) - }) - }, + async: loadAsync(SchedulePage), routes: [ { path: 'add', beforeLeave: checkDirtyBeforeLeave, - async (routeTo, routeFrom, resolve, reject) { - // dynamic import component; returns promise - const ruleEditComponent = () => import(/* webpackChunkName: "rule-edit" */ '../pages/settings/rules/rule-edit.vue') - // resolve promise - ruleEditComponent().then((vc) => { - // resolve with component - resolve({ - component: vc.default - }, { - props: { - createMode: true, - schedule: true - } - }) - }) - } + async: loadAsync(RuleEditPage, { createMode: true, schedule: true }) } ] }, - // { - // path: 'inbox/', - // component: InboxListPage - // }, { path: 'addons/:addonType', - component: AddonsListPage, + async: loadAsync(AddonsListPage), routes: [ { path: 'add', - component: AddonsAddPage + async: loadAsync(AddonsAddPage) }, { path: ':bindingId/config', - component: AddonsConfigureBindingPage + async: loadAsync(AddonsConfigureBindingPage) } ] }, { path: 'services/:serviceId', - component: ServiceSettingsPage, - beforeLeave: checkDirtyBeforeLeave + beforeLeave: checkDirtyBeforeLeave, + async: loadAsync(ServiceSettingsPage) } ] }, { path: '/developer/', - component: DeveloperToolsPage, - options: { - animate: false - }, + async: loadAsync(DeveloperToolsPage), routes: [ { path: 'widgets/', - component: WidgetsListPage, + async: loadAsync(WidgetsListPage), routes: [ { path: ':uid', beforeLeave: checkDirtyBeforeLeave, - async (routeTo, routeFrom, resolve, reject) { - // dynamic import component; returns promise - const widgetEditComponent = () => import(/* webpackChunkName: "widget-edit" */ '../pages/developer/widgets/widget-edit.vue') - // resolve promise - widgetEditComponent().then((vc) => { - // resolve with component - resolve({ - component: vc.default - }, - (routeTo.params.uid === 'add') ? { - props: { - createMode: true - } - } : {}) - }) - } + async: loadAsync(WidgetEditPage, (routeTo) => (routeTo.params.uid === 'add') ? { createMode: true } : {}) } ] }, { path: 'add-items-dsl', - component: ItemsAddFromTextualDefinition + async: loadAsync(ItemsAddFromTextualDefinition) }, { path: 'api-explorer', - component: ApiExplorerPage + async: loadAsync(ApiExplorerPage) } ] }, { path: '/analyzer/', - popup: { - component: Analyzer + async (routeTo, routeFrom, resolve, reject) { + AnalyzerPage().then((c) => { resolve({ popup: { component: c.default } }) }) } }, /* For Cordova */ diff --git a/bundles/org.openhab.ui/web/src/pages/developer/widgets/widget-edit.vue b/bundles/org.openhab.ui/web/src/pages/developer/widgets/widget-edit.vue index 7178722fa..dc7dd38d0 100644 --- a/bundles/org.openhab.ui/web/src/pages/developer/widgets/widget-edit.vue +++ b/bundles/org.openhab.ui/web/src/pages/developer/widgets/widget-edit.vue @@ -110,7 +110,7 @@ strOptions.fold.lineWidth = 0 export default { mixins: [DirtyMixin], components: { - 'editor': () => import('@/components/config/controls/script-editor.vue'), + 'editor': () => import(/* webpackChunkName: "script-editor" */ '@/components/config/controls/script-editor.vue'), ConfigSheet }, props: ['uid', 'createMode'], diff --git a/bundles/org.openhab.ui/web/src/pages/home/overview-tab.vue b/bundles/org.openhab.ui/web/src/pages/home/overview-tab.vue index 25c32acf2..aee8af21c 100644 --- a/bundles/org.openhab.ui/web/src/pages/home/overview-tab.vue +++ b/bundles/org.openhab.ui/web/src/pages/home/overview-tab.vue @@ -47,13 +47,13 @@ // import OtherApps from '../../components/home/other-apps.vue' import OhLayoutPage from '@/components/widgets/layout/oh-layout-page.vue' -import Habot from '../../components/home/habot.vue' export default { props: ['context', 'allowChat'], components: { OhLayoutPage, - Habot + 'empty-state-placeholder': () => import('@/components/empty-state-placeholder.vue'), + 'habot': () => import(/* webpackChunkName: "habot" */ '../../components/home/habot.vue') }, data () { return { diff --git a/bundles/org.openhab.ui/web/src/pages/page/page-view.vue b/bundles/org.openhab.ui/web/src/pages/page/page-view.vue index 5fdd0d2bf..05162de26 100644 --- a/bundles/org.openhab.ui/web/src/pages/page/page-view.vue +++ b/bundles/org.openhab.ui/web/src/pages/page/page-view.vue @@ -51,6 +51,7 @@ import OhLayoutPage from '@/components/widgets/layout/oh-layout-page.vue' export default { components: { 'oh-layout-page': OhLayoutPage, + 'empty-state-placeholder': () => import('@/components/empty-state-placeholder.vue'), 'oh-map-page': () => import(/* webpackChunkName: "map-page" */ '@/components/widgets/map/oh-map-page.vue'), 'oh-plan-page': () => import(/* webpackChunkName: "plan-page" */ '@/components/widgets/plan/oh-plan-page.vue'), 'oh-chart-page': () => import(/* webpackChunkName: "chart-page" */ '@/components/widgets/chart/oh-chart-page.vue') diff --git a/bundles/org.openhab.ui/web/src/pages/settings/addons/addons-list.vue b/bundles/org.openhab.ui/web/src/pages/settings/addons/addons-list.vue index 379b84f85..b4a420dc7 100644 --- a/bundles/org.openhab.ui/web/src/pages/settings/addons/addons-list.vue +++ b/bundles/org.openhab.ui/web/src/pages/settings/addons/addons-list.vue @@ -71,6 +71,7 @@ import AddonDetailsSheet from './addon-details-sheet.vue' export default { components: { + 'empty-state-placeholder': () => import('@/components/empty-state-placeholder.vue'), AddonDetailsSheet }, props: ['addonType'], diff --git a/bundles/org.openhab.ui/web/src/pages/settings/items/items-list-vlist.vue b/bundles/org.openhab.ui/web/src/pages/settings/items/items-list-vlist.vue index e5fbfcf8f..0176d7047 100644 --- a/bundles/org.openhab.ui/web/src/pages/settings/items/items-list-vlist.vue +++ b/bundles/org.openhab.ui/web/src/pages/settings/items/items-list-vlist.vue @@ -116,6 +116,9 @@