Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a persistence configuration page #1917

Merged
merged 11 commits into from
Jun 28, 2023
13 changes: 13 additions & 0 deletions bundles/org.openhab.ui/web/src/js/routes.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ const InboxListPage = () => import(/* webpackChunkName: "admin-config" */ '../pa
const TransformationsListPage = () => import(/* webpackChunkName: "admin-config" */ '../pages/settings/transformations/transformations-list.vue')
const TransformationsEditPage = () => import(/* webpackChunkName: "admin-rules" */ '../pages/settings/transformations/transformation-edit.vue')

const PersistenceEditPage = () => import(/* webpackChunkName: "admin-config" */ '../pages/settings/persistence/persistence-edit.vue')

const SemanticModelPage = () => import(/* webpackChunkName: "admin-config" */ '../pages/settings/model/model.vue')

const PagesListPage = () => import(/* webpackChunkName: "admin-pages" */ '../pages/settings/pages/pages-list.vue')
Expand Down Expand Up @@ -237,6 +239,17 @@ export default [
beforeEnter: [enforceAdminForRoute],
async: loadAsync(SemanticModelPage)
},
{
path: 'persistence/',
routes: [
{
path: ':serviceId',
beforeEnter: [enforceAdminForRoute],
beforeLeave: [checkDirtyBeforeLeave],
async: loadAsync(PersistenceEditPage)
}
]
},
{
path: 'rules/',
beforeEnter: [enforceAdminForRoute],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,15 @@
</f7-link>
</f7-nav-right>
</f7-navbar>
<f7-block v-if="type === 'persistence'" class="service-config block-narrow">
<f7-col>
<f7-block-title medium>
<f7-link color="blue" :href="'/settings/persistence/' + name">
Persistence configuration
</f7-link>
</f7-block-title>
</f7-col>
</f7-block>
<f7-block form v-if="configDescription && config" class="service-config block-narrow">
<f7-col>
<f7-block-title medium>
Expand Down Expand Up @@ -74,6 +83,14 @@ export default {
strippedAddonId: ''
}
},
computed: {
type () {
return this.addonId.split('-')[0]
},
name () {
return this.addonId.split('-')[1]
}
},
methods: {
save () {
let promises = []
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,97 @@
<template>
<f7-popup ref="modulePopup" class="moduleconfig-popup">
<f7-page>
<f7-navbar>
<f7-nav-left>
<f7-link icon-ios="f7:arrow_left" icon-md="material:arrow_back" icon-aurora="f7:arrow_left" popup-close />
</f7-nav-left>
<f7-nav-title>
Configure strategies and filters for Item(s)
</f7-nav-title>
<f7-nav-right>
<f7-link v-show="currentConfiguration.items.length > 0" @click="updateModuleConfig">
Done
</f7-link>
</f7-nav-right>
</f7-navbar>
<f7-block class="no-margin no-padding">
<f7-col>
<f7-block-title medium class="padding-bottom">
Items
</f7-block-title>
<f7-list>
<item-picker title="Select groups" name="groupItems" multiple="true"
filterType="Group" :value="groupItems" @input="selectGroupItems" />
<f7-list-item>... whose members are to be persisted.</f7-list-item>
</f7-list>
<f7-list>
<item-picker title="Select Items" name="items" multiple="true" :value="items"
@input="selectItems" />
<f7-list-item>... to be persisted.</f7-list-item>
</f7-list>
</f7-col>
<f7-col>
<f7-block-title medium class="padding-bottom">
Strategies
</f7-block-title>
<strategy-picker title="Select strategies" name="strategies" :strategies="strategies"
:value="currentConfiguration.strategies"
@strategiesSelected="currentConfiguration.strategies = $event" />
</f7-col>
<f7-col>
<f7-block-title medium class="padding-bottom">
Filters
</f7-block-title>
<filter-picker :filters="filters"
:value="currentConfiguration.filters"
@filtersSelected="currentConfiguration.filters = $event" />
</f7-col>
</f7-block>
</f7-page>
</f7-popup>
</template>

<script>
import ItemPicker from '@/components/config/controls/item-picker.vue'
import StrategyPicker from '@/pages/settings/persistence/strategy-picker.vue'
import FilterPicker from '@/pages/settings/persistence/filter-picker.vue'

export default {
components: { FilterPicker, StrategyPicker, ItemPicker },
props: ['configuration', 'strategies', 'filters'],
emits: ['configurationUpdate'],
data () {
return {
currentConfiguration: this.configuration || {
items: [],
strategies: [],
filters: []
}
}
},
computed: {
groupItems () {
return this.currentConfiguration.items.filter((i) => i.endsWith('*')).map((i) => i.slice(0, -1))
},
items () {
return this.currentConfiguration.items.filter((i) => !i.endsWith('*'))
}
},
methods: {
selectGroupItems (ev) {
this.currentConfiguration.items = ev.sort((a, b) => a.localeCompare(b)).map((i) => i + '*').concat(this.items)
},
selectItems (ev) {
this.currentConfiguration.items = this.groupItems.map((i) => i + '*').concat(ev.sort((a, b) => a.localeCompare(b)))
},
updateModuleConfig () {
if (this.currentConfiguration.items.length === 0) {
this.$f7.dialog.alert('Please select Items')
return
}
this.$f7.emit('configurationUpdate', this.currentConfiguration)
this.$refs.modulePopup.close()
}
}
}
</script>
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
<template>
<f7-popup ref="modulePopup" class="moduleconfig-popup">
<f7-page>
<f7-navbar>
<f7-nav-left>
<f7-link icon-ios="f7:arrow_left" icon-md="material:arrow_back" icon-aurora="f7:arrow_left" popup-close />
</f7-nav-left>
<f7-nav-title>
Configure cron strategy
</f7-nav-title>
<f7-nav-right>
<f7-link v-show="currentCronStrategy.name && currentCronStrategy.cronExpression" @click="updateModuleConfig">
Done
</f7-link>
</f7-nav-right>
</f7-navbar>
<f7-block class="no-margin no-padding">
<f7-col>
<f7-list>
<f7-list-input ref="name" label="Name" type="text" placeholder="Required" :value="currentCronStrategy.name"
@input="currentCronStrategy.name = $event.target.value"
:disabled="!createMode"
:info="(createMode) ? 'Note: cannot be changed after the creation' : ''"
required validate pattern="[A-Za-z]+" error-message="Required. A-Z,a-z only" />
</f7-list>
</f7-col>
<f7-col>
<f7-block-title medium class="padding-bottom">
Configuration
</f7-block-title>
<f7-list>
<parameter-cronexpression ref="cronExpression" :configDescription="cronExpressionConfigDescription"
:value="currentCronStrategy.cronExpression"
@input="currentCronStrategy.cronExpression = $event" />
</f7-list>
</f7-col>
</f7-block>
</f7-page>
</f7-popup>
</template>

<script>
import ParameterCronexpression from '@/components/config/controls/parameter-cronexpression.vue'

export default {
components: {
ParameterCronexpression
},
props: ['cronStrategy'],
emits: ['cronStrategyConfigUpdate'],
data () {
return {
createMode: !this.cronStrategy,
currentCronStrategy: this.cronStrategy || {
name: null,
cronExpression: null
},

cronExpressionConfigDescription: {
label: 'Cron Expression',
name: 'cronExpression',
required: true
}
}
},
methods: {
updateModuleConfig () {
if (!this.$f7.input.validateInputs(this.$refs.name.$el) && !this.$f7.input.validateInputs(this.$refs.cronExpression.$el)) {
this.$f7.dialog.alert('Please review the configuration and correct validation errors')
return
}
this.$f7.emit('cronStrategyConfigUpdate', this.currentCronStrategy)
this.$refs.modulePopup.close()
}
}
}
</script>
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
<template>
<f7-list class="strategy-picker-container" v-if="filters">
<f7-list-item title="Select filters" :smart-select="disabled !== true" :smart-select-params="smartSelectParams"
ref="smartSelect" class="defaults-picker">
<select v-if="disabled !== true" name="filters" multiple @change="select">
<option v-for="s in filters" :key="s" :value="s"
:selected="value.includes(s)">
{{ s }}
</option>
</select>
<div v-else>
{{ value.join(', ') }}
</div>
</f7-list-item>
</f7-list>
</template>

<style lang="stylus">
.strategy-picker-container
.item-content
padding-left calc(var(--f7-list-item-padding-horizontal) / 2 + var(--f7-safe-area-left))

.item-media
padding 0

.item-inner:after
display none
</style>

<script>
export default {
props: ['filters', 'value', 'disabled'],
emits: ['filtersSelected'],
data () {
return {
smartSelectParams: {
view: this.$f7.view.main,
openIn: 'popup',
virtualList: true,
virtualListHeight: (this.$theme.aurora) ? 32 : undefined
}
}
},
methods: {
select () {
this.$f7.input.validateInputs(this.$refs.smartSelect.$el)
const value = this.$refs.smartSelect.f7SmartSelect.getValue()
this.$emit('filtersSelected', value)
}
}
}
</script>
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
<template>
<f7-popup ref="modulePopup" class="moduleconfig-popup">
<f7-page>
<f7-navbar>
<f7-nav-left>
<f7-link icon-ios="f7:arrow_left" icon-md="material:arrow_back" icon-aurora="f7:arrow_left" popup-close />
</f7-nav-left>
<f7-nav-title>
Configure {{ filterType.label.toLowerCase() }} filter
</f7-nav-title>
<f7-nav-right>
<f7-link v-show="currentFilter.name" @click="updateModuleConfig">
Done
</f7-link>
</f7-nav-right>
</f7-navbar>
<f7-block class="no-margin no-padding">
<f7-col>
<f7-list>
<f7-list-input ref="name" label="Name" type="text" placeholder="Required" :value="currentFilter.name"
@input="currentFilter.name = $event.target.value"
:disabled="!createMode"
:info="(createMode) ? 'Note: cannot be changed after the creation' : ''"
required validate pattern="[A-Za-z]+" error-message="Required. A-Z,a-z only" />
</f7-list>
</f7-col>
<f7-col>
<f7-block-title medium>
Configuration
</f7-block-title>
<config-sheet ref="config-sheet" :parameter-groups="[]" :parameters="filterConfigDescriptionParameters"
:configuration="currentFilter" />
</f7-col>
</f7-block>
</f7-page>
</f7-popup>
</template>

<script>
import ConfigSheet from '@/components/config/config-sheet.vue'

export default {
components: { ConfigSheet },
props: ['filter', 'filterType', 'filterConfigDescriptionParameters'],
emits: ['filterUpdate'],
data () {
return {
createMode: !this.filter,
currentFilter: this.filter || {
name: null
}
}
},
methods: {
updateModuleConfig () {
if (!this.$refs['config-sheet'].isValid()) {
this.$f7.dialog.alert('Please review the configuration and correct validation errors')
return
}
this.$f7.emit('filterUpdate', this.currentFilter, this.filterType.name)
this.$refs.modulePopup.close()
}
}
}
</script>
Loading