Files
scrypted/plugins/core/ui/src/interfaces/Setting.vue
2022-03-07 18:56:23 -08:00

326 lines
8.5 KiB
Vue

<template>
<div>
<v-checkbox
v-if="lazyValue.type && lazyValue.type.toLowerCase() === 'boolean'"
dense
:readonly="lazyValue.readonly"
v-model="booleanValue"
:label="lazyValue.title"
:hint="lazyValue.description"
:placeholder="lazyValue.placeholder"
persistent-hint
@change="save"
:class="lazyValue.description ? 'mb-2' : ''"
></v-checkbox>
<div v-else-if="lazyValue.type === 'button'" @click="save">
<v-btn small block> {{ lazyValue.title }} </v-btn>
<span v-if="lazyValue.description" class="caption pl-1">{{
lazyValue.description
}}</span>
</div>
<v-combobox
v-else-if="lazyValue.choices && lazyValue.combobox"
dense
:readonly="lazyValue.readonly"
:items="lazyValue.choices"
:multiple="lazyValue.multiple"
:small-chips="lazyValue.multiple"
v-model="lazyValue.value"
outlined
:label="lazyValue.title"
:hint="lazyValue.description"
persistent-hint
:placeholder="lazyValue.placeholder"
>
<template v-slot:append-outer>
<v-btn
v-if="dirty && device"
color="success"
@click="save"
class="shift-up"
>
<v-icon>send</v-icon>
</v-btn>
</template>
</v-combobox>
<v-select
v-else-if="lazyValue.choices"
dense
:readonly="lazyValue.readonly"
:items="lazyValue.choices"
:multiple="lazyValue.multiple"
:small-chips="lazyValue.multiple"
v-model="lazyValue.value"
outlined
:label="lazyValue.title"
:hint="lazyValue.description"
persistent-hint
:placeholder="lazyValue.placeholder"
>
<template v-slot:append-outer>
<v-btn
v-if="dirty && device"
color="success"
@click="save"
class="shift-up"
>
<v-icon>send</v-icon>
</v-btn>
</template>
</v-select>
<DevicePicker
v-else-if="lazyValue.type === 'device'"
v-model="lazyValue.value"
:multiple="lazyValue.multiple"
:devices="devices"
:title="lazyValue.title"
:description="lazyValue.description"
>
<template v-slot:append-outer>
<v-btn
v-if="dirty && device"
color="success"
@click="save"
class="shift-up"
>
<v-icon>send</v-icon>
</v-btn>
</template>
</DevicePicker>
<DevicePicker
v-else-if="lazyValue.type === 'interface'"
v-model="lazyValue.value"
:multiple="lazyValue.multiple"
:devices="interfaces"
:title="lazyValue.title"
:description="lazyValue.description"
>
<template v-slot:append-outer>
<v-btn
v-if="dirty && device"
color="success"
@click="save"
class="shift-up"
>
<v-icon>send</v-icon>
</v-btn>
</template>
</DevicePicker>
<div v-else-if="lazyValue.type === 'clippath'" class="mb-2">
<v-btn small block @click="editZone">{{ lazyValue.title }} </v-btn>
<Camera
:value="device"
:device="device"
:clipPathValue="sanitizedClipPathValue"
:showDialog="editingZone"
:hidePreview="true"
@dialog="editingZoneChanged"
@clipPath="lazyValue.value = $event"
></Camera>
</div>
<v-text-field
autocomplete="off"
autocorrect="off"
autocapitalize="off"
spellcheck="false"
v-else
dense
:readonly="lazyValue.readonly"
outlined
v-model="lazyValue.value"
:placeholder="lazyValue.placeholder"
:label="lazyValue.title"
:hint="lazyValue.description"
persistent-hint
:type="lazyValue.type === 'password' ? 'password' : undefined"
>
<template v-slot:append-outer>
<v-btn
v-if="dirty && device"
color="success"
text
@click="save"
class="shift-up"
>
<v-icon>send</v-icon>
</v-btn>
</template>
</v-text-field>
</div>
</template>
<script>
import RPCInterface from "./RPCInterface.vue";
import DevicePicker from "../common/DevicePicker.vue";
import Grower from "../common/Grower.vue";
import cloneDeep from "lodash/cloneDeep";
import Camera from "./Camera.vue";
export default {
mixins: [RPCInterface],
components: {
Camera,
DevicePicker,
Grower,
},
data() {
return {
editingZone: false,
};
},
watch: {
dirty() {
if (this.device) return;
this.onInput();
},
},
computed: {
sanitizedClipPathValue() {
try {
return JSON.parse(JSON.stringify(this.lazyValue.value)) || [];
} catch (e) {
return [];
}
},
booleanValue: {
get() {
return (
this.lazyValue.value &&
this.lazyValue.value.toString().toLowerCase() === "true"
);
},
set(val) {
this.lazyValue.value = val.toString();
},
},
dirty() {
return (
JSON.stringify(this.lazyValue.value) !==
JSON.stringify(this.value.value)
);
},
devices() {
var expression;
try {
expression = this.lazyValue.deviceFilter || "true;";
// var interfaces = this.$scrypted.systemManager.getDeviceById(id).interfaces.map(iface => `var ${iface} = true`);
} catch (e) {
expression = "true;";
}
var ret = this.$store.state.scrypted.devices
.map((id) => this.$scrypted.systemManager.getDeviceById(id))
.filter((device) => {
try {
return eval(
`(function() { var interfaces = ${JSON.stringify(
device.interfaces
)}; var type='${device.type}'; return ${expression} })`
)();
} catch (e) {
return true;
}
})
.map((device) => ({
id: device.id,
text: device.name,
}));
if (!this.lazyValue.multiple) {
ret.splice(0, 0, {
id: null,
text: this.lazyValue.placeholder || "Select a Device",
});
}
return ret;
},
interfaces() {
var expression;
try {
expression = this.lazyValue.deviceFilter || "true;";
// var interfaces = this.$scrypted.systemManager.getDeviceById(id).interfaces.map(iface => `var ${iface} = true`);
} catch (e) {
expression = "true;";
}
var ret = this.$store.state.scrypted.devices
.map((id) => {
const device = this.$scrypted.systemManager.getDeviceById(id)
return device.interfaces.map(iface => ({
device,
deviceInterface: iface,
}))
})
.flat()
.filter(({device, deviceInterface}) => {
try {
return eval(
`(function() { var interfaces = ${JSON.stringify(
device.interfaces
)}; var deviceInterface = '${deviceInterface}'}; var type='${device.type}'; return ${expression} })`
)();
} catch (e) {
return true;
}
})
.map(({device, deviceInterface}) => ({
id: device.id + '#' + deviceInterface,
text: device.name + ` (${deviceInterface})`,
}));
if (!this.lazyValue.multiple) {
ret.splice(0, 0, {
id: null,
text: this.lazyValue.placeholder || "Select an Interface",
});
}
return ret;
},
},
methods: {
onChange() {},
editingZoneChanged(value) {
this.editingZone = value;
if (!value) {
this.rpc().putSetting(
this.lazyValue.key,
this.createInputValue().value
);
this.onInput();
}
},
createLazyValue() {
var type = this.value.type || "";
if (type.indexOf("[]") == -1 && type !== "clippath") {
return cloneDeep(this.value);
}
var ret = cloneDeep(this.value);
try {
ret.value = JSON.parse(ret.value);
}
catch (e) {
ret.value = [];
}
return ret;
},
createInputValue() {
var type = this.lazyValue.type || "";
if (type.indexOf("[]") == -1 && type !== "clippath") {
return this.lazyValue;
}
var ret = cloneDeep(this.lazyValue);
ret.value = JSON.stringify(ret.value.filter((id) => id));
return ret;
},
save() {
this.rpc().putSetting(this.lazyValue.key, this.createInputValue().value);
this.onInput();
},
editZone() {
this.editingZone = true;
},
},
};
</script>
<style scoped>
.shift-up {
margin-top: -8px;
}
</style>