Skip to content
Open
Show file tree
Hide file tree
Changes from 3 commits
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 @@ -24,6 +24,7 @@
"dialogs.search.rules": "Search rules",
"dialogs.search.nothingFound": "Nothing found",
"dialogs.search.persistence": "Search persistence",
"dialogs.search.sitemaps": "Search sitemaps",
"dialogs.search.transformationService": "Search transformation services",
"dialogs.search.transformation": "Search transformations",
"dialogs.searchOrCreate.transformation": "Search transformations / create definition inline",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
<template>
<ul class="sitemap-picker-container">
<f7-list-item
v-if="ready"
:title="title || 'Sitemap'"
smart-select
:smart-select-params="smartSelectParams"
ref="smartSelect"
:no-chevron="disabled"
:disabled="disabled">
<select :name="name" @change="select" :required="required">
<option value="" />
<option v-for="sitemap in sitemaps" :value="sitemap.name" :key="sitemap.name" :selected="value === sitemap.name ? true : null">
{{ sitemap.label ? sitemap.label + ' (' + sitemap.name + ')' : sitemap.name }}
</option>
</select>
</f7-list-item>
<!-- for placeholder purposes before sitemaps are loaded -->
<f7-list-item v-show="!ready" link :title="title" />
</ul>
</template>

<style lang="stylus">
.sitemap-picker-container
.item-inner:after
display none
</style>

<script>
import { f7 } from 'framework7-vue'
import { nextTick } from 'vue'
import { showToast } from '@/js/dialog-promises'

import * as api from '@/api'

export default {
props: {
title: String,
name: String,
value: String,
required: Boolean,
filterType: Array,
openOnReady: Boolean,
disabled: Boolean
},
emits: ['sitemapPicked', 'input'],

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

since sitempaPicked is an f7.emit, it shouldn't be listed here.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i actually don't see where there is a f7.on sitemapPicked - maybe this is just here for consistency?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This code is copied from persistencePicker I believe, so your feedback also may also apply to that one (and some other pickers). But all you point out is correct.

data() {
return {
ready: false,
sitemaps: [],
smartSelectParams: {
view: f7.view.main,
openIn: 'popup',
searchbar: true,
searchbarPlaceholder: this.$t('dialogs.search.sitemaps')
}
}
},
created() {
this.smartSelectParams.closeOnSelect = true
api
.getSitemaps()
.then((data) => {
this.sitemaps = data
.map((sitemap) => {
return {
name: sitemap.name,
label: sitemap.label
}
})
.sort((a, b) => {
const labelA = a.label || a.name
const labelB = b.label || b.name
return labelA.localeCompare(labelB)
})
if (this.filterType) {
this.sitemaps = this.sitemaps.filter((i) => this.filterType.indexOf(i.type) >= 0)
if (this.sitemaps.length < 5) {
this.smartSelectParams.openIn = 'sheet'
this.smartSelectParams.searchbar = false
}
}
this.ready = true
if (this.openOnReady) {
nextTick(() => {
this.$refs.smartSelect.$el.children[0].f7SmartSelect.open()
})
}
})
.catch((err) => {
console.error(err)
showToast('An error occurred while loading sitemaps: ' + (err?.message || String(err)))
})
},
methods: {
open() {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't see where 'open' is used, is it needed?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not used.

this.$refs.smartSelect.$el.children[0].f7SmartSelect.open()
},
select(e) {
f7.input.validateInputs(this.$refs.smartSelect.$el)
this.$emit('input', e.target.value)
f7.emit('sitemapPicked', e.target.value)
}
}
}
</script>
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,11 @@ export default {
{ type: 'Colortemperaturepicker', label: 'Color Temperature Picker', icon: 'thermometer' },
{ type: 'Mapview', label: 'Map View', icon: 'map' },
{ type: 'Image', icon: 'photo' },
{ type: 'Video', icon: 'videocam' }
{ type: 'Video', icon: 'videocam' },
{ type: 'NestedSitemap', label: 'Sitemap', icon: 'slider_horizontal_below_rectangle' }
]
this.LINKABLE_WIDGET_TYPES = ['Sitemap', 'Text', 'Frame', 'Group', 'Image', 'Buttongrid']
this.WIDGET_TYPES_NOT_REQUIRING_ITEM = ['Frame', 'Text', 'Image', 'Video', 'Webview', 'Buttongrid']
this.WIDGET_TYPES_NOT_REQUIRING_ITEM = ['Frame', 'Text', 'Image', 'Video', 'Webview', 'Buttongrid', 'NestedSitemap']
this.WIDGET_TYPES_SHOWING_VALUE = ['Text', 'Switch', 'Selection', 'Slider', 'Setpoint', 'Input', 'Default', 'Group']

