Files
lrc-frontend/src/components/Recorder.vue

277 lines
15 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<!-- components/Profile.vue -->
<template>
<div>
<section class="hero is-primary">
<div class="hero-body">
<div class="container has-text-centered">
{{cmd_params}}
<h3>
<div class="text-center">
<font-awesome-icon class="float-left" icon="arrow-circle-left" @click="previousRecorder()"/>
<input type="number" style="font-size: small; max-width: 48px; text-align: center;"
v-model="new_recorder_id" @blur="manually_set_recorder_id()" @input="manually_set_recorder_id()">
<font-awesome-icon class="float-right" icon="arrow-circle-right" @click="nextRecorder()"/>
</div>
</h3>
<div class="clearfix">
<!--Route params: {{$route.params.recorder_id}}-->
<b-img left style="margin-right: 20px;" src="https://picsum.photos/164/164/?image=58"
alt="Left image"></b-img>
<h2 class="title">
<font-awesome-icon v-if="recorder.locked" style="color: red;" icon="lock" @dblclick="unlock()"/>
<font-awesome-icon v-else icon="lock-open" style="color: green;" @click="lock()"/>
&nbsp;{{recorder.name}}
</h2>
<p>
<font-awesome-icon icon="tag"/>&nbsp;{{recorder.model_name ? recorder.model_name : "undefined"}}<br/>
<font-awesome-icon icon="code"/>&nbsp;{{recorder.firmware_version ? recorder.firmware_version : "undefined"}}<br/>
<font-awesome-icon icon="video"/>&nbsp;{{recorder.additional_camera_connected ? "yes" : "no"}}<br/>
<font-awesome-icon icon="barcode"/>&nbsp;{{recorder.serial_number ? recorder.serial_number : "undefined"}}<br/>
<font-awesome-icon icon="home"/>&nbsp;{{recorder.room ? recorder.room.name : "undefined"}}
</p>
</div>
<strong>{{$t('created_at')}}:&nbsp</strong>{{recorder.created_at}}<br/>
<strong>{{$t('last_time_modified')}}:&nbsp</strong>{{recorder.last_time_modified}}<br/>
<hr/>
<h3 style="color: orangered;" v-if="recorder.offline"><font-awesome-icon icon="wrench"/>&nbsp;
{{recorder.offline ? 'The recorder is in offline / maintenance mode' : ''}}</h3>
<hr v-if="recorder.offline" />
<h3 style="color: red;" v-if="recorder.lock_message"><font-awesome-icon icon="lock"/>&nbsp;
{{recorder.lock_message}}</h3>
<hr v-if="recorder.lock_message" />
<div role="tablist">
<b-card no-body class="mb-1">
<b-card-header header-tag="header" class="p-1" role="tab">
<b-button block href="#" v-b-toggle.accordion-1 variant="info">Network</b-button>
</b-card-header>
<b-collapse id="accordion-1" accordion="my-accordion" role="tabpanel">
<b-card-body>
<strong>{{$t('ip')}}:&nbsp</strong>{{recorder.ip}}<br/>
<strong>{{$t('mac')}}:&nbsp</strong>{{recorder.mac}}<br/>
<strong>{{$t('network_name')}}:&nbsp</strong>{{recorder.network_name}}<br/>
<strong>{{$t('ssh_port')}}:&nbsp</strong>{{recorder.ssh_port}}<br/>
<strong>{{$t('telnet_port')}}:&nbsp</strong>{{recorder.telnet_port}}<br/>
</b-card-body>
</b-collapse>
</b-card>
<b-card v-if="recorder.description" no-body class="mb-1">
<b-card-header header-tag="header" class="p-1" role="tab">
<b-button block href="#" v-b-toggle.accordion-2 variant="info">Description</b-button>
</b-card-header>
<b-collapse id="accordion-2" accordion="my-accordion" role="tabpanel">
<b-card-body>
<b-card-text>{{recorder.description}}</b-card-text>
</b-card-body>
</b-collapse>
</b-card>
<b-card v-if="recorderModel" no-body class="mb-1">
<b-card-header header-tag="header" class="p-1" role="tab">
<b-button block href="#" v-b-toggle.accordion-2 variant="outline-primary">Model / Recorder Adapter Info</b-button>
</b-card-header>
<b-collapse id="accordion-2" accordion="my-accordion" role="tabpanel">
<b-card-body>
<strong>{{$t('name')}}:&nbsp</strong>{{recorderModel.name}}<br/>
<strong>{{$t('created_at')}}:&nbsp</strong>{{recorderModel.created_at}}<br/>
<strong>{{$t('last_time_modified')}}:&nbsp</strong>{{recorderModel.last_time_modified ? recorderModel.last_time_modified : 'never'}}<br/>
<strong>{{$t('requires_username')}}:&nbsp</strong>{{recorderModel.requires_username ? 'Yes' : 'No'}}<br/>
<strong>{{$t('requires_password')}}:&nbsp</strong>{{recorderModel.requires_password ? 'Yes' : 'No'}}<br/>
<span v-if="recorderModel.notes"><strong>{{$t('notes')}}:&nbsp</strong>{{recorderModel.notes}}<br/></span>
</b-card-body>
</b-collapse>
</b-card>
<b-card v-if="recorderModel" no-body class="mb-1">
<b-card-header header-tag="header" class="p-1" role="tab">
<b-button block href="#" v-b-toggle.accordion-3 variant="danger">
<span>Commands</span>
<span v-if="recorder.locked">&nbsp;({{$t('locked')}})</span>
<span v-if="recorder.offline">&nbsp;({{$t('offline')}})</span>
</b-button>
</b-card-header>
<b-collapse id="accordion-3" visible accordion="my-accordion" role="tabpanel">
<b-card-body>
<b-list-group style="max-height: 400px; overflow-y:scroll;" v-if="!(recorder.locked || recorder.offline)">
<b-list-group-item v-for="command in recorderModel.commands"
v-bind:key="command.id">
<h5>{{command.name}}</h5>
<b-row>
<b-col sm="3" v-for="(a_type, arg) in command.parameters"
v-bind:key="arg"
v-if="command.parameters !== null">
<b-form-input @focus="setup_params(command.id, arg)" @blur="set_param(command.id, arg, $event.target.value)"
:placeholder="arg + ' ('+a_type+')'"
:type="a_type==='int'?'number':'text'" style="margin-right: 10px;">
<small>{{arg}}:&nbsp;{{a_type}}</small>
</b-form-input>
</b-col>
</b-row>
<button class="float-right" @click="execute_command(command.id)"><font-awesome-icon icon="play"/></button>
<p v-if="cmd_res[command.id]">
<font-awesome-icon style="color: green;" v-if="cmd_res[command.id].ok" icon="smile"/>
<font-awesome-icon style="color: red;" v-else icon="frown"/>
&nbsp;<span>{{cmd_res[command.id].time | moment("HH:mm:ss")}}</span> &nbsp;-&nbsp;Output:
<strong>
<span v-if="cmd_res[command.id].ok">{{cmd_res[command.id].output}}</span>
<span v-else>{{cmd_res[command.id].error}}</span>
</strong>
</p>
</b-list-group-item>
</b-list-group>
<span v-else>The recorder is either locked or in offline mode commands are disabled!</span>
</b-card-body>
</b-collapse>
</b-card>
</div>
</div>
</div>
</section>
</div>
</template>
<script>
import {EventBus} from '@/utils';
import getRepository from '@/api/RepositoryFactory';
const controlRepository = getRepository('control');
export default {
props: ['recorder_id'],
data() {
return {
current_recorder_id: this.recorder_id == null ? 1 : parseInt(this.recorder_id),
current_recorder_index: null,
new_recorder_id: this.current_recorder_id,
cmd_params: {},
cmd_res: {}
};
},
methods: {
setup_params(command_id, argument) {
if (!(command_id in this.cmd_params)) {
this.$set(this.cmd_params, command_id, {});
}
this.$set(this.cmd_params[command_id], argument, null)
},
set_param(command_id, argument, val){
this.$set(this.cmd_params[command_id], argument, val)
},
manually_set_recorder_id() {
if (this.new_recorder_id == null || this.new_recorder_id === ''){
this.new_recorder_id = this.current_recorder_id;
return;
}
if (this.recorderIds.includes(parseInt(this.new_recorder_id))){
this.current_recorder_id = parseInt(this.new_recorder_id);
}
this.new_recorder_id = this.current_recorder_id;
},
lock() {
this.recorder.locked = true;
},
unlock() {
this.recorder.locked = false;
},
calculate_current_recorder_index() {
this.current_recorder_index = this.recorderIds.findIndex( (id) =>
{ return id === this.current_recorder_id});
},
previousRecorder() {
if (null == this.current_recorder_index) {
this.calculate_current_recorder_index();
}
if (this.current_recorder_index === 0) this.current_recorder_index = this.recorderIds.length - 1;
else this.current_recorder_index = this.current_recorder_index - 1;
this.current_recorder_id = this.recorderIds[this.current_recorder_index];
this.new_recorder_id = this.current_recorder_id;
},
nextRecorder() {
if (null == this.current_recorder_index) {
this.calculate_current_recorder_index();
}
if (this.current_recorder_index === this.recorderIds.length - 1) this.current_recorder_index = 0;
else this.current_recorder_index = this.current_recorder_index + 1;
this.current_recorder_id = this.recorderIds[this.current_recorder_index];
this.new_recorder_id = this.current_recorder_id;
},
execute_command(command_id) {
console.log("recorder: "+ this.current_recorder_id + "; "+ command_id);
console.log(this.cmd_params);
console.log(this.cmd_params[command_id]);
this.$parent.$data.isLoading = true;
controlRepository.runRecorderCommand(this.current_recorder_id, command_id, this.cmd_params[command_id]).then((out)=>{
this.$parent.$data.isLoading = false;
console.log(out.data);
this.$set(this.cmd_res, command_id, out.data);
});
},
},
mounted() {
this.$store.dispatch('loadRecorders');
this.$store.dispatch('loadRecorderModels');
},
beforeDestroy() {
EventBus.$off('failedLoadingProfile');
},
computed: {
recorders() {
return this.$store.state.recorders;
},
recorderIds() {
let ids = [];
this.recorders.forEach((elem)=>{
ids.push(parseInt(elem.id));
});
return ids;
},
recorder() {
const recorder = this.$store.state.recorders.filter((item) => {
return parseInt(item.id) === this.current_recorder_id;
});
if(recorder.length < 1){
this.$router.replace({name: 'notFound'});
return {};
}
return recorder.shift();
},
recorderModel() {
if(!this.recorder || !this.recorder.recorder_model) return null;
const model = this.recorderModels.filter((item) => {
return parseInt(item.id) === this.recorder.recorder_model.id;
});
if(model.length < 1){
return null;
}
return model.shift();
},
recorderModels() {
return this.$store.state.recorderModels;
},
access_token() {
return this.$store.state.access_token;
},
},
};
</script>
<style lang="scss">
.error-msg {
color: red;
font-weight: bold;
}
.lang-btn {
padding: 15px;
border: 2px solid green;
font-size: 18px;
margin: 15px;
}
</style>