Compare commits

...

9 Commits

Author SHA1 Message Date
peterlu14 f86e7ea5de Merge branch 'feature/setting_update' into develop/neulive_0901 2021-09-15 15:58:45 +08:00
peterlu14 16df8514ba [update] setting pic update & display fix 2021-09-09 13:39:21 +08:00
Jordan Hsu a5085cbbe6 sd card UI 2021-09-08 21:29:55 +08:00
peterlu14 1fbf8c0022 [update] download replay data 2021-09-08 20:07:28 +08:00
peterlu14 0f5cbaf778 [update] sd_data download & replay 2021-09-08 16:26:49 +08:00
Jordan Hsu 2b5b42dd61 tmp for api debug 2021-09-08 13:52:59 +08:00
Jordan Hsu 4221a35f00 Merge remote-tracking branch 'origin/develop/neulive_0901' into feature/SD_card_UI 2021-09-08 11:06:41 +08:00
Jordan Hsu 047a72e9c6 [add] SD card init func 2021-09-07 16:56:29 +08:00
Jordan Hsu b79a4a2091 [init] SD card UI 2021-09-07 15:44:44 +08:00
24 changed files with 399 additions and 24 deletions
+5
View File
@@ -12106,6 +12106,11 @@
"set-blocking": "~2.0.0"
}
},
"nprogress": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/nprogress/-/nprogress-0.2.0.tgz",
"integrity": "sha1-y480xTIT2JVyP8urkH6UIq28r7E="
},
"nth-check": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/nth-check/-/nth-check-1.0.2.tgz",
+1
View File
@@ -35,6 +35,7 @@
"lodash": "^4.17.21",
"medium-editor": "^5.23.3",
"normalize.css": "^8.0.1",
"nprogress": "^0.2.0",
"popper.js": "^1.16.0",
"regenerator-runtime": "^0.13.3",
"register-service-worker": "^1.6.2",
+1
View File
@@ -31,6 +31,7 @@ import VueWorker from 'vue-worker'
import axios from 'axios'
import VueAxios from 'vue-axios'
import 'nprogress/nprogress.css'
import '../metrics'
import '../registerServiceWorker'
Binary file not shown.

After

Width:  |  Height:  |  Size: 108 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 201 KiB

