mirror of
https://github.com/koush/scrypted.git
synced 2026-03-02 09:12:08 +00:00
326 lines
8.5 KiB
Vue
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> |