277 lines
15 KiB
Vue
277 lines
15 KiB
Vue
<!-- 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()"/>
|
||
{{recorder.name}}
|
||
</h2>
|
||
|
||
<p>
|
||
<font-awesome-icon icon="tag"/> {{recorder.model_name ? recorder.model_name : "undefined"}}<br/>
|
||
<font-awesome-icon icon="code"/> {{recorder.firmware_version ? recorder.firmware_version : "undefined"}}<br/>
|
||
<font-awesome-icon icon="video"/> {{recorder.additional_camera_connected ? "yes" : "no"}}<br/>
|
||
<font-awesome-icon icon="barcode"/> {{recorder.serial_number ? recorder.serial_number : "undefined"}}<br/>
|
||
<font-awesome-icon icon="home"/> {{recorder.room ? recorder.room.name : "undefined"}}
|
||
|
||
</p>
|
||
</div>
|
||
<strong>{{$t('created_at')}}: </strong>{{recorder.created_at}}<br/>
|
||
<strong>{{$t('last_time_modified')}}: </strong>{{recorder.last_time_modified}}<br/>
|
||
|
||
<hr/>
|
||
<h3 style="color: orangered;" v-if="recorder.offline"><font-awesome-icon icon="wrench"/>
|
||
{{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"/>
|
||
{{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')}}: </strong>{{recorder.ip}}<br/>
|
||
<strong>{{$t('mac')}}: </strong>{{recorder.mac}}<br/>
|
||
<strong>{{$t('network_name')}}: </strong>{{recorder.network_name}}<br/>
|
||
|
||
<strong>{{$t('ssh_port')}}: </strong>{{recorder.ssh_port}}<br/>
|
||
<strong>{{$t('telnet_port')}}: </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')}}: </strong>{{recorderModel.name}}<br/>
|
||
<strong>{{$t('created_at')}}: </strong>{{recorderModel.created_at}}<br/>
|
||
<strong>{{$t('last_time_modified')}}: </strong>{{recorderModel.last_time_modified ? recorderModel.last_time_modified : 'never'}}<br/>
|
||
<strong>{{$t('requires_username')}}: </strong>{{recorderModel.requires_username ? 'Yes' : 'No'}}<br/>
|
||
<strong>{{$t('requires_password')}}: </strong>{{recorderModel.requires_password ? 'Yes' : 'No'}}<br/>
|
||
<span v-if="recorderModel.notes"><strong>{{$t('notes')}}: </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"> ({{$t('locked')}})</span>
|
||
<span v-if="recorder.offline"> ({{$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}}: {{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"/>
|
||
<span>{{cmd_res[command.id].time | moment("HH:mm:ss")}}</span> - 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>
|