this.REGEX_PERIOD =
Expand All @@ -49,7 +50,8 @@ export default {
Colortemperaturepicker: ['minValue', 'maxValue'],
Input: ['inputHint'],
Button: ['row', 'column', 'stateless', 'command', 'releaseCommand'],
Default: ['height']
Default: ['height'],
NestedSitemap: ['name']
}
this.ENCODING_DEFS = [
{ key: 'mjpeg', value: 'MJPEG Video' },
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -283,6 +283,16 @@
</option>
</select>
</f7-list-item>
<ul v-if="supports('name')" style="padding-left: 0" class="widget-nested-sitemap">
<sitemap-picker
style="padding-left: 0"
title="Sitemap"
:value="widget.name"
:disabled="!editable"
@input="(value) => (widget.name = value)" />

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you can change the emit to be update:value instead of 'input'. That way, you can use vmodel:value="widget.name" which is shorthand for the 2 separate :value and @input lines.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK

<f7-link v-if="widget.name" @click="navigateNestedSitemap(widget.name)"> <a>Edit Sitemap</a></f7-link>
<f7-link v-else-if="!widget.item" @click="navigateNestedSitemap()"> <a>Add Sitemap</a></f7-link>
</ul>
</ul>
</f7-list>
</f7-card-content>
Expand Down Expand Up @@ -318,6 +328,14 @@
color var(--f7-block-text-color)
.widget-persistence .item-after
color var(--f7-block-text-color)
.widget-nested-sitemap
.item-after
color var(--f7-block-text-color)
.link
display flex
flex-direction column
align-items flex-end
padding-right calc(var(--f7-list-item-padding-horizontal) + var(--f7-safe-area-right) - var(--menu-list-offset))
#additional:before
display block !important /* need two selectors to override the important Vue card css */

Expand All @@ -336,21 +354,23 @@ import { Categories } from '@/assets/categories.js'
import FormatEditor from '@/components/config/controls/format-editor.vue'
import ItemPicker from '@/components/config/controls/item-picker.vue'
import PersistencePicker from '@/components/config/controls/persistence-picker.vue'
import SitemapPicker from '@/components/config/controls/sitemap-picker.vue'
import SitemapMixin from '@/components/pagedesigner/sitemap/sitemap-mixin'

export default {
mixins: [SitemapMixin],
components: {
FormatEditor,
ItemPicker,
PersistencePicker
PersistencePicker,
SitemapPicker
},
props: {
widget: Object,
editable: Boolean,
createMode: Boolean
},
emits: ['sortbuttons', 'moveup', 'movedown', 'duplicate', 'remove'],
emits: ['sortbuttons', 'moveup', 'movedown', 'duplicate', 'remove', 'navigate-nested-sitemap'],
data() {
return {
iconInputId: '',
Expand Down Expand Up @@ -413,6 +433,9 @@ export default {
}
}
},
navigateNestedSitemap(target) {
this.$emit('navigate-nested-sitemap', target)
},
remove() {
this.$emit('remove')
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -331,7 +331,7 @@ describe('SitemapEdit', () => {
lastDialogConfig = null
wrapper.vm.validateWidgets()
expect(lastDialogConfig).toBeTruthy()
expect(lastDialogConfig.content).toMatch(/Webview widget Webview Test, no url configured/)
expect(lastDialogConfig.content).toMatch(/Web View widget Webview Test, no url configured/)

// configure a url for the Webview and check that there are no validation errors anymore
lastDialogConfig = null
Expand Down Expand Up @@ -490,6 +490,39 @@ describe('SitemapEdit', () => {
expect(lastDialogConfig).toBeFalsy()
})

it('validates nested sitemap has a name or item configured', async () => {
wrapper.vm.selectWidget([wrapper.vm.sitemap, null])
await wrapper.vm.$nextTick()
wrapper.vm.addWidget('NestedSitemap')
await wrapper.vm.$nextTick()
wrapper.vm.selectWidget([wrapper.vm.sitemap.widgets[0], wrapper.vm.sitemap])
await wrapper.vm.$nextTick()
wrapper.vm.selectedWidget.label = 'NestedSitemap Test'

// should not validate as the NestedSitemap has no name or item configured
lastDialogConfig = null
wrapper.vm.validateWidgets()
expect(lastDialogConfig).toBeTruthy()
expect(lastDialogConfig.content).toMatch(/Sitemap widget NestedSitemap Test, must have either name or item configured/)

// configure a name for the NestedSitemap and check that there are no validation errors anymore
lastDialogConfig = null
wrapper.vm.selectWidget([wrapper.vm.sitemap.widgets[0], wrapper.vm.sitemap])
await wrapper.vm.$nextTick()
wrapper.vm.selectedWidget.name = 'NestedSitemapName'
wrapper.vm.validateWidgets()
expect(lastDialogConfig).toBeFalsy()

// remove the name and configure an item for the NestedSitemap and check that there are no validation errors anymore
lastDialogConfig = null
wrapper.vm.selectWidget([wrapper.vm.sitemap.widgets[0], wrapper.vm.sitemap])
await wrapper.vm.$nextTick()
wrapper.vm.selectedWidget.name = null
wrapper.vm.selectedWidget.item = 'Item1'
wrapper.vm.validateWidgets()
expect(lastDialogConfig).toBeFalsy()
})

it('validates mappings', async () => {
wrapper.vm.selectWidget([wrapper.vm.sitemap, null])
await wrapper.vm.$nextTick()
Expand Down Expand Up @@ -579,7 +612,7 @@ describe('SitemapEdit', () => {
lastDialogConfig = null
wrapper.vm.validateWidgets()
expect(lastDialogConfig).toBeTruthy()
expect(lastDialogConfig.content).toMatch(/Buttongrid widget Buttongrid Test, no buttons defined/)
expect(lastDialogConfig.content).toMatch(/Button Grid widget Buttongrid Test, no buttons defined/)

// add button, should not validate as the button has no row defined
lastDialogConfig = null
Expand Down
Loading
Loading