Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -636,6 +636,7 @@ import SearchResults from './search-results.vue'
import ExpressionTester from './expression-tester.vue'
import ClipboardIcon from '@/components/util/clipboard-icon.vue'

import PageType from '@/pages/page-type-mixin'
import RuleStatus from '@/components/rule/rule-status-mixin'
import ThingStatus from '@/components/thing/thing-status-mixin'
import cloneDeep from 'lodash/cloneDeep'
Expand All @@ -645,7 +646,7 @@ import * as api from '@/api'
import { showToast } from '@/js/dialog-promises'

export default {
mixins: [RuleStatus, ThingStatus],
mixins: [RuleStatus, ThingStatus, PageType],
components: {
ClipboardIcon,
Item,
Expand Down Expand Up @@ -687,15 +688,6 @@ export default {
newCollectionName: '',
sseEvents: [],
openedItem: null,
pageTypes: [
{ type: 'sitemap', label: 'Sitemap', componentType: 'Sitemap', icon: 'menu' },
{ type: 'layout', label: 'Layout', componentType: 'oh-layout-page', icon: 'rectangle_grid_2x2' },
{ type: 'home', label: 'Home', componentType: 'oh-home-page', icon: 'house' },
{ type: 'tabs', label: 'Tabbed', componentType: 'oh-tabs-page', icon: 'squares_below_rectangle' },
{ type: 'map', label: 'Map', componentType: 'oh-map-page', icon: 'map' },
{ type: 'plan', label: 'Floor plan', componentType: 'oh-plan-page', icon: 'square_stack_3d_up' },
{ type: 'chart', label: 'Chart', componentType: 'oh-chart-page', icon: 'graph_square' }
],
testExpression: '',
addThingAutocomplete: null,
theme
Expand Down Expand Up @@ -1023,9 +1015,6 @@ export default {
load()
}
},
getPageType(page) {
return this.pageTypes.find((t) => t.componentType === page.component)
},
showItem(evt, item) {
evt.cancelBubble = true
if (this.$$(evt.target).closest('.itemlist-actions').length) return
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -388,8 +388,10 @@

<script>
import ClipboardIcon from '@/components/util/clipboard-icon.vue'
import PageType from '@/pages/page-type-mixin'

export default {
mixins: [PageType],
components: {
ClipboardIcon
},
Expand All @@ -408,16 +410,7 @@ export default {
rules: 'wand_stars',
pages: 'tv'
},
expandedTypes: {},
pageTypes: [
{ type: 'sitemap', label: 'Sitemap', componentType: 'Sitemap', icon: 'menu' },
{ type: 'layout', label: 'Layout', componentType: 'oh-layout-page', icon: 'rectangle_grid_2x2' },
{ type: 'home', label: 'Home', componentType: 'oh-home-page', icon: 'house' },
{ type: 'tabs', label: 'Tabbed', componentType: 'oh-tabs-page', icon: 'squares_below_rectangle' },
{ type: 'map', label: 'Map', componentType: 'oh-map-page', icon: 'map' },
{ type: 'plan', label: 'Floor plan', componentType: 'oh-plan-page', icon: 'square_stack_3d_up' },
{ type: 'chart', label: 'Chart', componentType: 'oh-chart-page', icon: 'graph_square' }
]
expandedTypes: {}
}
},
computed: {
Expand Down Expand Up @@ -482,9 +475,6 @@ export default {
showingAll(type) {
return this.expandedTypes[type] || this.searchResults[type].length <= 5
},
getPageType(page) {
return this.pageTypes.find((t) => t.componentType === page.component)
},
togglePin(evt, type, obj, keyName) {
evt.cancelBubble = true
if (evt.target.tagName.toLowerCase() === 'i') return
Expand Down
63 changes: 63 additions & 0 deletions bundles/org.openhab.ui/web/src/pages/page-type-mixin.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import type * as api from '@/api'
import type { DeepReadonly } from 'vue'

type PageType = {
type: string
label: string
icon: string
}

const pageTypes: Record<string, PageType> = {
Sitemap: { type: 'sitemap', label: 'Sitemap', icon: 'f7:menu' },
'oh-layout-page': { type: 'layout', label: 'Layout', icon: 'f7:rectangle_grid_2x2' },
'oh-home-page': { type: 'home', label: 'Home', icon: 'f7:house' },
'oh-tabs-page': { type: 'tabs', label: 'Tabbed', icon: 'f7:squares_below_rectangle' },
'oh-map-page': { type: 'map', label: 'Map', icon: 'f7:map' },
'oh-plan-page': { type: 'plan', label: 'Floor plan', icon: 'f7:square_stack_3d_up' },
'oh-chart-page': { type: 'chart', label: 'Chart', icon: 'f7:graph_square' }
}

const unknownPageType: PageType = { type: 'unknown', label: 'Unknown Page Type!', icon: 'f7:question_circle' }

/**
* Returns the PageType for the given page, or a default "unknown" PageType if the page type is unknown.
* The page type is determined by matching the page's component type against the known page types.
* @param page
* @returns The PageType for the given page, or a default "unknown" PageType if the page type is unknown.
*/
export function getPageType(page?: api.RootUiComponent | DeepReadonly<api.RootUiComponent> | null): PageType {
if (!page) return unknownPageType
return pageTypes[page.component] || unknownPageType
}

/**
* Returns the icon for the given page, or a default icon if the page type is unknown.
* The page type is determined by matching the page's component type against the known page types.
*
* Special cases:
* - If the page is null or undefined, it is considered an unknown page type and gets a question mark icon.
* - If the page has a uid of "overview", it is considered the overview page and gets a house icon.
* - If the page has a config with an icon, that icon is used.
*
* @param page
* @returns The icon for the given page, or a default icon if the page type is unknown.
*/
export function getPageIcon(page?: api.RootUiComponent | DeepReadonly<api.RootUiComponent> | null): string {
if (!page) return unknownPageType.icon
if (page.uid === 'overview') return 'f7:house'
if (page.config && page.config.icon) return page.config.icon as string
return getPageType(page).icon
}

const PageType = {
methods: {
getPageType(page: api.RootUiComponent | DeepReadonly<api.RootUiComponent> | null) {
return getPageType(page)
},
getPageIcon(page: api.RootUiComponent | DeepReadonly<api.RootUiComponent> | null) {
return getPageIcon(page)
}
}
}

export default PageType
23 changes: 3 additions & 20 deletions bundles/org.openhab.ui/web/src/pages/page/page-view.vue
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ import { useWidgetExpression } from '@/components/widgets/useWidgetExpression.ts
import { useViewArea } from '@/js/composables/useViewArea.ts'

import * as api from '@/api'
import { getPageType } from '@/pages/page-type-mixin'

import OhLayoutPage from '@/components/widgets/layout/oh-layout-page.vue'
import EmptyStatePlaceholder from '@/components/empty-state-placeholder.vue'
Expand Down Expand Up @@ -170,7 +171,7 @@ const context = computed(() => ({
vars: Object.assign(vars.value, page.value?.config?.defineVars ?? {}, props.defineVars ?? {}),
store: statesStore.trackedItems
}))
const pageType = computed(() => (page.value ? getPageType(page.value) : null))
const pageType = computed(() => getPageType(page.value).type)
const pageLabel = computed(() => page.value?.config?.label)
const editable = computed(() => page.value && userStore.isAdmin())
const fullscreenIcon = computed(() => {
Expand Down Expand Up @@ -199,24 +200,6 @@ const onTabChange = (idx: number) => {
// @ts-expect-error - url is not typed as part of the router
props.f7router.url = url
}
const getPageType = (page: api.RootUiComponent | DeepReadonly<api.RootUiComponent>) => {
if (!page) return null
switch (page.component) {
case 'oh-layout-page':
return 'layout'
case 'oh-map-page':
return 'map'
case 'oh-tabs-page':
return 'tabs'
case 'oh-plan-page':
return 'plan'
case 'oh-chart-page':
return 'chart'
default:
console.warn('Unknown page type!')
return 'unknown'
}
}
const tabContext = (tab: api.UiComponent) => {
const tabPage: DeepReadonly<api.RootUiComponent> | string = tab.config.page
? componentStore.page((tab.config.page as string).replace('page:', ''))!
Expand Down Expand Up @@ -291,7 +274,7 @@ const editPage = () => {
onClick: () => {
const tabPageUid = (page.value!.slots.default![currentTab.value]!.config.page as string).replace('page:', '')
const tabPage = componentStore.page(tabPageUid)!
const tabPageType = getPageType(tabPage)
const tabPageType = getPageType(tabPage).type
props.f7router.navigate('/settings/pages/' + tabPageType + '/' + tabPageUid)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -171,8 +171,10 @@ import { f7, theme } from 'framework7-vue'

import { useLastSearchQueryStore } from '@/js/stores/useLastSearchQueryStore'
import { showToast } from '@/js/dialog-promises'
import PageType from '@/pages/page-type-mixin'

export default {
mixins: [PageType],
props: {
f7router: Object
},
Expand All @@ -187,16 +189,7 @@ export default {
pages: [],
selectedItems: [],
groupBy: 'alphabetical',
showCheckboxes: false,
pageTypes: [
{ type: 'sitemap', label: 'Sitemap', componentType: 'Sitemap', icon: 'f7:menu' },
{ type: 'layout', label: 'Layout', componentType: 'oh-layout-page', icon: 'f7:rectangle_grid_2x2' },
{ type: 'home', label: 'Home', componentType: 'oh-home-page', icon: 'f7:house' },
{ type: 'tabs', label: 'Tabbed', componentType: 'oh-tabs-page', icon: 'f7:squares_below_rectangle' },
{ type: 'map', label: 'Map', componentType: 'oh-map-page', icon: 'f7:map' },
{ type: 'plan', label: 'Floor plan', componentType: 'oh-plan-page', icon: 'f7:square_stack_3d_up' },
{ type: 'chart', label: 'Chart', componentType: 'oh-chart-page', icon: 'f7:graph_square' }
]
showCheckboxes: false
}
},
computed: {
Expand Down Expand Up @@ -308,15 +301,6 @@ export default {
this.selectedItems.push(itemName)
}
},
getPageType(page) {
return this.pageTypes.find((t) => t.componentType === page.component)
},
getPageIcon(page) {
if (page.uid === 'overview') return 'f7:house'
if (page.config && page.config.icon) return page.config.icon
const pageType = this.pageTypes.find((t) => t.componentType === page.component)
return pageType ? pageType.icon : 'f7:tv'
},
removeSelected() {
const vm = this

Expand Down
Loading