Skip to content

Commit

Permalink
feat(ui): custom browser TZ/LOCALE and UI persistent preferences (#3525)
Browse files Browse the repository at this point in the history
  • Loading branch information
robertsLando authored Jan 18, 2024
1 parent 76802d5 commit f85f225
Show file tree
Hide file tree
Showing 7 changed files with 153 additions and 24 deletions.
22 changes: 13 additions & 9 deletions .env.app.example
Original file line number Diff line number Diff line change
@@ -1,17 +1,21 @@
# The host address to bind to
# HOST="::"
HOST="::"
# The port to listen to for incoming requests. Default is `8091`
# PORT=8091
PORT=''
# The absolute path to the directory where all files will be stored. Default is `<path to your zui dir>/store`
# STORE_DIR
STORE_DIR=''
# Used as secret for session. If not provided the default one is used
# SESSION_SECRET
SESSION_SECRET="zwavejsisawesome"


# NETWORK_KEY
# HTTPS=true
# S0 Key
NETWORK_KEY=''
HTTPS=''
# Set the cookie [secure](https://github.com/expressjs/session#cookiesecure) option.
# USE_SECURE_COOKIE
USE_SECURE_COOKIE=''
# Mostly needed for docker users.
# https://zwave-js.github.io/node-zwave-js/#/usage/external-config?id=specifying-an-external-config-db-location
# ZWAVEJS_EXTERNAL_CONFIG
ZWAVEJS_EXTERNAL_CONFIG=''

# Browser preferred locale/tz to use for date/time formatting
TZ=''
LOCALE=''
2 changes: 2 additions & 0 deletions api/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1037,6 +1037,8 @@ app.get(
serial_ports: [],
scales: scales,
sslDisabled: sslDisabled(),
tz: process.env.TZ,
locale: process.env.LOCALE,
deprecationWarning: process.env.TAG_NAME === 'zwavejs2mqtt',
}

Expand Down
2 changes: 2 additions & 0 deletions docs/guide/env-vars.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,3 +29,5 @@ This is the list of the supported environment variables:
- `FORCE_DISABLE_SSL`: Set this env var to `'true'` to disable SSL.
- `BASE_PATH`: Set this env var to the base path where the application is served. Default is `/`.
- `UID_DISCOVERY_PREFIX`: Sets the prefix used for MQTT Discovery `unique_id` of entities. Default is `zwavejs2mqtt_`.
- `TZ`: Set this env var to the timezone you want to use on UI. Default to browser TZ.
- `LOCALE`: Set this env var to the locale you want to use on UI. Default to browser locale.
5 changes: 4 additions & 1 deletion src/components/custom/StatisticsArrows.vue
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
<i
>{{
node.lastActive
? new Date(node.lastActive).toLocaleString()
? getDateTimeString(node.lastActive)
: 'Never'
}}
</i>
Expand All @@ -31,6 +31,8 @@

<script>
import { jsonToList } from '@/lib/utils'
import { mapActions } from 'pinia'
import useBaseStore from '../../stores/base.js'
export default {
props: {
Expand All @@ -49,6 +51,7 @@ export default {
}
},
methods: {
...mapActions(useBaseStore, ['getDateTimeString']),
jsonToList(item) {
return jsonToList(item, {
ignore: ['lwr', 'nlwr', 'rssi', 'backgroundRSSI', 'lastSeen'],
Expand Down
85 changes: 72 additions & 13 deletions src/components/nodes-table/ExpandedNode.vue
Original file line number Diff line number Diff line change
Expand Up @@ -222,10 +222,10 @@
clearable
>
<template slot="append-outer">
<v-tooltip bottom>
<v-tooltip v-if="!inverseSort" bottom>
<template v-slot:activator="{ on, attrs }">
<v-btn
@click="toggleAutoScroll"
@click="toggleAutoScroll()"
icon
:color="autoScroll ? 'primary' : ''"
:class="
Expand All @@ -241,6 +241,28 @@
</template>
<span>Enable/Disable auto scroll</span>
</v-tooltip>

<v-tooltip bottom>
<template v-slot:activator="{ on, attrs }">
<v-btn
@click="toggleSort()"
icon
:color="
inverseSort ? 'primary' : ''
"
:class="
inverseSort
? 'border-primary'
: ''
"
v-bind="attrs"
v-on="on"
>
<v-icon>swap_vert</v-icon>
</v-btn>
</template>
<span>Inverse Sort</span>
</v-tooltip>
</template>
</v-text-field>

Expand All @@ -252,7 +274,7 @@
>
<span
><i>{{
new Date(event.time).toISOString()
getDateTimeString(event.time)
}}</i></span
>
-
Expand Down Expand Up @@ -378,14 +400,20 @@ export default {
return this.showStatistics ? 'border-primary' : ''
},
filteredNodeEvents() {
return this.node.eventsQueue.filter((event) => {
return (
!this.searchEvents ||
JSON.stringify(event)
.toLowerCase()
.includes(this.searchEvents.toLowerCase())
)
})
return this.node.eventsQueue
.filter((event) => {
return (
!this.searchEvents ||
JSON.stringify(event)
.toLowerCase()
.includes(this.searchEvents.toLowerCase())
)
})
.sort((a, b) => {
a = new Date(a.time)
b = new Date(b.time)
return this.inverseSort ? b - a : a - b
})
},
advancedActions() {
const nodeActions = this.node.isControllerNode
Expand Down Expand Up @@ -553,18 +581,46 @@ export default {
currentTab() {
this.scrollBottom()
},
inverseSort() {
this.savePreferences()
},
autoScroll() {
this.savePreferences()
},
},
data() {
return {
currentTab: 0,
autoScroll: true,
inverseSort: true,
searchEvents: '',
advancedShowDialog: false,
showStatistics: false,
}
},
mounted() {
const pref = useBaseStore().getPreference('eventsList', {
inverseSort: true,
autoScroll: true,
})
this.inverseSort = pref.inverseSort
this.autoScroll = pref.autoScroll
},
methods: {
...mapActions(useBaseStore, ['showSnackbar', 'setValue']),
...mapActions(useBaseStore, [
'showSnackbar',
'setValue',
'getDateTimeString',
]),
savePreferences() {
useBaseStore().savePreferences({
eventsList: {
inverseSort: this.inverseSort,
autoScroll: this.autoScroll,
},
})
},
async updateValue(v, customValue) {
if (v) {
// in this way I can check when the value receives an update
Expand Down Expand Up @@ -704,8 +760,11 @@ export default {
toggleAutoScroll() {
this.autoScroll = !this.autoScroll
},
toggleSort() {
this.inverseSort = !this.inverseSort
},
async scrollBottom() {
if (!this.autoScroll) {
if (!this.autoScroll || this.inverseSort) {
return
}
const el = this.$refs.eventsList
Expand Down
35 changes: 35 additions & 0 deletions src/stores/base.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,12 @@ const useBaseStore = defineStore('base', {
nodes: [],
nodesMap: new Map(),
user: {},
tz: Intl.DateTimeFormat().resolvedOptions().timeZone,
locale: undefined, // uses default browser locale
preferences: settings.load('preferences', {
eventsList: {},
smartStartTable: {},
}),
zwave: {
port: '/dev/zwave',
allowBootloaderOnly: false,
Expand Down Expand Up @@ -112,6 +118,15 @@ const useBaseStore = defineStore('base', {
},
},
actions: {
getDateTimeString(date) {
if (typeof date === 'string' || typeof date === 'number') {
date = new Date(date)
}

return date.toLocaleString(this.locale, {
timeZone: this.tz,
})
},
getNode(id) {
if (typeof id === 'string') {
id = parseInt(id)
Expand Down Expand Up @@ -493,6 +508,14 @@ const useBaseStore = defineStore('base', {
},
init(data) {
if (data) {
if (data.tz) {
this.tz = data.tzd
}

if (data.locale) {
this.locale = data.locale
}

this.initSettings(data.settings)
this.initPorts(data.serial_ports)
this.initScales(data.scales)
Expand Down Expand Up @@ -522,6 +545,18 @@ const useBaseStore = defineStore('base', {
settings.store('compact', value)
this.ui.compactMode = value
},
getPreference(key, defaultValue) {
return {
...defaultValue,
...(this.preferences[key] || {}),
}
},
savePreferences(pref) {
settings.store(
'preferences',
pref ? Object.assign(this.preferences, pref) : this.preferences,
)
},
},
})

Expand Down
26 changes: 25 additions & 1 deletion src/views/SmartStart.vue
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
:items="items"
class="elevation-1"
style="margin-bottom: 80px"
:options.sync="tableOptions"
>
<template v-slot:top>
<h2 class="ma-3">Provisioning Entries</h2>
Expand Down Expand Up @@ -180,14 +181,26 @@ import InstancesMixin from '../mixins/InstancesMixin.js'
export default {
name: 'SmartStart',
mixins: [InstancesMixin],
watch: {},
watch: {
tableOptions: {
handler() {
useBaseStore().savePreferences({
smartStartTable: this.tableOptions,
})
},
deep: true,
},
},
computed: {
...mapState(useBaseStore, ['nodes']),
},
data() {
return {
items: [],
fab: false,
tableOptions: {
sortBy: ['nodeId'],
},
headers: [
{ text: 'ID', value: 'nodeId' },
{ text: 'Name', value: 'name' },
Expand Down Expand Up @@ -216,6 +229,17 @@ export default {
}
},
mounted() {
this.tableOptions = useBaseStore().getPreference('smartStartTable', {
page: 1,
itemsPerPage: 10,
sortBy: ['nodeId'],
sortDesc: [false],
groupBy: [],
groupDesc: [],
mustSort: false,
multiSort: false,
})
this.refreshItems()
},
methods: {
Expand Down

0 comments on commit f85f225

Please sign in to comment.