Compare commits

...

5 Commits

Author SHA1 Message Date
peterlu14 73edf21824 [update] controller & device info setting page 2021-05-20 03:59:25 +08:00
peterlu14 ad404819b3 Merge branch 'fix/replay_mini_no_data' into feature/aboutPage 2021-05-12 11:46:16 +08:00
peterlu14 7ea36c565e [update] about page white list connect 2021-04-28 11:06:20 +08:00
peterlu14 5653c4d3de [update] about content & add new api and factory 2021-04-22 11:32:11 +08:00
peterlu14 227d61d8e4 [update] about page vuex 2021-04-22 11:31:14 +08:00
24 changed files with 806 additions and 6 deletions
+13
View File
@@ -14857,6 +14857,11 @@
"is-plain-obj": "^1.0.0"
}
},
"sortablejs": {
"version": "1.10.2",
"resolved": "https://registry.npmjs.org/sortablejs/-/sortablejs-1.10.2.tgz",
"integrity": "sha512-YkPGufevysvfwn5rfdlGyrGjt7/CRHwvRPogD/lC+TnvcN29jDpCifKP+rBqf+LRldfXSTh+0CGLcSg0VIxq3A=="
},
"source-list-map": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-2.0.1.tgz",
@@ -17248,6 +17253,14 @@
"resolved": "https://registry.npmjs.org/vue-yandex-maps/-/vue-yandex-maps-0.9.0.tgz",
"integrity": "sha512-6gXec68eXNHvo5d6m43lGCDMShYRpciWWy55VA1RiFtMkLHIDeK4CJzYmkfAec32vpzYEqdcNBJh9b93wqtp8w=="
},
"vuedraggable": {
"version": "2.24.3",
"resolved": "https://registry.npmjs.org/vuedraggable/-/vuedraggable-2.24.3.tgz",
"integrity": "sha512-6/HDXi92GzB+Hcs9fC6PAAozK1RLt1ewPTLjK0anTYguXLAeySDmcnqE8IC0xa7shvSzRjQXq3/+dsZ7ETGF3g==",
"requires": {
"sortablejs": "1.10.2"
}
},
"vuestic-ui": {
"version": "0.2.2",
"resolved": "https://registry.npmjs.org/vuestic-ui/-/vuestic-ui-0.2.2.tgz",
+1
View File
@@ -54,6 +54,7 @@
"vue-router": "^3.1.3",
"vue-worker": "^1.2.1",
"vue-yandex-maps": "^0.9.0",
"vuedraggable": "^2.24.3",
"vuestic-ui": "~0.2.2",
"vuetable-2": "^1.7.5",
"vuex": "^3.1.2",
+35
View File
@@ -0,0 +1,35 @@
<template>
<div class="about">
<controller-info/>
<device-info/>
</div>
</template>
<script>
import DeviceInfo from './deviceInfo.vue'
import ControllerInfo from './controllerInfo.vue'
export default {
name: 'about-content',
components: {
ControllerInfo,
DeviceInfo,
},
created () {
},
data () {
return {
}
},
computed: {
},
watch: {
},
methods: {
},
async mounted () {
},
destroyed () {
},
}
</script>
+140
View File
@@ -0,0 +1,140 @@
<template>
<div class="controller-info">
<div class="row flex">
<div
class="flex sm12 xl12 md12 xs12 ma-2"
v-for="controller in controllers" :key="controller.mac_address"
>
<va-card
style="border: 5px solid #78ceff; border-radius: 30px; font-size: 1.5rem;"
>
<!-- {{ controller }} -->
<va-item :key="controller.device_mac" class="pa-0 ma-0"
>
<va-item-section avatar class="ml-2 mr-2">
<img
:src="getImageUrl()"
:alt="'BPS-CONTROLLER'"
width="300px"
height="300px"
contain
/>
</va-item-section>
<va-item-section class="ml-4" >
<va-item-label style="font-size: 2rem;">
{{ controller.wifi_name }}
</va-item-label>
<va-item-label>
Mac Address :
{{ controller.mac_address.toUpperCase() }}
</va-item-label>
<va-item-label>
Build Version : #
{{ controller.software_version }}
</va-item-label>
<va-item-label>
Update Time :
{{ GLOBAL.dateToStr(controller.updated_at) }}
</va-item-label>
</va-item-section>
</va-item>
</va-card>
</div>
</div>
</div>
</template>
<script>
import { mapActions, mapGetters, mapMutations } from 'vuex'
import api from '@/data/api/index'
import types from '@/store/modules/about/types'
import eliteImgUrl from '@/assets/img/elite_img.png'
export default {
name: 'controller-info',
components: {
},
// props: {
// data: {
// type: Object,
// default: function () {
// return {}
// },
// },
// cardclass: {
// type: Array,
// default: function () {
// return ['xs12', 'md12', 'xl12', 'sm12']
// },
// },
// cardheight: {
// type: String,
// default: '82vh',
// },
// cardwidth: {
// type: String,
// default: 'auto',
// },
// },
created () {
},
data () {
return {
}
},
computed: {
controllers () {
return this.getAllController()
},
},
watch: {
},
methods: {
getImageUrl () {
return eliteImgUrl
},
...mapActions('about', [types.controller.init]),
...mapMutations('about', [types.controller.set, types.controller.updateByIndex]),
...mapGetters('about', [types.controller.getAll]),
},
async mounted () {
this.initController({ api: api })
},
destroyed () {
},
}
</script>
<style lang="scss">
.area-style {
height: auto;
overflow-y: hidden;
overflow-x: hidden;
@include media-breakpoint-only(xl) {
height: 48vh;
overflow-y: scroll;
overflow-x: hidden;
}
}
.drag-flex {
display: flex;
flex-direction: row;
flex-wrap: wrap;
}
.font-small {
color: rgb(113, 186, 255);
font-size: 16px;
}
.center-medium {
text-align: center;
font-size: 20px;
}
.center-large {
text-align: center;
font-size: 28px;
}
</style>
+166
View File
@@ -0,0 +1,166 @@
<template>
<div class="device-info">
<div class="row flex">
<draggable class="flex d-flex sm12 xl12 md12 xs12" v-model="devices" @start="drag=true" @end="drag=false" >
<div
class="flex d-flex sm12 xl3 md4 xs12 ma-0 area-style "
v-for="(device, index) in devices" :key="device.id"
>
<va-card
:noPadding="true"
style="border: 5px solid #78ceff; border-radius: 30px;"
>
<div class="center-large" >
<div class="flex d-flex sm12 xl12 md12 xs12 ">
<div class="sm11 xl11 md11 xs11 ml-2" style="text-align: start;">
{{ device.name }}
</div>
<div class="sm1 xl1 md1 xs1" style="text-align: right;">
<va-icon
name="ion ion-md-close"
class="mr-1"
color="#babfc2"
style="cursor: pointer;"
@click.native.stop="removeCheck(index, device)"
/>
</div>
</div>
</div>
<div class="center-medium">
<p> {{ device.name }} </p>
</div>
<div class="center-medium">
<p> {{ macArrayToString(device.mac_address) }} </p>
</div>
<div class="mt-4 mb-4" style="text-align: center;">
<img
:src="getImageUrl(device.library)"
:alt="device.name"
width="150px"
height="100px"
contain
/>
</div>
<div class="center-medium">
<p> {{ device.device_version }} </p>
<p> {{ timeStampToLocaleTime(device.updated_at) }} </p>
</div>
<div class="flex sm12 xl12 md12 xs12" style="text-align: center;">
<va-button v-if="device.auto_connect" color="success" @click="autoConnect(index, device)">Auto Connect</va-button>
<va-button v-if="!device.auto_connect" color="#babfc2" @click="autoConnect(index, device)" outline>Auto Connect</va-button>
<va-button >User Guide</va-button>
</div>
</va-card>
</div>
</draggable>
</div>
</div>
</template>
<script>
import { mapActions, mapGetters, mapMutations } from 'vuex'
import api from '@/data/api/index'
import types from '@/store/modules/about/types'
import neuliveImgUrl from '@/assets/img/neulive_img.png'
import eliteImgUrl from '@/assets/img/elite_img.png'
import draggable from 'vuedraggable'
export default {
name: 'device-info',
components: {
draggable,
},
created () {
},
data () {
return {
}
},
computed: {
devices: {
get () {
return this.getAllDevice()
},
set (deviceList) {
this.reorderDevice({ deviceList: deviceList, api: api })
},
},
},
watch: {
},
methods: {
macArrayToString: function (macAddress) {
return this.GLOBAL.transMac(JSON.parse(macAddress))
},
timeStampToLocaleTime: function (time) {
return this.GLOBAL.dateToStr(time)
},
getImageUrl (libraryName) {
if (libraryName !== null) {
if (libraryName.indexOf('Neulive') >= 0) {
return neuliveImgUrl
} else if (libraryName.indexOf('Elite') >= 0) {
return eliteImgUrl
}
}
return null
},
autoConnect (index, device) {
device.auto_connect = !device.auto_connect
this.updateDatabaseByIDDevice({
id: device.id,
request: { auto_connect: device.auto_connect },
api: api,
})
this.updateByIndexDevice({ index: index, item: { auto_connect: device.auto_connect } })
},
removeCheck (index, device) {
/**
* TODO remove modal
*/
this.removeDevice({ id: device.id, index: index, device, deviceList: this.devices, api: api })
},
...mapActions('about', [types.device.init, types.device.remove, types.device.reorder, types.device.updateDatabaseByID]),
...mapMutations('about', [types.device.set, types.device.updateByIndex]),
...mapGetters('about', [types.device.getAll]),
},
async mounted () {
this.initDevice({ api: api })
},
destroyed () {
},
}
</script>
<style lang="scss">
.area-style {
height: auto;
overflow-y: hidden;
overflow-x: hidden;
@include media-breakpoint-only(xl) {
height: 48vh;
overflow-y: scroll;
overflow-x: hidden;
}
}
.drag-flex {
display: flex;
flex-direction: row;
flex-wrap: wrap;
}
.font-small {
color: rgb(113, 186, 255);
font-size: 16px;
}
.center-medium {
text-align: center;
font-size: 20px;
}
.center-large {
text-align: center;
font-size: 28px;
}
</style>
@@ -47,6 +47,13 @@ export const navigationRoutes = {
iconClass: 'vuestic-iconset vuestic-iconset-files',
},
},
{
name: 'settings',
displayName: 'Settings',
meta: {
iconClass: 'vuestic-iconset vuestic-iconset-settings',
},
},
// {
// name: 'forms',
// displayName: 'menu.forms',
+1 -1
View File
@@ -137,9 +137,9 @@
</template>
<script>
import api from '@/data/api/index'
import { taskInfo } from '../../data/task/TaskInfo'
import { FulfillingBouncingCircleSpinner } from 'epic-spinners'
import api from '../../data/api/index'
export default {
name: 'devices-overview',
+77 -5
View File
@@ -76,6 +76,16 @@ async function getCollectionsAll () {
}
}
async function getControllersAll () {
const _header = getHeader()
try {
return await axios.get('/api/controller/get/all', { headers: _header })
} catch (e) {
console.error(e)
return false
}
}
async function getCollectionsByParentName (collectionType, parent, name) {
console.log(collectionType, parent, name)
const _header = getHeader()
@@ -87,6 +97,66 @@ async function getCollectionsByParentName (collectionType, parent, name) {
}
}
async function createDevice (attrs) {
const _header = getHeader()
try {
return await axios.post('/api/device/create', attrs, { headers: _header })
} catch (e) {
console.error(e)
return false
}
}
async function updateDeviceByID (id, attrs) {
const _header = getHeader()
try {
return await axios.post(`/api/device/update_by_id/${id}`, attrs, { headers: _header })
} catch (e) {
console.error(e)
return false
}
}
async function deleteDevice (id) {
const _header = getHeader()
try {
return await axios.get(`/api/device/clear_deleted/${id}`, { headers: _header })
} catch (e) {
console.error(e)
return false
}
}
async function getDeviceByID (id) {
const _header = getHeader()
try {
return await axios.get('/api/device/get_by_id/' + id, { headers: _header })
} catch (e) {
console.error(e)
return false
}
}
async function getDeviceByName (name) {
const _header = getHeader()
try {
return await axios.get('/api/device/get_by_name/' + name, { headers: _header })
} catch (e) {
console.error(e)
return false
}
}
async function getDevicesAll () {
const _header = getHeader()
try {
return await axios.get('/api/device/get/all', { headers: _header })
} catch (e) {
console.error(e)
return false
}
}
async function createMetaFile () {
const _header = getHeader()
try {
@@ -98,7 +168,6 @@ async function createMetaFile () {
}
async function updateMetaFile (id, attrs) {
console.log('updateMetaFile')
const _header = getHeader()
try {
return await axios.post(`/api/file/meta/update/${id}`, attrs, { headers: _header })
@@ -109,7 +178,6 @@ async function updateMetaFile (id, attrs) {
}
async function updateRawFile (channel, id, attrs) {
console.log('updateRawFile')
const _header = getHeader()
try {
return await axios.post(`/api/file/raw/update/${channel}/${id}`, attrs, { headers: _header })
@@ -120,7 +188,6 @@ async function updateRawFile (channel, id, attrs) {
}
async function updateMiniFile (channel, id, attrs) {
console.log('updateMiniFile')
const _header = getHeader()
try {
return await axios.post(`/api/file/mini/update/${channel}/${id}`, attrs, { headers: _header })
@@ -141,7 +208,6 @@ async function clearDeleteMetaFile (id) {
}
async function clearDeleteRawFile (channel, id) {
console.log('clearDeleteRawFile')
const _header = getHeader()
try {
return await axios.get(`/api/file/raw/clear_deleted/${channel}/${id}`, { headers: _header })
@@ -152,7 +218,6 @@ async function clearDeleteRawFile (channel, id) {
}
async function clearDeleteMiniFile (channel, id) {
console.log('clearDeleteMiniFile')
const _header = getHeader()
try {
return await axios.get(`/api/file/mini/clear_deleted/${channel}/${id}`, { headers: _header })
@@ -310,6 +375,13 @@ const api = {
getCollectionsByParent,
getCollectionsByParentName,
getCollectionsAll,
getControllersAll,
createDevice,
updateDeviceByID,
deleteDevice,
getDeviceByID,
getDeviceByName,
getDevicesAll,
createMetaFile,
updateMetaFile,
updateRawFile,
+13
View File
@@ -0,0 +1,13 @@
function newController (controllerID) {
return {
controller: {
name: '',
mac_address: '',
controller_id: '',
build_number: '',
update_time: '',
},
}
}
export default newController
+31
View File
@@ -0,0 +1,31 @@
function newDevice () {
return {
device: {
name: '',
mac_address: '',
serial_number: '',
configuration: '',
library: '',
library_version: '',
device_version: '',
battery: 0,
type: '',
temperature: '',
auto_connect: false,
connect_priorty: 0,
connect_time: 0,
status: '',
parameter_set: -1,
calibration: '',
user_auth: {
owner: [],
maintainer: [],
guest: [],
},
created_at: '',
updated_at: '',
},
}
}
export default newDevice
+13
View File
@@ -81,6 +81,11 @@ export default new Router({
component: () => import('../components/dashboard/Dashboard.vue'),
default: true,
},
{
name: 'about',
path: 'about',
component: () => import('../components/about/aboutContent.vue'),
},
{
name: 'devices',
path: 'devices',
@@ -114,6 +119,14 @@ export default new Router({
// keepAlive: true,
// },
},
{
name: 'settings',
path: 'settings',
component: () => import('../components/about/aboutContent.vue'),
// meta: {
// keepAlive: true,
// },
},
{
name: 'statistics',
path: 'statistics',
+2
View File
@@ -6,6 +6,7 @@ import state from './state'
import neuliveReplay from './modules/analysis/replay/neulive'
import eliteReplay from './modules/analysis/replay/elite'
import projectContent from './modules/project/content'
import about from './modules/about'
import mutations from './mutations'
import * as getters from './getters'
@@ -19,6 +20,7 @@ const store = new Vuex.Store({
neuliveReplay,
eliteReplay,
projectContent,
about,
},
state: state,
mutations: mutations,
@@ -0,0 +1,17 @@
import types from '@/store/modules/about/types'
const typePath = types.controller
const controllerActs = {
/**
* init controller list
*
* @return {object} : controller data
*/
[typePath.init]: async ({ state, getters, commit, dispatch }, payload) => {
const controllers = await payload.api.getControllersAll()
commit(typePath.set, { list: controllers.data })
},
}
export default controllerActs
@@ -0,0 +1,66 @@
import types from '@/store/modules/about/types'
const typePath = types.device
const deviceActs = {
/**
* init devices list
*
* @param {object} api
*/
[typePath.init]: async ({ state, getters, commit, dispatch }, payload) => {
const devices = await payload.api.getDevicesAll()
commit(typePath.set, { deviceList: devices.data })
},
/**
* reorder devices list
*
* @param {object} api
* @param {object} deviceList
*/
[typePath.reorder]: async ({ state, getters, commit, dispatch }, payload) => {
if (payload.deviceList.length > 0) {
// update connect_priority according to id
payload.deviceList.map((v, idx) => {
v.connect_priority = idx
})
// update database device's info
for (const device of payload.deviceList) {
dispatch(typePath.updateDatabaseByID, { id: device.id, request: { connect_priority: device.connect_priority }, api: payload.api })
}
commit(typePath.set, { deviceList: payload.deviceList })
}
},
/**
* update database device table data by ID with request
*
* @param {number} id
* @param {object} request
* @param {object} api
*/
[typePath.updateDatabaseByID]: async ({ state, getters, commit, dispatch }, payload) => {
await payload.api.updateDeviceByID(payload.id, payload.request)
},
/**
* delete device
*
* @param {number} id
* @param {number} index
* @param {Array} deviceList
* @param {object} api
*/
[typePath.remove]: async ({ state, getters, commit, dispatch }, payload) => {
if (payload.deviceList.length > 0) {
payload.deviceList.splice(payload.index, 1)
dispatch(typePath.reorder, { deviceList: payload.deviceList, api: payload.api })
await dispatch(typePath.updateDatabaseByID, { id: payload.id, request: { deleted: true }, api: payload.api })
await payload.api.deleteDevice(payload.id)
}
},
}
export default deviceActs
+7
View File
@@ -0,0 +1,7 @@
import deviceAct from './deviceAct'
import controllerAct from './controllerAct'
export default {
...deviceAct,
...controllerAct,
}
@@ -0,0 +1,44 @@
import types from '@/store/modules/about/types'
const typePath = types.controller
const controllerGets = {
/**
* get controller by list index
*
* @param {int} index
* @return {object} : controller info
*/
[typePath.getByIndex]: (state) => (index) => {
if (index == null || state.controllerInfoList[index] == null) {
return null
}
return state.controllerInfoList[index]
},
/**
* get controller by id
*
* @param {int} id
* @return {object} : controller info
*/
[typePath.getByID]: (state) => (id) => {
state.controllerInfoList.forEach(controller => {
if (controller.id === id) {
return controller
}
})
return null
},
/**
* get all controller info
*
* @return {Array} : controller list
*/
[typePath.getAll]: (state) => {
return state.controllerInfoList
},
}
export default controllerGets
@@ -0,0 +1,44 @@
import types from '@/store/modules/about/types'
const typePath = types.device
const deviceGets = {
/**
* get device by list index
*
* @param {int} index
* @return {object} : device info
*/
[typePath.getByIndex]: (state) => (index) => {
if (index == null || state.deviceInfoList[index] == null) {
return null
}
return state.deviceInfoList[index]
},
/**
* get device by id
*
* @param {int} id
* @return {object} : device info
*/
[typePath.getByID]: (state) => (id) => {
state.deviceInfoList.forEach(device => {
if (device.id === id) {
return device
}
})
return null
},
/**
* get all device info
*
* @return {Array} : device list
*/
[typePath.getAll]: (state) => {
return state.deviceInfoList
},
}
export default deviceGets
+7
View File
@@ -0,0 +1,7 @@
import deviceGet from './deviceGet'
import controllerGet from './controllerGet'
export default {
...deviceGet,
...controllerGet,
}
+12
View File
@@ -0,0 +1,12 @@
import actions from './actions'
import getters from './getters'
import mutations from './mutations'
import state from './state'
export default {
namespaced: true,
state: state,
getters: getters,
actions: actions,
mutations: mutations,
}
@@ -0,0 +1,30 @@
import types from '@/store/modules/about/types'
const typePath = types.controller
const controllerMutations = {
/**
* set controller info list
*
*/
[typePath.set]: async (state, payload) => {
state.controllerInfoList.length = 0
state.controllerInfoList.push(...payload.list)
},
/**
* update controller info list by index
*
* @param {number} index
* @param {any} item
*/
[typePath.updateByIndex]: async (state, payload) => {
for (const item in payload) {
if (item !== 'index') {
state.controllerInfoList[payload.index][item] = payload[item]
}
}
},
}
export default controllerMutations
@@ -0,0 +1,35 @@
import types from '@/store/modules/about/types'
const typePath = types.device
const deviceMutations = {
/**
* set device info list
*
* @param {Array} deviceList
*/
[typePath.set]: async (state, payload) => {
state.deviceInfoList.length = 0
state.deviceInfoList.push(...payload.deviceList)
},
/**
* update device info list by index
*
* @param {number} index
* @param {object} item
*/
[typePath.updateByIndex]: async (state, payload) => {
for (const idx in payload.item) {
state.deviceInfoList[payload.index][idx] = payload.item[idx]
}
},
[typePath.removeByIndex]: async (state, payload) => {
for (const idx in payload.item) {
state.deviceInfoList[payload.index][idx] = payload.item[idx]
}
},
}
export default deviceMutations
@@ -0,0 +1,7 @@
import deviceMut from './deviceMut'
import controllerMut from './controllerMut'
export default {
...deviceMut,
...controllerMut,
}
+8
View File
@@ -0,0 +1,8 @@
function newState () {
return {
controllerInfoList: [],
deviceInfoList: [],
}
}
export default newState
+30
View File
@@ -0,0 +1,30 @@
const types = {
controller: {
init: 'initController',
set: 'setController',
setByApi: 'setByApiController',
updateByIndex: 'updateByIndexController',
getByIndex: 'getByIndexController',
getByID: 'getByIDController',
getAll: 'getAllController',
},
device: {
init: 'initDevice',
remove: 'removeDevice',
reorder: 'reorderDevice',
updateDatabaseByID: 'updateDatabaseByIDDevice',
set: 'setDevice',
setByApi: 'setByApiDevice',
updateByIndex: 'updateByIndexDevice',
getByIndex: 'getByIndexDevice',
getByID: 'getByIDDevice',
getAll: 'getAllDevice',
},
}
export default types