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

#250 Improve Entity selection (list, filter) #251

Merged
merged 1 commit into from
Feb 12, 2024
Merged
Show file tree
Hide file tree
Changes from all 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
51 changes: 51 additions & 0 deletions src/components/EntitySelection.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
<template>
<div>
<label class="form-label" for="entity">Entity</label>
<select size="5" id="entity" @change="emit('update:modelValue', $event.target.value)" :value="modelValue"
class="form-select form-select-sm mb-1" title="The entity you want to display">
<option v-for="entity in filteredEntities" v-bind:key="entity" :value="entity.entityId">{{
entity.title
}}
</option>
</select>
<input type="text" class="form-control form-control-sm" v-model="entityFilter"
placeholder="Filter by name or entity_id...">
</div>
</template>
<script setup>

import {computed, ref} from "vue";
import {Entity} from "@/modules/pi/entity";

const props = defineProps({
modelValue: {
required: true,
type: Object,
default: () => (new Entity())
},
availableEntities: {
required: true,
type: [] // Entity[]
}
})

const emit = defineEmits([
'update:modelValue'
])

const entityFilter = ref("")

const filteredEntities = computed(() => {
if (!entityFilter.value) {
return props.availableEntities
}

let filterLc = entityFilter.value.toLowerCase();
return props.availableEntities.filter(entity => {
let entityIdMatches = entity.entityId.toLowerCase().indexOf(filterLc) !== -1;
let titleMatches = entity.title.toLowerCase().indexOf(filterLc) !== -1;
return entityIdMatches || titleMatches
})
})

</script>
38 changes: 3 additions & 35 deletions src/components/PiComponent.vue
Original file line number Diff line number Diff line change
Expand Up @@ -44,28 +44,7 @@
<div v-if="haConnectionState === 'connected'" class="clearfix mb-3">
<h1>{{ controllerType }} appearance</h1>

<div class="mb-3">
<label class="form-label" for="accessToken">Domain</label>
<select id="domain" v-model="domain" class="form-select form-select-sm"
title="The domain of the entity you want to display"
v-on:change="entity = ''">
<option v-for="availableDomain in availableEntityDomains" v-bind:key="availableDomain">{{
availableDomain
}}
</option>
</select>
</div>

<div class="mb-3">
<label class="form-label" for="entity">Entity</label>
<select id="entity" v-model="entity" class="form-select form-select-sm" title="The entity you want to display">
<option v-for="domainEntity in domainEntities" v-bind:key="domainEntity.entityId"
:value="domainEntity.entityId">{{
domainEntity.title
}}
</option>
</select>
</div>
<EntitySelection class="mb-3" :available-entities="availableEntities" v-model="entity"></EntitySelection>

<div class="form-check">
<input id="chkButtonTitle" v-model="useCustomTitle" class="form-check-input" type="checkbox">
Expand Down Expand Up @@ -122,7 +101,6 @@
<ServiceCallConfiguration v-model="serviceShortPress" :available-entities="availableEntities"
:available-services="availableServices"
class="mb-2"

></ServiceCallConfiguration>
</AccordeonItem>

Expand Down Expand Up @@ -184,8 +162,7 @@

</AccordeonComponent>

<button id="mybutton" :disabled="!domain" class="btn btn-sm btn-primary float-end"
v-on:click="saveSettings">
<button class="btn btn-sm btn-primary float-end" v-on:click="saveSettings">
Save configuration
</button>

Expand All @@ -205,13 +182,13 @@ import ServiceCallConfiguration from "@/components/ServiceCallConfiguration.vue"
import {ObjectUtils} from "@/modules/common/utils";
import AccordeonComponent from "@/components/accordeon/BootstrapAccordeon.vue";
import AccordeonItem from "@/components/accordeon/BootstrapAccordeonItem.vue";
import EntitySelection from "@/components/EntitySelection.vue";

let $HA = null;
let $SD = null;

const serverUrl = ref("")
const accessToken = ref("")
const domain = ref("")
const entity = ref("")

const serviceShortPress = ref({})
Expand Down Expand Up @@ -239,7 +216,6 @@ const haError = ref("")

const controllerType = ref("")


onMounted(() => {
window.connectElgatoStreamDeckSocket = (inPort, inPropertyInspectorUUID, inRegisterEvent, inInfo, inActionInfo) => {
$SD = new StreamDeck(inPort, inPropertyInspectorUUID, inRegisterEvent, inInfo, inActionInfo);
Expand All @@ -266,7 +242,6 @@ onMounted(() => {

let settings = Settings.parse(actionInfo.payload.settings);

domain.value = settings["display"]["domain"]
entity.value = settings["display"]["entityId"]
enableServiceIndicator.value = settings["display"]["enableServiceIndicator"] || settings["display"]["enableServiceIndicator"] === undefined;
hideIcon.value = settings["display"]["hideIcon"];
Expand All @@ -288,12 +263,6 @@ const isHaSettingsComplete = computed(() => {
return serverUrl.value && accessToken.value
})


const domainEntities = computed(() => {
return availableEntities.value.filter((entity) => entity.domain === domain.value)
})


const entityAttributes = computed(() => {
let currentEntityState = currentStates.value.find((state) => state.entityId === entity.value)
if (currentEntityState && currentEntityState.attributes) {
Expand Down Expand Up @@ -376,7 +345,6 @@ function saveSettings() {
controllerType: controllerType.value,

display: {
domain: domain.value,
entityId: entity.value,
useCustomTitle: useCustomTitle.value,
buttonTitle: buttonTitle.value,
Expand Down
24 changes: 9 additions & 15 deletions src/components/ServiceCallConfiguration.vue
Original file line number Diff line number Diff line change
Expand Up @@ -34,20 +34,10 @@
</div>

<div v-if="domainEntities.length > 0" class="mb-3">
<label class="form-label" for="entity">Entity</label>
<div class="input-group">
<select id="entity"
:value="modelValue.entityId" class="form-select form-select-sm"
@change="update('entityId', $event.target.value)">
<option v-for="domainEntity in domainEntities" v-bind:key="domainEntity.entityId"
:value="domainEntity.entityId">
{{ domainEntity.title }}
</option>
</select>
<button class="btn btn-sm btn-outline-secondary" type="button"
@click="clear('entityId')">Clear
</button>
</div>
<EntitySelection class="mb-3" :available-entities="domainEntities" @change="update('entityId', $event.target.value)" :model-value="props.modelValue.entityId"></EntitySelection>
<button class="btn btn-sm btn-outline-secondary" type="button"
@click="clear('entityId')">Clear
</button>
</div>

<template v-if="props.modelValue.serviceId">
Expand All @@ -71,7 +61,10 @@
<details v-if="dataProperties && dataProperties.length > 0">
<summary>Available options</summary>
<div v-for="item in dataProperties" v-bind:key="item.name" class="form-text">
<span class="text-info font-monospace">{{ item.name }}&nbsp;</span> <span class="text-warning font-monospace" v-if="item.info.required">(required) </span>{{ item.info.description }}
<span class="text-info font-monospace">{{ item.name }}&nbsp;</span> <span class="text-warning font-monospace"
v-if="item.info.required">(required) </span>{{
item.info.description
}}
<template v-if="item.info.example">
<br>
<span class="ml-2">Example: <i>{{ item.info.example }}</i></span>
Expand All @@ -86,6 +79,7 @@

import {computed, onMounted, ref} from "vue";
import nunjucks from "nunjucks";
import EntitySelection from "@/components/EntitySelection.vue";

const titleSort = (s1, s2) => s1.title.toLowerCase() > s2.title.toLowerCase() ? 1 : -1;

Expand Down
Loading