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 0000000000..ad96a9dcfa --- /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 ab10fbb52f..7df95c5191 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 46f5c60c3c..55dcc03423 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 6abc679a90..8d2306d17b 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 1d2571a6bd..e019336631 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 7178722fa1..dc7dd38d0d 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 25c32acf2e..aee8af21c6 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 5fdd0d2bfa..05162de26d 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 379b84f851..b4a420dc78 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 e5fbfcf8fc..0176d70473 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 @@