@@ -18,6 +18,7 @@
</div>
<change-cycle v-show="showCyclePanel" style="margin: 3px;" :ref="'change_cycle'" @refreshChart="refreshChart"/>
<show-resample-rate style="margin: 3px;"/>
<sd-card-toggle :ref="'sd_card_toggle'"/>
<show-parameter style="margin: 3px;" :ref="'show_param'" deviceName="elite"/>
</va-card>
</div>
@@ -33,6 +34,7 @@ import DownloadFile from '@/components/analysis/replay/toolbox/DownloadFile.vue'
import DeleteFile from '@/components/analysis/replay/toolbox/DeleteFile.vue'
import EditFileName from '@/components/analysis/replay/toolbox/EditFileName.vue'
import ShowParameter from '@/components/analysis/replay/toolbox/ShowParameter.vue'
import SdCardToggle from '@/components/analysis/replay/toolbox/SdCardToggle.vue'
import { mapFields } from 'vuex-map-fields'
export default {
@@ -47,6 +49,7 @@ export default {
DeleteFile,
EditFileName,
ShowParameter,
SdCardToggle,
},
computed: {
...mapFields('replay', [
@@ -59,6 +59,7 @@ export default {
'startTimeCurrent',
'endTimeCurrent',
'sampleMethod',
'useSdCardData',
]),
},
props: {
@@ -133,7 +134,11 @@ export default {
},
getData: async function (scale, sampleMethod, id, channel, meta) {
if (scale === 1) {
return await download.rawByIDChannels(id, channel, meta)
if (this.useSdCardData) {
return await download.rawSdDataByIDChannels(id, channel, meta)
} else {
return await download.rawByIDChannels(id, channel, meta)
}
} else {
if (sampleMethod === 'mean') {
return await download.miniMeanByIDChannel(id, channel, meta)
@@ -12,6 +12,7 @@
<change-unit v-show="showXUnit" :ref="'change_unit_x'" deviceName="neulive" axis="x" @refreshChart="refreshChart"/>
<change-unit :ref="'change_unit_y'" class="box_inline-block" deviceName="neulive" axis="y" @refreshChart="refreshChart"/>
<change-scale :ref="'change_scale_y'" class="box_inline-block" deviceName="neulive" axis="y"/>
<sd-card-toggle :ref="'sd_card_toggle'"/>
<show-parameter :ref="'show_param'" deviceName="neulive"/>
</va-card>
</div>
@@ -26,6 +27,7 @@ import DownloadFile from '@/components/analysis/replay/toolbox/DownloadFile.vue'
import DeleteFile from '@/components/analysis/replay/toolbox/DeleteFile.vue'
import EditFileName from '@/components/analysis/replay/toolbox/EditFileName.vue'
import ShowParameter from '@/components/analysis/replay/toolbox/ShowParameter.vue'
import SdCardToggle from '@/components/analysis/replay/toolbox/SdCardToggle.vue'
export default {
name: 'top-control-panel',
@@ -38,6 +40,7 @@ export default {
DeleteFile,
EditFileName,
ShowParameter,
SdCardToggle,
},
computed: {
},
@@ -0,0 +1,60 @@
<template>
<div class="row flex sm12 xl12 md12 xs12 align--center my-0 py-0">
<div class="flex sm4 xl4 md4 xs4 px-0 mx-0">
<p class="display-6">Window size<p/>
</div>
<div class="flex sm8 xl8 md8 xs8 px-0 mx-0">
<va-input
@keyup.enter="itemChange(windowSize)"
@blur="itemChange(windowSize)"
v-model="windowSize"
class="mb-0"
>
<p slot="append" style="margin-right: 0;" small>
µs
</p>
</va-input>
</div>
</div>
</template>
<script>
import { mapFields } from 'vuex-map-fields'
export default {
name: 'ChangeWindowSize',
components: {
},
computed: {
...mapFields('replay', [
'startTimeCurrent',
'endTimeCurrent',
'windowSize',
]),
},
props: {
},
created () {
},
data () {
return {
}
},
mqtt: {
},
methods: {
itemChange (val) {
this.windowSize = parseInt(val)
// this.endTimeCurrent = this.startTimeCurrent + parseInt(val)
// this.$emit('reDraw')
},
},
async mounted () {
},
destroyed () {
},
watch: {
},
}
</script>
@@ -0,0 +1,48 @@
<template>
<div>
<span class="box_inline-block"> use SD card data </span>
<va-toggle flat small class="box_inline-block" v-model="useSdCardData"/>
</div>
</template>
<script>
import { mapFields } from 'vuex-map-fields'
export default {
name: 'SdCardToggle',
components: {
},
computed: {
...mapFields('replay', [
'useSdCardData',
]),
},
props: {
},
created () {
},
data () {
return {
}
},
mqtt: {
},
methods: {
},
async mounted () {
},
destroyed () {
},
watch: {
},
}
</script>
<style lang="scss">
.box_inline-block {
padding: 1px;
margin: 1px;
display: inline-block;
}
</style>
+17 -6
View File
@@ -60,6 +60,7 @@ export default {
...mapActions('download',
[
types.raw.rawDataByID,
types.raw.rawSdDataByID,
types.export.setHeader,
types.export.setTitle,
types.export.setData,
@@ -81,6 +82,7 @@ export default {
// TODO authorization
const format = this.$route.params.format
this.metaList = this.$route.params.metaList.split('-')
const sd = this.$route.params.sd
while (this.metaList.length !== 0) {
let meta
@@ -159,12 +161,21 @@ export default {
const rawID = this.downloadInfo.channelInfo[channel].downloadIDList[_idx][rowIndex]
// console.log(rowIndex, _idx, rawID)
if (rawID !== undefined) {
await this.rawDataByIDRaw({
channel: channel,
rawID: rawID,
idx: _idx,
api: api,
})
if (sd === 'sd') {
await this.rawSdDataByIDRaw({
channel: channel,
rawID: rawID,
idx: _idx,
api: api,
})
} else {
await this.rawDataByIDRaw({
channel: channel,
rawID: rawID,
idx: _idx,
api: api,
})
}
}
}
}
@@ -182,6 +182,9 @@
<va-popover :message="`download ${props.rowData.name} in csv-edf format`" placement="top">
<va-button flat small color="gray" icon="fa fa-download" v-if="props.rowData.type !== 'folder' && props.rowData.device.library_name.indexOf('Neulive') >= 0" @click.stop="downloadExcel(props.rowData)"/>
</va-popover>
<va-popover :message="`sdcard ${props.rowData.name}`" placement="top">
<sd-card-button v-if="props.rowData.type !== 'folder' && props.rowData.device.library_name.indexOf('Neulive') >= 0" :meta="props.rowData" @refreshPage="refreshPage" @downloadSdCard="downloadSdCard"/>
</va-popover>
<va-popover :message="`replay ${props.rowData.name}`" placement="top">
<va-button flat small color="gray" icon="fa fa-eye" v-if="props.rowData.type !== 'folder'" @click.stop="replay(props.rowData)"/>
</va-popover>
@@ -205,11 +208,13 @@ import { debounce } from 'lodash'
import { file } from '../../../data/file/File'
import { FulfillingBouncingCircleSpinner } from 'epic-spinners'
import api from '../../../data/api/index'
import SdCardButton from '../sdcard/SdCardButton.vue'
export default {
name: 'FileTable',
components: {
FulfillingBouncingCircleSpinner,
SdCardButton,
},
data () {
return {
@@ -661,6 +666,12 @@ export default {
window.open('http://' + href + '/#/download/csv-edf/' + meta.id)
}
},
downloadSdCard: async function (meta) {
const href = location.href.split('/')[2]
if (meta.device.library_name.indexOf('Neulive') >= 0) {
window.open('http://' + href + '/#/download/csv/' + meta.id + '/sd')
}
},
replay: function (meta) {
if (meta.device.library_name.includes('Neulive') === true) {
// window.open('http://' + location.href.split('/')[2].split(':')[0] + '/#/admin/data-replay/' + meta.id)
+134
View File
@@ -0,0 +1,134 @@
<template>
<div>
<va-button
flat
small
color="gray"
:icon="icon"
:disabled="isButtonDisable"
@click.stop="checkButtonState()"
>
<p :style="{color: this.$themes.danger}" class="display-6" v-show="!isButtonDisable && !isSdCardDataLoaded">
!
</p>
</va-button>
</div>
</template>
<script>
import { apiManager } from './apiManager'
export default {
name: 'SdCardButton',
components: {
},
props: {
meta: {
type: Object,
required: true,
},
},
data () {
return {
isButtonDisable: false,
isSdCardDataLoaded: false,
checkSDresult: '',
metaID: '',
mac_address: '',
uuid: '',
icon: 'fa fa-eye',
}
},
mqtt: {
},
methods: {
initMetaInfo () {
this.metaID = this.meta.id
this.mac_address = this.meta.device.device_address.toString()
this.uuid = this.meta.uuid
},
initButtonState () {
const exist = this.meta.sd_data_exist // null, ture or false
const uploaded = this.meta.sd_data_uploaded // null, ture or false
if (exist === false) {
this.isButtonDisable = true
} else if (exist === true || exist === null) { // null: default value, mean it hasn't be checked yet
this.isButtonDisable = false
}
if (uploaded === false || uploaded === null) { // null: default value, mean it hasn't be uploaded yet
this.isSdCardDataLoaded = false
} else if (uploaded === true) {
this.icon = 'fa fa-download'
this.isSdCardDataLoaded = true
}
},
init () {
this.initMetaInfo()
this.initButtonState()
},
async checkButtonState () {
const exist = this.meta.sd_data_exist // null, ture or false
const uploaded = this.meta.sd_data_uploaded // null, ture or false
if (exist === null) {
const checkResult = await this.checkInSD()
if (checkResult === 'True') {
await this.moveToDB()
await this.deleteSDCard()
this.$emit('refreshPage')
}
} else if (exist === true) {
if (uploaded !== true) {
await this.moveToDB()
await this.deleteSDCard()
this.$emit('refreshPage')
} else {
this.$emit('downloadSdCard', this.meta)
}
}
},
async checkInSD () {
console.log('checkInSD')
this.pageToast('Start checking in SD card')
apiManager.startProgressBar()
const result = await apiManager.call('Check_in_SD', this.metaID, this.mac_address, this.uuid)
this.checkSDresult = result.data
this.pageToast('In SD card: ' + this.checkSDresult)
apiManager.endProgressBar()
return result.data
},
async moveToDB () {
console.log('moveToDB')
this.pageToast('Start Moving to database...')
apiManager.startProgressBar()
await apiManager.call('Move_to_DB', this.metaID, this.mac_address, this.uuid)
apiManager.endProgressBar()
},
async deleteSDCard () {
console.log('deleteSDCard')
this.pageToast('Start deleting in SD card')
apiManager.startProgressBar()
await apiManager.call('Delete_SD', this.metaID, this.mac_address, this.uuid)
apiManager.endProgressBar()
console.log(status)
},
pageToast: function (mes) {
this.showToast(
mes,
{
icon: 'fa-bell',
position: 'bottom-right',
duration: 4000,
},
)
},
},
async mounted () {
this.init()
},
destroyed () {
},
watch: {
},
}
</script>
+32
View File
@@ -0,0 +1,32 @@
import api from '@/data/api/index'
import nProgress from 'nprogress'
export const apiManager = {
call: async (instruction, metaID, macAddress, uuid) => {
if (instruction === 'Check_in_SD') {
return await api.sdcard.exist({
id: metaID,
mac: macAddress,
uuid: uuid,
})
} else if (instruction === 'Delete_SD') {
return await api.sdcard.deleted({
id: metaID,
mac: macAddress,
uuid: uuid,
})
} else if (instruction === 'Move_to_DB') {
return await api.sdcard.upload({
id: metaID,
mac: macAddress,
uuid: uuid,
})
}
},
startProgressBar: () => {
nProgress.start()
},
endProgressBar: () => {
nProgress.done()
},
}
+2 -2
View File
@@ -47,7 +47,7 @@
import { mapActions, mapGetters, mapMutations } from 'vuex'
import api from '@/data/api/index'
import types from '@/store/modules/setting/types'
import eliteImgUrl from '@/assets/img/elite_img.png'
import controllerImgUrl from '@/assets/img/controller.png'
export default {
name: 'controller-info',
@@ -90,7 +90,7 @@ export default {
},
methods: {
getImageUrl () {
return eliteImgUrl
return controllerImgUrl
},
...mapActions('setting', [types.controller.init]),
...mapMutations('setting', [types.controller.set, types.controller.updateByIndex]),
+13 -6
View File
@@ -1,9 +1,10 @@
<template>
<div class="device-info">
<div class="row flex">
<draggable class="flex d-flex sm12 xl12 md12 xs12" v-model="devicesList" @start="drag=true" @end="drag=false" >
<div class="flex-wrap-setting sm12 xl12 md12 xs12">
<!-- <draggable class="flex d-flex sm12 xl12 md12 xs12" v-model="devicesList" @start="drag=true" @end="drag=false" > -->
<div
class="flex d-flex sm12 xl3 md4 xs12 ma-0 area-style-setting-device "
class="flex d-flex sm12 xl3 md6 xs12 ma-0"
v-for="(device, index) in devicesList" :key="device.id"
>
<va-card
@@ -52,7 +53,8 @@
</div>
</va-card>
</div>
</draggable>
</div>
<!-- </draggable> -->
</div>
</div>
</template>
@@ -62,13 +64,12 @@ import { mapFields } from 'vuex-map-fields'
import api from '@/data/api/index'
import types from '@/store/modules/setting/types'
import neuliveImgUrl from '@/assets/img/neulive_img.png'
import eliteImgUrl from '@/assets/img/elite_img.png'
import draggable from 'vuedraggable'
import eliteImgUrl from '@/assets/img/elite_img_v2.png'
// import draggable from 'vuedraggable'
export default {
name: 'device-info',
components: {
draggable,
},
created () {
},
@@ -163,4 +164,10 @@ export default {
text-align: center;
font-size: 28px;
}
.flex-wrap-setting {
display: flex;
flex-direction: horizontal;
flex-wrap: wrap;
}
</style>
+10 -2
View File
@@ -1,7 +1,15 @@
<template>
<div class="about">
<controller-info/>
<device-info/>
<div class="row">
<div class="flex sm12 xl12 md12 xs12">
<controller-info/>
</div>
</div>
<div class="row">
<div class="flex sm12 xl12 md12 xs12">
<device-info/>
</div>
</div>
</div>
</template>
<script>
@@ -208,7 +208,7 @@ export default {
{
id: 7,
value: 30000,
description: '20k',
description: '30k',
},
{
id: 8,
@@ -218,17 +218,17 @@ export default {
{
id: 9,
value: 50000,
description: '20k',
description: '50k',
},
{
id: 10,
value: 60000,
description: '20k',
description: '60k',
},
{
id: 11,
value: 70000,
description: '20k',
description: '70k',
},
{
id: 12,
@@ -238,7 +238,7 @@ export default {
{
id: 13,
value: 90000,
description: '20k',
description: '90k',
},
{
id: 14,
+2
View File
@@ -8,6 +8,7 @@ import meta from './meta'
import raw from './raw'
import mini from './mini'
import analysis from './analysis'
import sdcard from './sdcard'
// axios.defaults.baseURL = 'http://192.168.3.53:3000'
axios.defaults.baseURL = 'http://' + location.href.split('/')[2].split(':')[0] + ':3000'
@@ -23,6 +24,7 @@ const api = {
raw,
mini,
analysis,
sdcard,
}
export default api
+1 -1
View File
@@ -106,7 +106,7 @@ export const download = {
parseRawSdData: async function (rawData, prevLastTime, meta, dataArray) {
for (const raw of rawData) {
if (raw.sd_data !== null && raw.sd_data.length > 0) {
const encodedData = raw.sd_data.split('"***"')
const encodedData = raw.sd_data.split('"***"').slice(0, -1)
const unzipDatas = encodedData.map(ctx => {
return ctx.split(' ')
})
+1 -1
View File
@@ -76,7 +76,7 @@ export default new Router({
children: [
{
name: 'download',
path: ':format/:metaList',
path: ':format/:metaList/:sd?',
component: () => import('../components/download/Download.vue'),
},
],
@@ -28,6 +28,7 @@ function newState () {
valueFormatX: {},
valueFormatY: {},
showCyclePanel: false,
useSdCardData: false,
}
}
@@ -23,6 +23,18 @@ const rawActs = {
}
},
[typePath.rawSdDataByID]: async ({ state, getters, commit, dispatch }, payload) => {
const { channel, rawID, idx, api } = payload
const rawDataRes = await api.raw.getAttrByID(channel, rawID, 'id-channel-size-serial_number-start_time-end_time-sd_data')
if (rawDataRes.data !== null) {
if (state.downloadInfo.channelInfo[channel].downloadDataBuffer[idx] === undefined) {
state.downloadInfo.channelInfo[channel].downloadDataBuffer[idx] = []
}
dispatch(typePath.parseRawSdData, { channel: channel, idx: idx, rawData: rawDataRes })
}
},
/**
* get raw data by multi ID from database
*
@@ -72,6 +84,35 @@ const rawActs = {
delete payload.rawData
},
[typePath.parseRawSdData]: function ({ state, getters, commit, dispatch }, payload) {
const { channel, rawData, idx } = payload
for (const raw of rawData.data) {
if (raw.sd_data !== null && raw.sd_data.length > 0) {
const encodedData = raw.sd_data.split('"***"').slice(0, -1)
const unzipDatas = encodedData.map(ctx => {
return ctx.split(' ')
})
for (let i = 0; i <= unzipDatas.length - 1; i++) {
if (unzipDatas[i].length > 0) {
if (state.downloadInfo === undefined) {
dispatch(typePath.parseData, { channel: channel, rawData: unzipDatas[i], idx: idx })
} else {
if (state.downloadInfo.format === 'csv-edf') {
dispatch(typePath.parseFixedData, { channel: channel, rawData: unzipDatas[i], idx: idx })
} else {
dispatch(typePath.parseData, { channel: channel, rawData: unzipDatas[i], idx: idx })
}
}
}
}
encodedData.length = 0
unzipDatas.length = 0
}
}
delete payload.rawData
},
[typePath.parseData]: function ({ state, getters, commit }, payload) {
const { channel, rawData, idx } = payload
const meta = state.metaInfo
+2
View File
@@ -12,7 +12,9 @@ const types = {
},
raw: {
rawDataByID: 'rawDataByIDRaw',
rawSdDataByID: 'rawSdDataByIDRaw',
parseRawData: 'parseRawDataRaw',
parseRawSdData: 'parseRawSdDataRaw',
parseData: 'parseDataRaw',
parseFixedData: 'parseFixedDataRaw',
},