Compare commits

...

59 Commits

Author SHA1 Message Date
peterlu14 29f7d23d38 [debug] fix delete file working mode error 2023-01-04 15:21:40 +08:00
peterlu14 4d032858a3 [update] trigger add timer 2023-01-03 15:30:03 +08:00
peterlu14 417c4010a9 [update] fix advanced setting 2023-01-03 14:58:48 +08:00
peterlu14 6bf7edad0b [update] recover trigger ui 2023-01-03 14:42:54 +08:00
peterlu14 fafc6620d2 [debug] fix CC Mode csv header wrong information 2022-12-27 11:04:40 +08:00
peterlu14 78d236d9c0 [update] fix scheduler parameter default problem 2022-12-27 11:03:52 +08:00
ROY 6e42dc9333 [update] add debug channel in file 2022-12-07 14:23:19 +08:00
peterlu14 d4d6172645 Merge branch 'dev/scheduler_UI' into dev/test_ac_amp 2022-12-06 16:07:17 +08:00
peterlu14 8685768f42 [update] fix impendance scale & millidegree 2022-12-06 15:58:06 +08:00
peterlu14 8ca0e3fa28 Merge branch 'dev/scheduler_UI' into dev/test_ac_amp 2022-12-06 14:22:32 +08:00
peterlu14 7e61eb6e52 [update] fix phase degree scale error 2022-12-06 14:22:12 +08:00
peterlu14 d16d7b0cb5 Merge branch 'dev/scheduler_UI' into dev/test_ac_amp 2022-12-05 11:57:19 +08:00
peterlu14 c960a8228c [update] fix phase degree scale error 2022-12-05 11:56:39 +08:00
ROY d4423503d6 Merge remote-tracking branch 'origin/dev/scheduler_UI' into dev/test_ac_amp 2022-12-02 17:45:35 +08:00
peterlu14 6c8583e139 [update] fix CF mode name & name PEIS into EIS 2022-12-02 17:40:54 +08:00
peterlu14 f3817694cf [update] scheduler count start from 0 2022-12-02 17:30:13 +08:00
peterlu14 73eced5f52 [update] EIS_AVERAGE_NUM default 3 -> 0 2022-12-02 17:29:54 +08:00
peterlu14 5453928bc1 [update] remove project table cell for cycle 2022-12-02 17:29:29 +08:00
peterlu14 814cfa8b86 [update] fix delete project step 2022-12-02 17:28:56 +08:00
ROY c3f6349c6e [test] print notify_one & notify_two & notify_three 2022-12-01 14:15:12 +08:00
peterlu14 0dc8cc4344 [update] support cancel delete project click anywhere 2022-11-28 10:09:41 +08:00
peterlu14 9358ad7ffa [update] input auto focus & double check delete 2022-11-25 13:27:58 +08:00
peterlu14 95203486e2 [update] add showProjectManagerPanel button 2022-11-25 13:26:07 +08:00
peterlu14 164a658870 [update] fix project copy parameter show error 2022-11-24 18:01:01 +08:00
peterlu14 d4c71fd4f9 [update] update package v-tooltips 2022-11-24 11:21:42 +08:00
peterlu14 4b60975782 [update] show available parameters 2022-11-24 11:19:55 +08:00
peterlu14 d1b8683387 [update] add v-popover to parameter 2022-11-24 11:18:56 +08:00
peterlu14 fd4a677173 [update] fix draggable problem by combine device table row together 2022-11-24 10:13:09 +08:00
peterlu14 6f4d96fb17 [update] project manager filter & table header 2022-11-21 17:44:33 +08:00
peterlu14 3ad822bde1 [update] open cf mode 2022-11-21 16:48:29 +08:00
peterlu14 2b2dd50f41 [update] modify project menu device and table font & fix draggable bug 2022-11-21 16:45:44 +08:00
peterlu14 ca57978763 [update] device not pair coor change & draggable cannot drag while input & table header & cell font-size change 2022-11-21 15:40:35 +08:00
peterlu14 6c41341392 [update] fix getConfigTable & getDevice null error 2022-11-21 11:50:30 +08:00
peterlu14 4a5f07da18 [update] fix project parameter refs init problem 2022-11-21 11:49:12 +08:00
peterlu14 17492ccc98 [update] Vue use v-tooltip 2022-11-18 16:57:11 +08:00
peterlu14 e5603cd80e [update] minor modify to project typography 2022-11-18 15:49:07 +08:00
peterlu14 99898dc862 [update] thead sticky top 2022-11-18 15:44:45 +08:00
peterlu14 66bdf13955 [update] display menu in flexbox layout 2022-11-18 14:22:05 +08:00
peterlu14 89ffad6fbe [update] fix img src, project manager ui change 2022-11-18 13:25:59 +08:00
peterlu14 079ba2023d [update] img resource 2022-11-18 13:21:57 +08:00
peterlu14 9158697bdc [update] device text change place 2022-11-17 16:05:35 +08:00
peterlu14 0b20104133 [update] hover show parameter & add task bottom & table font alter 2022-11-17 16:05:16 +08:00
peterlu14 90f6090edb Merge branch 'release/v1.3.9/scheduler_device' into dev/scheduler_cf 2022-11-16 17:34:41 +08:00
peterlu14 c51c723e5f [update] chart table add new pair T_Impedance, T_Phase, T_Current 2022-11-16 15:41:32 +08:00
peterlu14 e38df250e2 [update] fix cf_mode channel set index error 2022-11-16 15:40:36 +08:00
peterlu14 06d52cabea Merge remote-tracking branch 'origin/dev/cf_mode' into dev/scheduler_cf 2022-11-16 13:47:21 +08:00
ROY 11305159a9 [update] new cf mode, but hide 2022-11-16 11:54:17 +08:00
peterlu14 aef2a48b78 [update] menu font & device font fix 2022-11-16 10:54:00 +08:00
peterlu14 036f4b664e [update] project cycle height 50 px & fix task add show 2022-11-15 17:27:12 +08:00
peterlu14 45653ba7cb [update] fix draggable 2022-11-15 16:59:01 +08:00
peterlu14 b45f731f1d [update] project only one device & auto add start 2022-11-15 14:32:23 +08:00
peterlu14 7946ada265 [update] default parameter bug fix 2022-11-15 13:14:34 +08:00
peterlu14 90c722a7c3 [update] project ui & cursor pointer 2022-11-15 13:14:02 +08:00
peterlu14 d6712139f3 [update] add working mode Idle 2022-11-15 11:53:48 +08:00
peterlu14 1d20f9c207 [update] action&condition into start stop & create start in select device & project table ui optimize & add taskAct method 2022-11-15 11:50:23 +08:00
peterlu14 3e3fe59bd2 [update] add start & stop icon and recover menu function 2022-11-15 11:42:57 +08:00
peterlu14 9495a17d2d [update] remove folder 2022-11-10 11:43:07 +08:00
peterlu14 120a7d45b1 [update] remove EIS device battery 2022-11-10 11:42:44 +08:00
peterlu14 d8bc49a100 [update] project menu UI update 2022-11-09 13:49:39 +08:00
64 changed files with 2229 additions and 308 deletions
+43 -9
View File
@@ -17021,13 +17021,29 @@
"integrity": "sha512-VPNCOTZK6WZy73lcWc+R7IW1uaBFEO3/Csrs5CzWVOdvE30V8Y1+BE/BtTlcEmeDGx0eqdE7bSCg55Jj37PMJg=="
},
"v-tooltip": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/v-tooltip/-/v-tooltip-2.0.3.tgz",
"integrity": "sha512-KZZY3s+dcijzZmV2qoDH4rYmjMZ9YKGBVoUznZKQX0e3c2GjpJm3Sldzz8HHH2Ud87JqhZPB4+4gyKZ6m98cKQ==",
"version": "2.1.3",
"resolved": "https://registry.npmjs.org/v-tooltip/-/v-tooltip-2.1.3.tgz",
"integrity": "sha512-xXngyxLQTOx/yUEy50thb8te7Qo4XU6h4LZB6cvEfVd9mnysUxLEoYwGWDdqR+l69liKsy3IPkdYff3J1gAJ5w==",
"requires": {
"lodash": "^4.17.15",
"popper.js": "^1.16.0",
"vue-resize": "^0.4.5"
"@babel/runtime": "^7.13.10",
"lodash": "^4.17.21",
"popper.js": "^1.16.1",
"vue-resize": "^1.0.1"
},
"dependencies": {
"@babel/runtime": {
"version": "7.20.1",
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.20.1.tgz",
"integrity": "sha512-mrzLkl6U9YLF8qpqI7TB82PESyEGjm/0Ly91jG575eVxMMlb8fYfOXFZIJ8XfLrJZQbm7dlKry2bJmXBUEkdFg==",
"requires": {
"regenerator-runtime": "^0.13.10"
}
},
"regenerator-runtime": {
"version": "0.13.11",
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz",
"integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg=="
}
}
},
"v8-compile-cache": {
@@ -17327,9 +17343,27 @@
}
},
"vue-resize": {
"version": "0.4.5",
"resolved": "https://registry.npmjs.org/vue-resize/-/vue-resize-0.4.5.tgz",
"integrity": "sha512-bhP7MlgJQ8TIkZJXAfDf78uJO+mEI3CaLABLjv0WNzr4CcGRGPIAItyWYnP6LsPA4Oq0WE+suidNs6dgpO4RHg=="
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/vue-resize/-/vue-resize-1.0.1.tgz",
"integrity": "sha512-z5M7lJs0QluJnaoMFTIeGx6dIkYxOwHThlZDeQnWZBizKblb99GSejPnK37ZbNE/rVwDcYcHY+Io+AxdpY952w==",
"requires": {
"@babel/runtime": "^7.13.10"
},
"dependencies": {
"@babel/runtime": {
"version": "7.20.1",
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.20.1.tgz",
"integrity": "sha512-mrzLkl6U9YLF8qpqI7TB82PESyEGjm/0Ly91jG575eVxMMlb8fYfOXFZIJ8XfLrJZQbm7dlKry2bJmXBUEkdFg==",
"requires": {
"regenerator-runtime": "^0.13.10"
}
},
"regenerator-runtime": {
"version": "0.13.11",
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz",
"integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg=="
}
}
},
"vue-router": {
"version": "3.3.4",
+1 -1
View File
@@ -46,7 +46,7 @@
"regenerator-runtime": "^0.13.3",
"register-service-worker": "^1.6.2",
"streamsaver": "^2.0.5",
"v-tooltip": "^2.0.2",
"v-tooltip": "^2.1.3",
"vee-validate": "^2.2.13",
"vue": "^2.6.10",
"vue-axios": "^3.2.0",
+4
View File
@@ -33,6 +33,8 @@ import localforage from 'localforage'
import SlideOut from '@hyjiacan/vue-slideout'
import '@hyjiacan/vue-slideout/lib/slideout.css'
import VTooltip from 'v-tooltip'
import '../metrics'
import '../registerServiceWorker'
@@ -108,6 +110,8 @@ Vue.use(SlideOut, {
// set default props here
})
Vue.use(VTooltip)
Vue.prototype.API = api
Vue.prototype.GLOBAL = global_
+1
View File
@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 384 512"><!--! Font Awesome Pro 6.2.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2022 Fonticons, Inc. --><path fill="#FFFFFF" d="M214.6 41.4c-12.5-12.5-32.8-12.5-45.3 0l-160 160c-12.5 12.5-12.5 32.8 0 45.3s32.8 12.5 45.3 0L160 141.2V448c0 17.7 14.3 32 32 32s32-14.3 32-32V141.2L329.4 246.6c12.5 12.5 32.8 12.5 45.3 0s12.5-32.8 0-45.3l-160-160z"/></svg>

After

Width:  |  Height:  |  Size: 477 B

+4
View File
@@ -0,0 +1,4 @@
<svg width="22" height="22" viewBox="0 0 22 22" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M18.3334 1.83337H9.16671C8.15562 1.83337 7.33337 2.65562 7.33337 3.66671V7.33337H3.66671C2.65562 7.33337 1.83337 8.15562 1.83337 9.16671V18.3334C1.83337 19.3445 2.65562 20.1667 3.66671 20.1667H12.8334C13.8445 20.1667 14.6667 19.3445 14.6667 18.3334V14.6667H18.3334C19.3445 14.6667 20.1667 13.8445 20.1667 12.8334V3.66671C20.1667 2.65562 19.3445 1.83337 18.3334 1.83337ZM3.66671 18.3334V9.16671H12.8334L12.8352 18.3334H3.66671ZM18.3334 12.8334H14.6667V9.16671C14.6667 8.15562 13.8445 7.33337 12.8334 7.33337H9.16671V3.66671H18.3334V12.8334Z" fill="#B8C3CC"/>
<path d="M5.5 11H11V12.8333H5.5V11ZM5.5 14.6667H11V16.5H5.5V14.6667Z" fill="#B8C3CC"/>
</svg>

After

Width:  |  Height:  |  Size: 757 B

+4
View File
@@ -0,0 +1,4 @@
<svg width="28" height="28" viewBox="0 0 28 28" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M23.3333 2.33325H11.6666C10.3798 2.33325 9.33331 3.37975 9.33331 4.66659V9.33325H4.66665C3.37981 9.33325 2.33331 10.3798 2.33331 11.6666V23.3333C2.33331 24.6201 3.37981 25.6666 4.66665 25.6666H16.3333C17.6201 25.6666 18.6666 24.6201 18.6666 23.3333V18.6666H23.3333C24.6201 18.6666 25.6666 17.6201 25.6666 16.3333V4.66659C25.6666 3.37975 24.6201 2.33325 23.3333 2.33325ZM4.66665 23.3333V11.6666H16.3333L16.3356 23.3333H4.66665ZM23.3333 16.3333H18.6666V11.6666C18.6666 10.3798 17.6201 9.33325 16.3333 9.33325H11.6666V4.66659H23.3333V16.3333Z" fill="white"/>
<path d="M7 14H14V16.3333H7V14ZM7 18.6667H14V21H7V18.6667Z" fill="white"/>
</svg>

After

Width:  |  Height:  |  Size: 743 B

+3
View File
@@ -0,0 +1,3 @@
<svg width="20" height="24" viewBox="0 0 20 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M11 14.3337H13V10.8337H16V8.50041H13V5.00041H11V8.50041H8V10.8337H11V14.3337ZM6 19.0004C5.45 19.0004 4.97933 18.7721 4.588 18.3156C4.196 17.8582 4 17.3087 4 16.6671V2.66707C4 2.02541 4.196 1.47591 4.588 1.01857C4.97933 0.562018 5.45 0.33374 6 0.33374H18C18.55 0.33374 19.021 0.562018 19.413 1.01857C19.8043 1.47591 20 2.02541 20 2.66707V16.6671C20 17.3087 19.8043 17.8582 19.413 18.3156C19.021 18.7721 18.55 19.0004 18 19.0004H6ZM6 16.6671H18V2.66707H6V16.6671ZM2 23.6671C1.45 23.6671 0.979333 23.4388 0.588 22.9822C0.196 22.5249 0 21.9754 0 21.3337V5.00041H2V21.3337H16V23.6671H2Z" fill="white"/>
</svg>

After

Width:  |  Height:  |  Size: 710 B

+3
View File
@@ -0,0 +1,3 @@
<svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M11.2132 12.6274L6.97054 8.38479L2.7279 12.6274L1.31369 11.2132L5.55633 6.97058L1.31369 2.72794L2.7279 1.31373L6.97054 5.55637L11.2132 1.31373L12.6274 2.72794L8.38475 6.97058L12.6274 11.2132L11.2132 12.6274Z" fill="#B8C3CC" stroke="#B8C3CC" stroke-linejoin="round"/>
</svg>

After

Width:  |  Height:  |  Size: 379 B

+3
View File
@@ -0,0 +1,3 @@
<svg width="19" height="21" viewBox="0 0 19 21" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M3.87524 20.625C3.25649 20.625 2.72699 20.4049 2.28674 19.9646C1.84574 19.5236 1.62524 18.9938 1.62524 18.375V3.75H0.500244V1.5H6.12524V0.375H12.8752V1.5H18.5002V3.75H17.3752V18.375C17.3752 18.9938 17.1551 19.5236 16.7149 19.9646C16.2739 20.4049 15.744 20.625 15.1252 20.625H3.87524ZM15.1252 3.75H3.87524V18.375H15.1252V3.75ZM6.12524 16.125H8.37524V6H6.12524V16.125ZM10.6252 16.125H12.8752V6H10.6252V16.125Z" fill="white"/>
</svg>

After

Width:  |  Height:  |  Size: 536 B

+3
View File
@@ -0,0 +1,3 @@
<svg width="14" height="14" viewBox="0 0 16 18" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M3 18C2.45 18 1.97933 17.8043 1.588 17.413C1.196 17.021 1 16.55 1 16V3H0V1H5V0H11V1H16V3H15V16C15 16.55 14.8043 17.021 14.413 17.413C14.021 17.8043 13.55 18 13 18H3ZM13 3H3V16H13V3ZM5 14H7V5H5V14ZM9 14H11V5H9V14Z" fill="#FF6C63"/>
</svg>

After

Width:  |  Height:  |  Size: 343 B

+8
View File
@@ -0,0 +1,8 @@
<svg width="36" height="38" viewBox="0 0 36 38" fill="none" xmlns="http://www.w3.org/2000/svg">
<mask id="mask0_3_20" style="mask-type:alpha" maskUnits="userSpaceOnUse" x="0" y="0" width="36" height="38">
<rect width="36" height="38" fill="#D9D9D9"/>
</mask>
<g mask="url(#mask0_3_20)">
<path d="M25.737 18.6561C25.5543 18.849 25.5543 19.151 25.737 19.3439L30.8113 24.7L29.4 26.1897L22.5888 19L29.4 11.8103L30.8113 13.3L25.737 18.6561ZM5 28V25.8333H23.5V28H5ZM5 20.0833V17.9167H19V20.0833H5ZM5 12.1667V10H23.5V12.1667H5Z" fill="#768B9B" stroke="#768B9B" stroke-linejoin="round"/>
</g>
</svg>

After

Width:  |  Height:  |  Size: 592 B

+3
View File
@@ -0,0 +1,3 @@
<svg width="26" height="30" viewBox="0 0 26 30" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M24.6304 15L1.9413 27.9904V2.00962L24.6304 15Z" fill="white" stroke="white" stroke-width="2.5" stroke-linejoin="round"/>
</svg>

After

Width:  |  Height:  |  Size: 233 B

+3
View File
@@ -0,0 +1,3 @@
<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M8.75012 18.7498V11.2498H1.25012V8.74976H8.75012V1.24976H11.2501V8.74976H18.7501V11.2498H11.2501V18.7498H8.75012Z" fill="white" stroke="white" stroke-linejoin="round"/>
</svg>

After

Width:  |  Height:  |  Size: 281 B

+3
View File
@@ -0,0 +1,3 @@
<svg width="22" height="22" viewBox="0 0 22 22" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M3.25 1.5C2.78587 1.5 2.34075 1.68437 2.01256 2.01256C1.68437 2.34075 1.5 2.78587 1.5 3.25V18.75C1.50001 19.1708 1.65165 19.5775 1.92714 19.8956C2.20263 20.2137 2.58351 20.4219 3 20.482V13.25C3 12.6533 3.23705 12.081 3.65901 11.659C4.08097 11.2371 4.65326 11 5.25 11H16.75C17.3467 11 17.919 11.2371 18.341 11.659C18.7629 12.081 19 12.6533 19 13.25V20.482C19.4165 20.4219 19.7974 20.2137 20.0729 19.8956C20.3483 19.5775 20.5 19.1708 20.5 18.75V5.786C20.5 5.321 20.316 4.876 19.987 4.548L17.452 2.013C17.2895 1.85035 17.0965 1.72133 16.884 1.63331C16.6716 1.54528 16.4439 1.49998 16.214 1.5H16V5.75C16 6.04547 15.9418 6.33805 15.8287 6.61104C15.7157 6.88402 15.5499 7.13206 15.341 7.34099C15.1321 7.54992 14.884 7.71566 14.611 7.82873C14.3381 7.9418 14.0455 8 13.75 8H7.25C6.65326 8 6.08097 7.76295 5.65901 7.34099C5.23705 6.91903 5 6.34674 5 5.75V1.5H3.25ZM6.5 1.5V5.75C6.5 6.164 6.836 6.5 7.25 6.5H13.75C13.9489 6.5 14.1397 6.42098 14.2803 6.28033C14.421 6.13968 14.5 5.94891 14.5 5.75V1.5H6.5ZM17.5 20.5V13.25C17.5 13.0511 17.421 12.8603 17.2803 12.7197C17.1397 12.579 16.9489 12.5 16.75 12.5H5.25C5.05109 12.5 4.86032 12.579 4.71967 12.7197C4.57902 12.8603 4.5 13.0511 4.5 13.25V20.5H17.5ZM0 3.25C0 2.38805 0.34241 1.5614 0.951903 0.951903C1.5614 0.34241 2.38805 0 3.25 0H16.215C17.0769 5.14719e-05 17.9035 0.342495 18.513 0.952L21.048 3.487C21.658 4.097 22 4.924 22 5.786V18.75C22 19.612 21.6576 20.4386 21.0481 21.0481C20.4386 21.6576 19.612 22 18.75 22H3.25C2.38805 22 1.5614 21.6576 0.951903 21.0481C0.34241 20.4386 0 19.612 0 18.75V3.25Z" fill="white"/>
</svg>

After

Width:  |  Height:  |  Size: 1.6 KiB

+3
View File
@@ -0,0 +1,3 @@
<svg width="25" height="22" viewBox="0 0 25 22" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M15.7246 13.3226L23.2481 20.2889L22.872 20.6372L15.2354 13.5662L14.627 13.0029L13.9608 13.4964C13.3939 13.9164 12.7313 14.257 11.9636 14.5122C11.2143 14.7612 10.4084 14.8889 9.54002 14.8889C7.37746 14.8889 5.59555 14.2043 4.13159 12.8488C2.66996 11.4954 1.96002 9.88006 1.96002 7.94444C1.96002 6.00883 2.66996 4.39346 4.13159 3.04009C5.59555 1.68457 7.37746 1 9.54002 1C11.7026 1 13.485 1.68458 14.95 3.04027C16.4105 4.39351 17.12 6.00882 17.12 7.94444C17.12 8.7236 16.9867 9.44582 16.7256 10.1191C16.4567 10.8127 16.0964 11.4153 15.6473 11.9351L15.0157 12.6662L15.7246 13.3226ZM14.4273 12.5749L14.4279 12.5744C15.7797 11.3218 16.48 9.76006 16.48 7.94444C16.48 6.12883 15.7797 4.56711 14.4279 3.3145L14.4273 3.31398C13.0775 2.06509 11.4285 1.44444 9.54002 1.44444C7.65159 1.44444 6.00256 2.06509 4.65273 3.31398L4.65217 3.3145C3.30039 4.56711 2.60002 6.12883 2.60002 7.94444C2.60002 9.76006 3.30039 11.3218 4.65217 12.5744L4.65273 12.5749C6.00256 13.8238 7.65158 14.4444 9.54002 14.4444C11.4285 14.4444 13.0775 13.8238 14.4273 12.5749Z" fill="#2C4053" stroke="#B8C3CC" stroke-width="2"/>
</svg>

After

Width:  |  Height:  |  Size: 1.2 KiB

+3
View File
@@ -0,0 +1,3 @@
<svg width="25" height="25" viewBox="0 0 25 25" fill="none" xmlns="http://www.w3.org/2000/svg">
<rect rx="5" ry="5" width="25" height="25" style="fill: white;"/>
</svg>

After

Width:  |  Height:  |  Size: 172 B

@@ -61,14 +61,14 @@ export const navigationRoutes = {
iconClass: 'vuestic-iconset vuestic-iconset-settings',
},
},
// {
// name: 'project',
// displayName: 'Scheduler',
// meta: {
// iconClass: 'vuestic-iconset vuestic-iconset-tables',
// // iconClass: 'vuestic-iconset vuestic-iconset-browse-gallery',
// },
// },
{
name: 'project',
displayName: 'Scheduler',
meta: {
iconClass: 'vuestic-iconset vuestic-iconset-tables',
// iconClass: 'vuestic-iconset vuestic-iconset-browse-gallery',
},
},
// {
// name: 'forms',
// displayName: 'menu.forms',
+18 -12
View File
@@ -180,7 +180,7 @@
{{ props.rowData.name }}
</template>
<template slot="parameter_set" slot-scope="props">
{{ getWorkingMode(props.rowData) }}
{{ getWorkingMode(props.rowData.device, props.rowData.parameter_set) }}
</template>
<template slot="created_at" slot-scope="props">
{{transDate(props.rowData.created_at)}}
@@ -591,6 +591,7 @@ export default {
},
fillDeleteInfo: function (info) {
if (info.type === 'folder') {
this.deleteInfo.metaID = undefined
this.deleteInfo.folderID = info.id
this.deleteInfo.name = info.name
} else {
@@ -628,10 +629,13 @@ export default {
deleteFileDone: async function () {
const tmpCurrentPage = this.$refs.datatable_ref.currentPage
// rebuild table
this.fileLists = this.fileLists.filter(file => file.name !== this.deleteInfo.name)
await this.refreshPage()
this.$refs.datatable_ref.currentPage = tmpCurrentPage
this.$refs.datatable_ref.inputPage(tmpCurrentPage)
this.fileLists = this.fileLists.filter(file => {
return file.id !== this.deleteInfo.metaID
})
// await this.refreshPage()
await this.$refs.datatable_ref.inputPage(1)
await this.$refs.datatable_ref.inputPage(tmpCurrentPage)
// this.$refs.datatable_ref.inputPage(tmpCurrentPage)
// this.loadingFiles = false
this.showToast(`deleted ${this.deleteInfo.name}`, {
position: 'bottom-right',
@@ -675,7 +679,7 @@ export default {
// call getfolder api and update
const folders = await api.collection.getByParent('folder', this.currentInfo.id)
const files = await api.meta.getAttrByParent('folder', this.currentInfo.id, 'id-path-name-parent-description-size-time_duration-uuid-device-channels-created_at')
const files = await api.meta.getAttrByParent('folder', this.currentInfo.id, 'id-path-name-parent-description-size-time_duration-uuid-device-channels-parameter_set-created_at')
file.updateFileList(folders)
file.updateFileList(files)
@@ -702,8 +706,7 @@ export default {
}
const tmpCurrentPage = this.$refs.datatable_ref.currentPage
await this.refreshPage()
this.$refs.datatable_ref.currentPage = tmpCurrentPage
this.$refs.datatable_ref.inputPage(tmpCurrentPage)
await this.$refs.datatable_ref.inputPage(tmpCurrentPage)
},
downloadCsv: async function (meta) {
const href = location.href.split('/')[2]
@@ -773,11 +776,14 @@ export default {
})
}
},
getWorkingMode: function (rowData) {
getWorkingMode: function (device, parameterSet) {
try {
if (rowData.type === 'folder') return ''
return configTable.getModeConfig(rowData.device.library_name, rowData.parameter_set.MODE).name
} catch {
if (parameterSet) {
return configTable.getModeConfig(device.library_name, parameterSet.MODE).name
}
return ''
} catch (e) {
console.log('e', e)
return ''
}
},
+5 -2
View File
@@ -54,8 +54,8 @@ export default {
return {
controllerList: [],
cardStyle: {
small: 'flex xl4 md4 sm12 xs12',
medium: 'flex xl8 md8 sm12 xs12',
small: 'flex xl3 md3 sm12 xs12',
medium: 'flex xl9 md9 sm12 xs12',
large: 'flex xl12 md12 sm12 xs12',
},
}
@@ -213,6 +213,9 @@ export default {
header: 'get_running_project/0',
}))
},
destroyed () {
this.projectManagerPanel.show = true
},
}
</script>
@@ -4,34 +4,25 @@
<template slot="header">
<div class="row">
<div class="flex d-flex xs5 sm5 lg5 xl5">
<va-icon name="fa fa-bluetooth-b" color="primary"/>
<h5 class="mb-0">PROJECTS</h5>
<p class="project-view-header">PROJECTS</p>
</div>
<div class="flex xs7 sm7 lg7 xl7" style="text-align: right;">
<!-- <va-button v-if="projectConfigList.length !== 0" class="ma-0 circle-button" @click="closePanel"> -->
<va-icon v-if="projectConfigList.length !== 0" @click.native="closePanel"
name="fa fa-times"
color="black"
/>
<!-- </va-button> -->
<img class="img-vertical-center" src="@/assets/img/project/menu_close.svg" @click="closePanel">
</div>
</div>
<!-- <div class="flex d-flex xl5 lg5 sm5 xs5 ma-0">
<va-icon name="fa fa-bluetooth-b mr-3" color="primary"/>
<h5 class="mb-0">PROJECTS</h5>
</div>
<div class="flex d-flex xl7 lg7 sm7 xs7 ma-0" style="text-align: right;">
<va-button v-if="projectConfigList.length !== 0" class="pa-0 ma-0 circle-button" small color="dark" @click="closePanel">
<va-icon
name="fa fa-times"
color="white"
/>
</va-button>
</div> -->
</template>
<div class="flex d-flex m12 xs12 md12 xl12">
<div>
<va-button @click="createProject({ api: API })" icon="fa fa-plus"></va-button>
<div class="input-icons input-style flex sm12 xs12 md7 xl7 pa-0">
<img class="icon" src="@/assets/img/project/search.svg">
<input class="input-field" type="text" v-model="filterText">
</div>
<div class="ml-1 pa-0" style="text-align: right;">
<button class="project-copy-btn" @click="copyProject({ project: getSelectProject, index: index, api: API })">
<img class="img-vertical-center" src="@/assets/img/project/copy-alt.svg">
</button>
<button class="project-copy-btn ml-1" @click="createProject({ api: API })">
<img class="img-vertical-center" src="@/assets/img/project/plus.svg">
</button>
</div>
</div>
<div>
@@ -42,15 +33,15 @@
</va-tabs>
</div>
<div class="mt-1">
<project-manager-list v-if='tabValue == 0'/>
<running-project-manager-list v-if='tabValue == 1'/>
<project-manager-list v-if='tabValue == 0' :filterText="filterText"/>
<running-project-manager-list v-if='tabValue == 1' :filterText="filterText"/>
</div>
</va-card>
</div>
</template>
<script>
import { mapActions } from 'vuex'
import { mapActions, mapGetters } from 'vuex'
import { mapFields } from 'vuex-map-fields'
import types from '@/store/modules/project/types'
import ProjectManagerList from '@/components/project/manager/ProjectManagerList'
@@ -63,6 +54,10 @@ export default {
RunningProjectManagerList,
},
computed: {
...mapGetters('project', [
'getSelectProject',
]),
...mapFields('project', [
'lockMode',
'projectList',
@@ -75,6 +70,7 @@ export default {
return {
tabValue: 0,
tabTitles: ['CONFIG', 'RUNNING'],
filterText: '',
}
},
methods: {
@@ -86,6 +82,9 @@ export default {
...mapActions('project',
[
types.project.create,
types.project.copy,
types.project.select,
types.project.delete,
],
),
closePanel: function () {
@@ -100,4 +99,39 @@ export default {
<style>
.input-icons img {
position: absolute;
}
.input-icons {
width: 67%;
/* margin-bottom: 10px; */
}
.icon {
color: grey;
min-width: 40px;
padding: 10px;
}
.input-field {
width: 100%;
padding: 9px;
text-align: right;
background: #f1f1f1;
border: none;
border-radius: 6px 6px 0 0;
border-bottom: 1.5px solid #758b9a;
}
.project-copy-btn {
width: 50px;
height: 38px;
background: #858dd6;
border: none;
border-radius: 5px;
cursor: pointer;
}
</style>
@@ -1,12 +1,13 @@
<template>
<div class="row">
<div class="flex xs12 lg12 md12">
<va-item class="mb-1" v-for="(project, index) in projectConfigList" :key="index" @click="selectProject({index: index})" clickable>
<va-item :class="(selectProjectIndex === index) ? 'project-list-text project-list-focus': 'project-list-text project-list'" v-for="(project, index) in configList" :key="index" @click="select(index)">
<va-item-section @dblclick.native="switchEdit('name', index)">
<div v-if="projectTable.name == index">
<va-input
:ref="'input_ref'"
v-model="project.name"
style="width: 100px;"
style="min-width: 100px;"
@blur="switchEdit('name', -1, project)"
@keyup.enter="switchEdit('name', -1, project)"
/>
@@ -14,13 +15,11 @@
<div v-else>
{{ project.name }}
</div>
<!-- <va-item-label>
{{ project.name }}
</va-item-label> -->
</va-item-section>
<va-item-section side>
<va-icon class="fa fa-copy mr-2" color="bloack" @click.native.stop="copyProject({ project: project, index: index, api: API })"></va-icon>
<va-icon class="fa fa-close" color="danger" @click.native.stop="deleteProject({ project: project, index: index, api: API })"></va-icon>
<img class="mr-2" src="@/assets/img/project/copy-alt-grey.svg" @click="copyProject({ project: project, index: index, api: API })">
<img v-if="selectDeleteIndex !== index" class="mr-2" src="@/assets/img/project/cross.svg" @click.stop="confirmDelete($event, index)">
<img v-else class="mr-2" src="@/assets/img/project/delete14_14.svg" @click.stop="_deleteProject(project, index)">
</va-item-section>
</va-item>
</div>
@@ -33,9 +32,21 @@ import types from '@/store/modules/project/types'
export default {
name: 'project-manager-list',
props: {
filterText: {
type: String,
default: '',
},
},
computed: {
configList () {
if (this.filterText === '') return this.projectConfigList
return this.projectConfigList.filter(ele => ele.name.includes(this.filterText))
},
...mapFields('project', [
'projectConfigList',
'projectSelectIndex',
]),
},
data () {
@@ -43,15 +54,47 @@ export default {
projectTable: {
name: -1,
},
selectProjectIndex: -1,
selectDeleteIndex: -1,
}
},
methods: {
reset: function () {
this.selectProjectIndex = -1
this.selectDeleteIndex = -1
},
resetDelete: function (e) {
if (e.target.classList.contains('clicked')) {
e.target.classList.remove('clicked')
return
}
this.selectDeleteIndex = -1
},
confirmDelete: function (e, index) {
e.target.classList.add('clicked')
this.selectProjectIndex = index
this.selectDeleteIndex = index
window.addEventListener('mousedown', this.resetDelete, { once: true })
},
_deleteProject: async function (project, index) {
this.reset()
await this.deleteProject({ project: project, index: index, api: this.API })
},
select: function (index) {
this.selectProjectIndex = index
this.selectDeleteIndex = -1
this.selectProject({ index: index })
},
switchEdit: function (tag, index, project) {
if (this.projectTable[tag] >= 0) {
this.projectTable[tag] = -1
project && this.API.project.update(project.id, { name: project.name })
} else {
this.projectTable[tag] = index
this.$nextTick(() => {
this.$refs.input_ref[0].$refs.input.focus()
})
}
},
...mapActions('project',
@@ -66,3 +109,32 @@ export default {
},
}
</script>
<style lang="scss">
.project-list-text {
// font
font-family: 'Inter-Regular';
font-style: italic;
font-weight: 400;
font-size: 16px;
line-height: 24px;
color: #768b9b;
}
.project-list-focus {
/* Rectangle 5 */
background: #ebedff;
border: 1px solid #dbdcf0;
box-shadow: 1px 1px 2px rgba(0, 0, 0, 0.25);
border-radius: 5px;
}
.project-list-focus:hover {
opacity: 0.8;
background: #ebedff;
}
.project-list:hover {
opacity: 0.8;
}
</style>
@@ -1,8 +1,9 @@
<template>
<div>
<project-task-config-device v-if="taskViewPanel.type===1"></project-task-config-device>
<project-task-config-condition v-if="taskViewPanel.type===3"></project-task-config-condition>
<project-task-config-parameter v-if="taskViewPanel.type===4"></project-task-config-parameter>
<project-task-config-condition v-if="taskViewPanel.type===2" :actionType="'start'"></project-task-config-condition>
<project-task-config-condition v-if="taskViewPanel.type===3" :actionType="'stop'"></project-task-config-condition>
<project-task-config-parameter v-show="taskViewPanel.type===4"></project-task-config-parameter>
</div>
</template>
<script>
@@ -1,37 +1,18 @@
<template>
<div class="flex sm12 xl12 md12 xs12">
<!-- <span>Device</span>
<div class="row flex sm12 xl12 md12 xs12" v-if="Object.keys(registeredDevice).length > 0">
<div class="flex sm12 xl6 md6 xs12" v-for="(device, key) in registeredDevice" :key="key">
<va-button @click="selectDevice(key)" small>{{ getDeviceShowNameProject(key) }}</va-button>
<!-- <span>Condition</span> -->
<div v-for="(condition, key) in conditionObj" :key="key">
<!-- <div v-if="key === 'cycle' || key === 'cycle_next'" class="flex d-flex align--center"> -->
<div class="flex d-flex align--center">
<va-checkbox v-model="condition.select"></va-checkbox>
<span class="mr-1">{{ condition.prefix }}</span>
<input style="width: 100px;" class="mr-1" :type="condition.type" v-model="condition.value"/>
<span>{{ condition.suffix }}</span>
</div>
</div>
<div align="center" v-else>
No registered device found.
</div> -->
<div v-if="settingStep >= 1">
<!-- <span>Action</span> -->
<div class="flex d-flex">
<div v-for="action in actionTemplate" :key="action">
<va-button color="info" @click="selectAction(action)" small>{{ action }}</va-button>
</div>
</div>
</div>
<div v-if="settingStep >= 2">
<!-- <span>Condition</span> -->
<div v-for="(condition, key) in conditionObj" :key="key">
<!-- <div v-if="key === 'cycle' || key === 'cycle_next'" class="flex d-flex align--center"> -->
<div class="flex d-flex align--center">
<va-checkbox v-model="condition.select"></va-checkbox>
<span class="mr-1">{{ condition.prefix }}</span>
<input style="width: 100px;" class="mr-1" :type="condition.type" v-model="condition.value"/>
<span>{{ condition.suffix }}</span>
</div>
</div>
<div align="right">
<va-button color="warning" @click="reset" small>Reset</va-button>
<va-button color="success" @click="save" small>Save</va-button>
</div>
<div align="right">
<va-button color="warning" @click="reset" small>Reset</va-button>
<va-button color="success" @click="save" small>Save</va-button>
</div>
</div>
</template>
@@ -46,9 +27,15 @@ export default {
name: 'project-task-config-condition',
components: {
},
props: {
actionType: {
type: String,
required: true,
},
},
computed: {
conditionObj () {
return this.conditionTemplate[this.actionSelect]
return this.conditionTemplate[this.actionType]
},
deviceSelectName () {
@@ -128,7 +115,7 @@ export default {
},
save: function () {
const actionUUID = this.GLOBAL.getUUID()
const newAction = this.createAction(actionUUID, this.actionSelect, this.deviceSelect)
const newAction = this.createAction(actionUUID, this.actionType, this.deviceSelect)
// if device not add in task then add in
if (!this.getSelectTask.device.includes(this.deviceSelect)) {
@@ -137,18 +124,6 @@ export default {
for (const key in this.conditionObj) {
if (this.conditionObj[key].select) {
// create fake condition if duplicate type & target
if (Object.values(this.getSelectTask.condition).findIndex(ele => ele.type === 'previous_task_done' && ele.target === this.deviceSelect) === -1) {
// create fake start previous done
const fakeStartActionUUID = this.GLOBAL.getUUID()
const fakeAction = this.createAction(fakeStartActionUUID, 'start', this.deviceSelect)
const fakeConditionUUID = this.GLOBAL.getUUID()
const fakeCondition = this.createCondition(fakeConditionUUID, 'previous_task_done', 'equal', '')
this.setConditionTask({ condition: fakeCondition })
fakeAction[fakeStartActionUUID].condition.push(fakeConditionUUID)
this.setActionTask({ action: fakeAction })
}
const conditionUUID = this.GLOBAL.getUUID()
const newCondition = this.createCondition(conditionUUID, key, 'equal', this.conditionObj[key].value)
@@ -104,10 +104,23 @@ export default {
appendToTask: function (key) {
// if select single task
this.getSelectTask.device.push(key)
// create start action-condtion-pair when choose device
this.createActionConditionPairTask({
device: key,
task: this.getSelectTask,
action: 'start',
condition: {
type: 'previous_task_done',
comparsion: 'equal',
value: '',
},
})
},
removeFromTask: function (key) {
// if select single task
this.getSelectTask.device = this.getSelectTask.device.filter(item => item !== key)
// this.getSelectTask.device = this.getSelectTask.device.filter(item => item !== key)
// remove device & relation action, condition, parameter
this.deleteDeviceTask({ deviceKey: key, onlySelectTask: true })
},
closePanel: function () {
this.taskViewPanel.show = !(this.taskViewPanel.show)
@@ -116,6 +129,8 @@ export default {
...mapActions('project',
[
types.project.createDevice,
types.task.deleteDevice,
types.task.createActionConditionPair,
],
),
},
@@ -1,22 +1,12 @@
<template>
<div class="flex sm12 xl12 md12 xs12">
<!-- <div class="task-config__header-separator mb-1">
<div class="task-config__header-text">
<span >Parameter Set</span>
<va-button class="circle-button" small color="dark" @click="closePanel">
<va-icon
name="fa fa-times"
color="white"
/>
</va-button>
</div>
</div> -->
<div>
<device-parameter-recording
:ref="'device_parameter_ref'"
:parameter="parameter"
:library="device.library"
:library="library"
:place="'scheduler'"
:resetParameterModeChange="true"
@setParameter="setParameter"
@setParameterWithDebounce="setParameterWithDebounce"
/>
@@ -38,6 +28,11 @@ export default {
DeviceParameterRecording,
},
computed: {
library () {
if (this.device === null || this.device === undefined) return null
return this.device.library
},
...mapGetters('project', [
types.task.getSelect,
types.task.getParameterSet,
@@ -48,6 +43,7 @@ export default {
'taskViewPanel',
'taskSelectKey',
'deviceSelectKey',
'projectSelectIndex',
]),
},
data () {
@@ -90,6 +86,7 @@ export default {
resetParameter: function (mode) {
// get Device
this.device = this.getDeviceProject(this.deviceSelectKey)
if (this.device === undefined) return
// get Config
if (typeof this.device.library === 'string') { // string
this.config = configTable.getConfig(this.device.library)
@@ -112,7 +109,8 @@ export default {
this.$refs.device_parameter_ref.workingModeSelectChange(modeOption)
this.parameter = Object.assign(this.parameter, Object.values(parameterSet)[0])
} else {
this.setParameter('MODE', 0)
const defaultMode = this.config.MODE_OPTIONS.find(ele => ele.description === 'Idle')
this.setParameter('MODE', defaultMode.id)
}
},
...mapActions('project',
@@ -122,13 +120,12 @@ export default {
),
},
mounted () {
// init parameter
this.resetParameter()
},
watch: {
// refresh parameter when click different task's parameter
taskSelectKey: {
handler: function () {
this.device = null
this.parameter = {}
this.parameterUUID = ''
this.resetParameter()
@@ -136,6 +133,15 @@ export default {
},
deviceSelectKey: {
handler: function () {
this.device = null
this.parameter = {}
this.parameterUUID = ''
this.resetParameter()
},
},
projectSelectIndex: {
handler: function () {
this.device = null
this.parameter = {}
this.parameterUUID = ''
this.resetParameter()
+99 -12
View File
@@ -1,23 +1,30 @@
<template>
<div>
<!-- <pre>{{ getSelectProject }} </pre> -->
<va-card style="height: 88vh; overflow: auto; display: block;">
<va-card style="height: 88vh; overflow: auto; display: block;" @mousemove.native="mousemove">
<div id="project-view-show-btn" v-if="!projectManagerPanel.show" @click="showProjectManagerPanel">
<img id="project-view-show-btn-img" src="@/assets/img/project/arrow-right.svg">
</div>
<template slot="header">
<va-icon name="fa fa-bluetooth-b mr-3" color="primary"/>
<h5 class="mt-0 mb-0"> {{ getSelectProject ? getSelectProject.name : '' }}</h5>
<p class="project-view-header">{{ getSelectProject ? getSelectProject.name : '' }}</p>
</template>
<div v-if="getSelectProject === undefined">
<span>please select project</span>
</div>
<div v-else>
<project-menu @detect="detect"/>
<project-menu @detect="detect" @save_project="save"/>
<project-table/>
<div align="right" v-if="lockMode === false">
<va-button @click="save">Save</va-button>
<va-button @click="start">Start</va-button>
<button class="project-start-btn" @click="start">
<div>
<img src='@/assets/img/project/play.svg' alt="start">
</div>
</button>
</div>
<div align="right" v-if="lockMode === true">
<va-button @click="stop">Stop</va-button>
<button class="project-stop-btn" @click="stop">
<img src='@/assets/img/project/stop.svg' alt="stop">
</button>
</div>
</div>
</va-card>
@@ -46,6 +53,7 @@ export default {
'deviceConnectList',
'projectSelectIndex',
'projectLibrary',
'projectManagerPanel',
]),
},
data () {
@@ -53,14 +61,45 @@ export default {
}
},
methods: {
showProjectManagerPanel: function () {
this.projectManagerPanel.show = true
},
mousemove: function (e) {
// define constant
const DETECT_X_MAX = 50
const DETECT_X_MIN = 0
// get element
const element = document.getElementById('project-view-show-btn')
if (!element) return
let x = e.offsetX
// console.log('e', e, e.srcElement.className, e.srcElement.id)
// if mouse on project
if (e.srcElement.id === 'project-view-show-btn' || e.srcElement.id === 'project-view-show-btn-img') {
element.style.opacity = 0.7
element.style.transform = 'rotate(90deg) translate(40vh, 25px)'
return
}
if (e.srcElement.className !== 'va-card__body' && e.srcElement.className !== 'va-card') {
element.style.transform = 'rotate(90deg) translate(40vh, 75px)'
return
}
if (x >= DETECT_X_MAX) x = DETECT_X_MAX
if (x < DETECT_X_MIN) x = DETECT_X_MIN
const offsetPercentage = Math.round(((DETECT_X_MAX - x) / DETECT_X_MAX) * 4) / 4
const newOffset = 75 - offsetPercentage * 50
element.style.opacity = offsetPercentage * 0.7
element.style.transform = 'rotate(90deg) translate(40vh, ' + String(newOffset) + 'px)'
},
start: function () {
this.$emit('start_project', this.getSelectProject)
},
stop: function () {
this.$emit('stop_project', this.getSelectProject)
},
save: function () {
this.$emit('save_project', this.getSelectProject)
save: function (project) {
this.$emit('save_project', project)
},
detect: function (device) {
this.$emit('detect', device)
@@ -75,9 +114,57 @@ export default {
watch: {
},
async mounted () {
// console.log('mounted')
// console.log(this.deviceConnectList)
// console.log(this.deviceConnectList.length)
},
}
</script>
<style lang="scss">
#project-view-show-btn {
position: absolute;
top: 0;
left: 0;
width: 100px;
height: 50px;
border-radius: 100px 100px 0 0;
background-color: #495057;
transform: rotate(90deg) translate(40vh, 75px);
transition: transform 0.1s linear;
}
#project-view-show-btn-img {
position: relative;
top: 5px;
left: 30px;
width: 40px;
height: 40px;
}
.project-view-header {
margin: 0.3rem 0 2rem 0;
font-family: 'Inter-ExtraBold';
// font-style: normal;
// font-weight: 800;
font-size: 24px;
line-height: 29px;
/* identical to box height */
color: #2c4053;
}
.project-start-btn {
width: 120px;
height: 50px;
background: #87d9d4;
border-radius: 8px;
border: white;
cursor: pointer;
}
.project-stop-btn {
width: 120px;
height: 50px;
background: #ff6c63;
border-radius: 8px;
border: white;
cursor: pointer;
}
</style>
@@ -1,11 +1,28 @@
<template>
<div>
<div class="row">
<div class="flex d-flex">
<switch-project/>
<add-task/>
<!-- <add-device @showDeviceModal="showDeviceModal"/> -->
<va-button @click="showCycleModal" small>+ Cycle</va-button>
<div class="flex d-flex sm12 xs12 md6 xl4 px-0">
<add-task/>
<div>
<button class="add-cycle-btn" @click="showCycleModal">
<div class="add-cycle-text">
<p>Add Cycle</p>
</div>
</button>
</div>
<div>
<button class="copy-project-btn" @click="copyTask({ project: getSelectProject, index: projectTableSelectIndex})">
<img class="img-vertical-center" src="@/assets/img/project/copy.svg">
</button>
</div>
<div>
<button class="copy-project-btn" @click="saveProject">
<img class="img-vertical-center" src="@/assets/img/project/save.svg">
</button>
</div>
<div>
<button class="copy-project-btn" @click="deleteTask({ project: getSelectProject, index: projectTableSelectIndex})">
<img class="img-vertical-center" src="@/assets/img/project/delete.svg">
</button>
</div>
</div>
<project-device @showDeviceModal="showDeviceModal"></project-device>
@@ -15,26 +32,37 @@
</template>
<script>
import SwitchProject from '@/components/project/view/menu/components/SwitchProject'
// import SwitchProject from '@/components/project/view/menu/components/SwitchProject'
import AddTask from '@/components/project/view/menu/components/AddTask'
// import AddDevice from '@/components/project/view/menu/components/AddDevice'
import ProjectDevice from '@/components/project/view/menu/components/ProjectDevice'
import NewDeviceModal from '@/components/project/view/menu/components/NewDeviceModal'
import CycleModal from '@/components/project/view/menu/components/CycleModal'
import { mapActions } from 'vuex'
import { mapFields } from 'vuex-map-fields'
import { mapActions, mapGetters } from 'vuex'
import types from '@/store/modules/project/types'
export default {
name: 'project-menu',
components: {
SwitchProject,
AddTask,
// AddDevice,
ProjectDevice,
NewDeviceModal,
CycleModal,
},
computed: {
...mapGetters('project', [
types.project.getSelect,
]),
...mapFields('project', [
'taskViewPanel',
'taskSelectKey',
'deviceSelectKey',
'lockMode',
'projectTableSelectIndex',
]),
},
data () {
return {
}
@@ -54,12 +82,58 @@ export default {
this.$refs.cycle_modal_ref.show()
this.$refs.cycle_modal_ref.reset()
},
saveProject: function () {
this.$emit('save_project', this.getSelectProject)
},
...mapActions('project',
[
types.task.copy,
types.task.delete,
types.task.rearrange,
types.task.createCycle,
],
),
},
}
</script>
<style lang="scss">
.add-cycle-btn {
margin-left: 0.5rem;
width: 120px;
height: 38px;
left: 0;
top: 0;
background: #87d9d4;
border: none;
border-radius: 8px;
cursor: pointer;
}
.add-cycle-text {
width: 110px;
height: 24px;
font-family: 'Inter-Bold';
font-style: normal;
font-weight: 700;
font-size: 16px;
line-height: 24px;
text-align: center;
color: #ffffff;
margin: 0 auto;
}
.copy-project-btn {
margin-left: 0.5rem;
width: 50px;
height: 38px;
background: #87d9d4;
border: none;
border-radius: 8px;
cursor: pointer;
}
.img-vertical-center {
vertical-align: middle;
}
</style>
@@ -1,6 +1,10 @@
<template>
<div>
<va-button @click="createTask" small>+ TASK</va-button>
<button class="add-task-btn" @click="createTask">
<div class="add-task-text">
<p>Add Task</p>
</div>
</button>
</div>
</template>
<script>
@@ -30,3 +34,28 @@ export default {
},
}
</script>
<style lang="scss">
.add-task-btn {
width: 120px;
height: 38px;
left: 0;
top: 0;
background: #87d9d4;
border: none;
border-radius: 8px;
cursor: pointer;
}
.add-task-text {
width: 100px;
height: 24px;
font-family: 'Inter-Bold';
font-style: normal;
font-weight: 700;
font-size: 16px;
line-height: 24px;
text-align: center;
color: #ffffff;
margin: 0 auto;
}
</style>
@@ -1,21 +1,43 @@
<template>
<div class="row">
<div class="flex d-flex" v-if="showLibrary === true">
<va-button small @click="clickShowDevice('EDC')">EDC</va-button>
<va-button small @click="clickShowDevice('EIS')">EIS</va-button>
<va-button small @click="cancelSelectDevice()">X</va-button>
<div class="flex d-flex sm12 xs12 md12 xl12 pa-0" style="align-items: center; margin-left: 0.6rem; margin-top: -12px;">
<!-- header -->
<div class="flex sm3 xs3 md3 xl1 px-0 project-device-header-text">
<p>Device</p>
</div>
<!-- create persudo devcie -->
<div class="flex d-flex" v-if="showLibrary === true">
<div class="flex d-flex pa-0 sm12 xs12 md6 xl3">
<div>
<button class="pair-button" @click="clickShowDevice('EDC')">
<span class="pair-button-text">EDC</span>
</button>
</div>
<div class="ml-2">
<button class="pair-button" @click="clickShowDevice('EIS')">
<span class="pair-button-text">EIS</span>
</button>
</div>
<div class="ml-2">
<button class="pair-button" @click="cancelSelectDevice()">
<span class="pair-button-text">X</span>
</button>
</div>
</div>
</div>
<!-- device list -->
<div class="flex d-flex" v-if="showDevice === false && showLibrary === false">
<draggable class="flex row" :list="deviceListInOrder" :move="handleMove" @end="handleDragEnd">
<draggable class="d-flex" :list="deviceListInOrder" :move="handleMove" @end="handleDragEnd">
<!-- devices -->
<div class="mr-2" v-for="(device, index) in deviceListInOrder" :key="index">
<button :class="device[1].pairStatus === 1 ? 'pair-button mr-2' : 'not-pair-button mr-2'" @click="showDeviceModal(device[0], device[1])">
<span class="pair-button-text">{{ getDeviceShowNameProject(device[0]) }}</span>
</button>
</div>
<!-- append device -->
<div v-if="deviceListInOrder.length < 4">
<button class="add-button" icon="fa fa-plus" @click="clickShowLibrary"><span class="add-button-text">+</span></button>
</div>
</draggable>
<div>
<button class="add-button" icon="fa fa-plus" @click="clickShowLibrary"><span class="add-button-text">+</span></button>
</div>
</div>
</div>
</template>
@@ -159,19 +181,32 @@ export default {
.not-pair-button {
width: 100%;
height: 36px;
background: #858dd6;
border: 1px #ffffff dashed;
background: #e0e0e0;
border: 0;
border-radius: 20px;
}
.pair-button-text {
font-family: 'Inter';
font-family: 'Inter-Regular';
font-style: normal;
font-weight: 400;
font-size: 18px;
font-size: 16px;
line-height: 24px;
text-align: center;
color: #ffffff;
}
.project-device-header-text {
align-items: center;
// font-family: 'Inter-Regular';
// font-style: normal;
font-weight: 700;
font-size: 20px;
line-height: 29px;
/* identical to box height */
color: rgb(52, 73, 94);
// color: #768b9b;
}
</style>
+355 -102
View File
@@ -1,35 +1,28 @@
<template>
<div class="markup-tables project-table flex d-flex sm12 xl12 md12 xs12 px-0 mx-0" id="scro" style="width: 100%; height: 55vh; overflow: auto;">
<div class="markup-tables project-table flex d-flex sm12 xl12 md12 xs12 px-0 mx-0" id="scro" style="width: 100%; height: 55vh; overflow: auto; padding-top: 0;">
<div class="table-wrapper" style="width: 100%;">
<table class="va-table">
<table class="va-table project-table-text">
<thead>
<tr>
<th v-if="lockMode === false">
<va-checkbox
v-model="tableColumn.checked"
:array-value="'-1'"
@input="selectAll($event)"
/>
</th>
<th align="center">order</th>
<th align="center">name</th>
<tr class="project-table-header">
<th align="center" style="min-width: 50px; padding: 0;">order</th>
<th align="center" style="min-width: 100px;">name</th>
<th align="center" @click="openConfig(1)">device</th>
<th align="center">action and condition</th>
<th align="center">parameter</th>
<th v-if="lockMode" align="center">cycle</th>
<th align="center"></th>
<th align="center" style="min-width: 100px;">start</th>
<th align="center" style="min-width: 100px;">stop</th>
<th align="center" style="min-width: 100px;">parameter</th>
<!-- <th v-if="lockMode" align="center">cycle</th> -->
<th align="center" style="min-width: 50px;"></th>
</tr>
</thead>
<!-- <tbody> -->
<vuedraggable :disabled="lockMode === true" class="draggable" :list="getSelectProject.task" @end="rearrangeTask({ project: getSelectProject })" tag="tbody" animation="500">
<vuedraggable :disabled="lockMode === true || inputMode === true" class="draggable" :list="getSelectProject.task" @end="rearrangeTask({ project: getSelectProject })" tag="tbody" animation="500">
<template class="item" v-for="(task, taskIndex) in getSelectProject.task">
<tr v-if="task.type === 'cycle'" :key="'empty' + taskIndex" height="80px" @click="showCycleModal(task.uuid)">
<td v-if="lockMode === false">
<va-checkbox
v-model="tableColumn.checked"
:array-value="String(taskIndex)"
/>
</td>
<tr
v-if="task.type === 'cycle'"
:key="'empty' + taskIndex"
height="50px"
@click="showCycleModal(task.uuid)"
>
<td align="center">
{{ taskIndex + 1 }}
</td>
@@ -61,7 +54,6 @@
<va-button icon="fa fa-play" @click="trigger_button(getSelectProject)" flat></va-button>
<td/>
<td align="center" v-if="lockMode === true">
<!-- {{ task.status }} -->
<fulfilling-bouncing-circle-spinner
v-if="task.status === 1"
:animation-duration="3000"
@@ -71,21 +63,35 @@
<!-- <va-icon v-if="task.status === 2" class="fa fa-check"></va-icon> -->
</td>
</tr>
<tr v-else-if="task.device && task.device.length === 0" :key="'empty' + taskIndex" height="80px" @click="() => { focus = taskIndex }">
<td v-if="lockMode === false">
<va-checkbox
v-model="tableColumn.checked"
:array-value="String(taskIndex)"
/>
</td>
<tr
v-else-if="task.device && task.device.length === 0"
:class="taskIndex === projectTableSelectIndex ? 'table-row-focus' : ''"
:key="'empty' + taskIndex" height="50px"
@click="() => { projectTableSelectIndex = taskIndex }"
>
<td align="center">
{{ taskIndex + 1 }}
</td>
<td align="center">
{{ task.name }}
<!-- name -->
<td align="center" @dblclick="switchInput('name', taskIndex)">
<div v-if="tableColumn.name == taskIndex && lockMode === false">
<va-input
:ref="'input_ref'"
v-model="task.name"
style="width: 100px;"
@blur="switchInput('name', -1)"
@keyup.enter="switchInput('name', -1)"
/>
</div>
<div v-else align="center">
{{ task.name }}
</div>
</td>
<td align="center">
<va-button :flat="true" @click="openConfig(1, taskIndex)" small>+ Device</va-button>
<va-button :flat="true" @click="openConfig(1, taskIndex)" small>+</va-button>
</td>
<td align="center">
<va-button :flat="true" @click="openConfig(2, taskIndex)" :disabled="true" small>-</va-button>
</td>
<td align="center">
<va-button :flat="true" @click="openConfig(3, taskIndex)" :disabled="true" small>-</va-button>
@@ -93,23 +99,23 @@
<td align="center">
<va-button :flat="true" @click="openConfig(4, taskIndex)" :disabled="true" small>-</va-button>
</td>
<td align="center">
<va-icon class="fa fa-close" @click.native="() => deleteTask({ project: getSelectProject, index: taskIndex})"></va-icon>
</td>
</tr>
<tr :class="taskIndex === focus ? 'table-row-focus' : ''" v-else v-for="(deviceUUID) in task.device" :key="String(taskIndex) + ' ' + String(deviceUUID)" height="80px" @click="() => { focus = taskIndex }">
<td v-if="lockMode === false">
<va-checkbox
v-model="tableColumn.checked"
:array-value="String(taskIndex)"
/>
</td>
<tr
v-else
height="50px"
:class="taskIndex === projectTableSelectIndex ? 'table-row-focus' : ''"
:key="String(taskIndex)"
@click="() => { projectTableSelectIndex = taskIndex }"
>
<!-- order -->
<td align="center">
{{ taskIndex + 1 }}
</td>
<!-- name -->
<td align="center" @dblclick="switchInput('name', taskIndex)">
<div v-if="tableColumn.name == taskIndex && lockMode === false">
<va-input
:ref="'input_ref'"
v-model="task.name"
style="width: 100px;"
@blur="switchInput('name', -1)"
@@ -128,77 +134,103 @@
</va-button>
</div>
<div v-else>
<va-button :flat="true" @click="openConfig(1, taskIndex, deviceUUID)" small>
<span>{{ getDeviceShowNameProject(deviceUUID)}}</span>
</va-button>
<div class="flex project-table-cell" v-for="(deviceUUID) in task.device" :key="deviceUUID" @click="openConfig(1, taskIndex, deviceUUID)">
<p>{{ getDeviceShowNameProject(deviceUUID)}}</p>
</div>
</div>
</td>
<!-- device end -->
<!-- action -->
<!-- start -->
<td align="center">
<div v-if="Object.keys(task.action).length === 0">
<va-button :flat="true" @click="openConfig(3, taskIndex, deviceUUID)" small>
+ Event
</va-button>
</div>
<div v-else class="flex">
<div class="flex project-table-cell" v-for="(deviceUUID) in task.device" :key="deviceUUID">
<div v-if="Object.values(task.action).filter(ele => ele.type === 'start' && ele.target === deviceUUID).length === 0">
+
</div>
<div v-for="(action, actionKey) in task.action" :key="actionKey">
<div v-if="action.target === deviceUUID">
<div v-for="conditionKey in action.condition" :key="conditionKey">
<div small v-if="action.type !== 'cycle' && action.type !== 'start'">
{{ action.type }} {{ task.condition[conditionKey].type }} {{ task.condition[conditionKey].value }}
<va-icon class="fa fa-close" @click.native="delAction(task, actionKey, conditionKey)"/>
</div>
<div small v-else-if="action.type == 'cycle' && task.condition[conditionKey].type === 'previous_task_done'">
{{ action.type }} go to {{ task.cycle_next }} run {{ task.cycle }} times
<va-icon class="fa fa-close" @click.native="delAction(task, actionKey, conditionKey)"/>
<div v-if="action.condition.length === 0">
+
</div>
<div v-else v-for="conditionKey in action.condition" :key="conditionKey">
<div v-if="action.type == 'start' && task.condition[conditionKey].type === 'previous_task_done'">
<div v-if=" taskIndex === 0"> - </div>
<div v-else> Follow {{ getSelectProject.task[taskIndex - 1].name }} </div>
</div>
</div>
</div>
</div>
<va-button :flat="true" @click="openConfig(3, taskIndex, deviceUUID)" small>
+ Event
</va-button>
</div>
</td>
<!-- action end -->
<!-- start end -->
<!-- stop -->
<td align="center">
<div v-if="Object.keys(task.parameter_set).length === 0">
<va-button :flat="true" @click="openConfig(4, taskIndex, deviceUUID)" small>
+ Parameter
</va-button>
</div>
<va-button :flat="true" @click="openConfig(4, taskIndex, deviceUUID)" v-else class="flex d-flex">
<div class="flex" small>
<div v-for="(parameterSet, parameterSetKey) in getParameterSetTask(taskIndex, deviceUUID)" :key="parameterSetKey">
<div v-for="(parameter, parameterKey) in parameterSet" :key="parameterKey">
<span v-if="parameterKey !== 'target'">
<div small>
{{ parameterName(parameterKey, deviceUUID) }} : {{ parameterValue(parameterKey, parameter, deviceUUID) }}
</div>
</span>
<div class="flex project-table-cell" v-for="(deviceUUID) in task.device" :key="deviceUUID" @click="openConfig(3, taskIndex, deviceUUID)">
<div v-if="Object.values(task.action).filter(ele => ele.type === 'stop' && ele.target === deviceUUID).length === 0">
+
</div>
<div v-for="(action, actionKey) in task.action" :key="actionKey">
<div v-if="action.target === deviceUUID">
<div v-if="action.condition.length === 0">
+
</div>
<div v-else v-for="conditionKey in action.condition" :key="conditionKey">
<div v-if="action.type == 'stop' && task.condition[conditionKey].type === 'after_task_run'" >
{{ transTime(task.condition[conditionKey].value) }}
<va-icon class="fa fa-close" @click.native="delAction(task, actionKey, conditionKey)"/>
</div>
</div>
</div>
</div>
</va-button>
</div>
</td>
<!-- stop end -->
<td align="center">
<div class="flex project-table-cell" v-for="(deviceUUID) in task.device" :key="deviceUUID" @click="openConfig(4, taskIndex, deviceUUID)">
<div v-if="Object.values(task.parameter_set).filter(ele => ele.target === deviceUUID).length === 0" >
<p>
+
</p>
</div>
<div style="height: auto;" v-for="(parameterSet, parameterSetKey) in getParameterSetTask(taskIndex, deviceUUID)" :key="parameterSetKey">
<v-popover
placement="right"
trigger="hover"
popoverBaseClass="tooltip popover test"
:disabled="!Object.keys(parameterSet).filter(ele=>ele !== 'MODE' && ele !== 'target').length > 0"
>
<div class="tooltip-target">
{{ parameterName('MODE', deviceUUID) }} : {{ parameterValue('MODE', parameterSet.MODE, deviceUUID) }}
</div>
<template slot="popover">
<div>
<div v-for="(parameter) in parameterShow(parameterSet.MODE, deviceUUID)" :key="parameter + parameterSet.MODE">
<p>
{{ parameterName(parameter, deviceUUID) }} : {{ parameterValue(parameter, parameterSet[parameter], deviceUUID) }}
</p>
</div>
</div>
</template>
</v-popover>
</div>
</div>
</td>
<td align="center" v-if="lockMode === false">
<va-icon v-if="String(taskIndex) !== '0'" class="fa fa-toggle-up" @click.native="swapTask(taskIndex, 0)"/>
<!-- <va-icon v-if="String(taskIndex) !== '0'" class="fa fa-toggle-up" @click.native="swapTask(taskIndex, 0)"/>
<va-icon v-if="parseInt(taskIndex) !== getSelectProject.task.length - 1" class="fa fa-toggle-down" @click.native="swapTask(taskIndex, 1)"/>
<va-icon class="fa fa-copy ml-1" @click.native="() => copyTask({ project: getSelectProject, index: taskIndex})"></va-icon>
<va-icon class="fa fa-close ml-1" @click.native="() => deleteTask({ project: getSelectProject, index: taskIndex})"></va-icon>
<va-icon class="fa fa-copy ml-1" @click.native="() => copyTask({ project: getSelectProject, index: taskIndex})"></va-icon> -->
<va-icon class="fa fa-close" color="#B8C3CC" @click.native="() => deleteTask({ project: getSelectProject, index: taskIndex})"></va-icon>
</td>
<td align="center" v-if="lockMode === true">
<!-- <td align="center" v-if="lockMode === true">
<div v-if="task.cycle > 0 && task.status === 2 && task.cycle_count === 0">
{{ task.cycle }}/{{ task.cycle }}
</div>
<div v-else-if="task.cycle > 0">
{{ task.cycle_count }}/{{ task.cycle }}
</div>
</td>
<td v-if="lockMode === true && Object.values(task.condition).findIndex(ele => ele.type == 'until_button_trigger') != -1 && task.status === 1">
</td> -->
<!-- <td v-if="lockMode === true && Object.values(task.condition).findIndex(ele => ele.type == 'until_button_trigger') != -1 && task.status === 1">
<va-button icon="fa fa-play" @click="trigger_button(getSelectProject)" flat></va-button>
<td/>
<td/> -->
<td align="center" v-if="lockMode === true">
<!-- {{ task.status }} -->
<fulfilling-bouncing-circle-spinner
@@ -212,7 +244,10 @@
</tr>
</template>
</vuedraggable>
<!-- </tbody> -->
<!-- </tbody> -->
<tr class="table-row-add-task" v-if="lockMode === false">
<td align="center" colspan="7" class="table-row-add-task-text" @click="createTask">+ task</td>
</tr>
</table>
</div>
<div>
@@ -259,6 +294,7 @@ export default {
'deviceSelectKey',
'lockMode',
'projectLibrary',
'projectTableSelectIndex',
]),
},
data () {
@@ -268,12 +304,48 @@ export default {
checked: [],
},
inputSaved: '',
focus: -1,
index: -1,
futureIndex: -1,
inputMode: false,
}
},
methods: {
transTime: function (sec) {
if (sec === undefined || sec === 'None') {
return '0 s'
}
let result = ''
if (sec < 1) {
result = '~ 1 s'
} else {
let seconds = parseInt(sec / 1)
if (seconds < 60) {
result = `${seconds} sec`
} else {
let minutes = parseInt(seconds / 60)
seconds %= 60
if (minutes < 60) {
if (seconds === 0) {
result = `${minutes} min`
} else {
result = `${minutes} m ${seconds} s`
}
} else {
const hours = parseInt(minutes / 60)
minutes %= 60
if (seconds === 0 && minutes === 0) {
result = `${hours} hour`
} else {
result = `${hours} h ${minutes} m ${seconds} s`
}
}
}
}
return result
},
mqttPub: function (topic, mes) {
this.$mqtt.publish(topic, mes)
},
@@ -323,9 +395,18 @@ export default {
}))
},
switchInput: function (tag, index) {
this.tableColumn[tag] >= 0
? this.tableColumn[tag] = -1
: this.tableColumn[tag] = index
if (this.tableColumn[tag] === -1) {
if (index !== -1) {
this.inputMode = true
this.tableColumn[tag] = index
this.$nextTick(() => {
this.$refs.input_ref[0].$refs.input.focus()
})
}
} else {
this.inputMode = false
this.tableColumn[tag] = -1
}
},
switchCycle: function (tag, index, projectID, task) {
this.switchInput(tag, index)
@@ -364,6 +445,12 @@ export default {
}
}
},
parameterShow (mode, deviceKey) {
const config = configTable.getConfig(this.getDeviceLibraryProject(deviceKey))
if (config !== undefined && Object.keys(config) !== 0) {
return config.MODE[mode].parameter
}
},
parameterName (name, deviceKey) {
const config = configTable.getConfig(this.getDeviceLibraryProject(deviceKey))
if (config !== undefined && Object.keys(config) !== 0) {
@@ -378,15 +465,16 @@ export default {
},
parameterValue (name, value, deviceKey) {
const config = configTable.getConfig(this.getDeviceLibraryProject(deviceKey))
const _value = (value === undefined) ? config[name].defaultValue : value
if (config !== undefined && Object.keys(config) !== 0) {
if (name === 'MODE') {
return config.MODE[value].name
return config.MODE[_value].name
}
if (config[name].type === 'number') {
const scale = config[name].unit[config[name].defaultUnit]
return `${config[name].outputReadabilityData(value, scale)} ${config[name].defaultUnit}`
return `${config[name].outputReadabilityData(_value, scale)} ${config[name].defaultUnit}`
} else if (config[name].type === 'array') {
return `${config[name].outputReadabilityData(value)}`
return `${config[name].outputReadabilityData(_value)}`
} else if (config[name].type === 'none') {
return ''
}
@@ -417,6 +505,7 @@ export default {
return false // disable sort
},
...mapActions('project', [
types.task.create,
types.task.copy,
types.task.delete,
types.task.rearrange,
@@ -435,8 +524,8 @@ export default {
.table-row-focus {
background: #ebedff;
border: 1px solid #dbdcf0;
box-shadow: 1px 1px 2px rgba(0, 0, 0, 0.25);
// border: 0.5px solid #dbdcf0;
// box-shadow: 1px 1px 2px rgba(0, 0, 0, 0.25);
border-radius: 5px;
}
@@ -456,13 +545,17 @@ export default {
max-height: 100px;
overflow: auto;
white-space: nowrap;
font-size: 1.1rem;
}
td:hover {
cursor: pointer;
}
th {
padding: 0 0 0 0;
margin: 0;
// padding: 0 0 0;
// margin: 0;
font-size: 1rem;
border: none;
}
div {
@@ -471,4 +564,164 @@ export default {
}
}
.table-row-add-task {
height: 50px;
background: #f4f4f4;
border: 1px dashed #c7c7c7;
border-radius: 5px;
}
.table-row-add-task-text {
font-family: 'Inter-Regular';
font-style: italic;
font-weight: 600;
font-size: 16px;
line-height: 24px;
text-align: center;
color: #c7c7c7;
}
.project-table-header {
position: sticky;
top: 0;
background: white;
font-family: 'Inter-Bold';
font-style: normal;
font-weight: 600;
font-size: 16px;
line-height: 24px;
text-align: center;
color: #2c4053;
}
.project-table-text {
font-family: 'Inter-Regular';
font-style: normal;
// font-weight: 400;
font-size: 16px;
line-height: 24px;
text-align: center;
color: #2c4053;
}
.project-table-cell:hover {
opacity: 0.6;
}
.tooltip {
display: block !important;
z-index: 10000;
.tooltip-inner {
// background: red !important;
color: white;
border-radius: 16px;
padding: 5px 10px 4px;
box-shadow: rgba(108, 127, 238, 0.6) 0 2px 3px 0;
background-color: #ebedff !important;
}
.tooltip-arrow {
width: 0;
height: 0;
border-style: solid;
position: absolute;
margin: 5px;
border-color: black;
z-index: 1;
}
&[x-placement^="top"] {
margin-bottom: 5px;
.tooltip-arrow {
border-width: 5px 5px 0 5px;
border-left-color: transparent !important;
border-right-color: transparent !important;
border-bottom-color: transparent !important;
bottom: -5px;
left: calc(50% - 5px);
margin-top: 0;
margin-bottom: 0;
}
}
&[x-placement^="bottom"] {
margin-top: 5px;
.tooltip-arrow {
border-width: 0 5px 5px 5px;
border-left-color: transparent !important;
border-right-color: transparent !important;
border-top-color: transparent !important;
top: -5px;
left: calc(50% - 5px);
margin-top: 0;
margin-bottom: 0;
}
}
&[x-placement^="right"] {
margin-left: 5px;
.tooltip-arrow {
border-width: 5px 5px 5px 0;
border-left-color: transparent !important;
border-top-color: transparent !important;
border-bottom-color: transparent !important;
left: -5px;
top: calc(50% - 5px);
margin-left: 0;
margin-right: 0;
}
}
&[x-placement^="left"] {
margin-right: 5px;
.tooltip-arrow {
border-width: 5px 0 5px 5px;
border-top-color: transparent !important;
border-right-color: transparent !important;
border-bottom-color: transparent !important;
right: -5px;
top: calc(50% - 5px);
margin-left: 0;
margin-right: 0;
}
}
&.popover {
$color: #ebedff;
.popover-inner {
background: $color;
color: black;
padding: 24px;
border-radius: 5px;
box-shadow: 0 5px 30px rgba(black, 0.1);
}
.popover-arrow {
border-color: $color;
}
}
&[aria-hidden='true'] {
visibility: hidden;
opacity: 0;
transition: opacity 0.15s, visibility 0.15s;
}
&[aria-hidden='false'] {
visibility: visible;
opacity: 1;
transition: opacity 0.15s;
}
}
.test {
left: -175px !important;
}
</style>
@@ -17,7 +17,7 @@
/>
<va-input
v-if="[1, 2, 3].indexOf(selectFilter.id) >= 0"
:label="'EIS_FREQ'"
:label="'FREQ'"
class="mx-1 freq-input"
v-model="freq2"
>
@@ -17,7 +17,7 @@
/>
<va-input
v-if="[1, 2, 3].indexOf(selectFilter.id) >= 0"
:label="'EIS_FREQ'"
:label="'FREQ'"
class="mx-1 freq-input"
v-model="freq2"
>
@@ -186,7 +186,7 @@ export default {
} else if (deviceInfo.library_name.includes('Elite')) {
const sourceObj = configTable.getChannelConfig(String(deviceInfo.library_name), deviceInfo.configuration.MODE) // [{id:0 channel:'Current'}, {id:1, channel:'Voltage'}, ]
let channelSet
if (deviceInfo.library_name.includes('EIS') && deviceInfo.configuration.MODE === 0) {
if (deviceInfo.library_name.includes('EIS') && (deviceInfo.configuration.MODE === 0 || deviceInfo.configuration.MODE === 5)) {
channelSet = ['Zimag_Raw', 'Zreal_Raw', 'Frequency', 'Cycle', 'Zimag', 'Zreal', 'Impedance', 'Phase', 'Current', 'Level gain']
} else {
channelSet = []
@@ -262,7 +262,7 @@ export default {
} else if (deviceInfo.library_name.indexOf('Elite') >= 0) {
const sourceObj = configTable.getChannelConfig(String(deviceInfo.library_name), deviceInfo.configuration.MODE) // [{id:0 channel:'Current'}, {id:1, channel:'Voltage'}, ]
let channelSet
if (deviceInfo.library_name.includes('EIS') && deviceInfo.configuration.MODE === 0) {
if (deviceInfo.library_name.includes('EIS') && (deviceInfo.configuration.MODE === 0 || deviceInfo.configuration.MODE === 5)) {
channelSet = ['Zimag_Raw', 'Zreal_Raw', 'Frequency', 'Cycle', 'Zimag', 'Zreal', 'Impedance', 'Phase', 'Current', 'Level gain']
} else {
channelSet = []
@@ -105,6 +105,109 @@ const chartTable = {
},
},
],
T_Impedance: [
// 0
{
default: {
name: 'Time',
unit: {
us: 1,
ms: 1e3,
s: 1e6,
min: 60 * 1e6,
hour: 60 * 60 * 1e6,
},
defaultUnit: 's',
downloadUnit: 'ms',
},
},
// 1
{
default: {
name: 'Resistance',
unit: {
: 1e-3,
Ω: 1,
: 1e3,
: 1e6,
},
defaultUnit: 'Ω',
downloadUnit: 'Ω',
},
},
],
T_Phase: [
// 0
{
default: {
name: 'Time',
unit: {
us: 1,
ms: 1e3,
s: 1e6,
min: 60 * 1e6,
hour: 60 * 60 * 1e6,
},
defaultUnit: 's',
downloadUnit: 'ms',
},
},
// 1
{
default: {
name: 'degree',
unit: {
'°': 1e3,
},
defaultUnit: '°',
downloadUnit: '°',
},
},
],
T_Current: [
// 0
// 0
{
default: {
name: 'Time',
unit: {
us: 1,
ms: 1e3,
s: 1e6,
min: 60 * 1e6,
hour: 60 * 60 * 1e6,
},
defaultUnit: 's',
downloadUnit: 'ms',
},
},
// 1
{
default: {
name: 'Current',
unit: {
nA: 1,
uA: 1e3,
mA: 1e6,
A: 1e9,
},
defaultUnit: (Mode) => { return (Mode === 10 || Mode === 11) ? 'nA' : 'mA' },
downloadUnit: 'mA',
},
// Q = ∫ I dt
integral: {
name: 'Charge',
unit: {
nAh: 3600 * 1e6,
uAh: 1600 * 1e9,
mAh: 3600 * 1e12,
Ah: 3600 * 1e15,
},
defaultUnit: 'mAh',
downloadUnit: 'mAh',
},
},
],
V_V: [
// 0
{
@@ -19,11 +19,13 @@
<img :src="device.picture" :alt="device.name">
</va-avatar>
</va-item-section>
<va-item-section class="ml-3" caption>
<!-- <va-button @click="getBattery(device)"> get battery </va-button> -->
<!-- <pre> {{ device.battery }} </pre> -->
<va-item-label v-if="parseInt((device.battery - 2900) / 10) >= 75">
<va-item-label v-if="device.library_name.includes('EIS')">
{{ `[${device.memory_board}]` }} {{ device.name }}
</va-item-label>
<va-item-label v-else-if="parseInt((device.battery - 2900) / 10) >= 75">
{{ `[${device.memory_board}]` }} {{ device.name }} <va-icon class="ml-3 fa fa-battery-full" color="#5BC236"/> {{ (parseInt((device.battery - 2900) / 10) > 100 ? 100 : parseInt((device.battery - 2900) / 10)) + '%' }}
</va-item-label>
<va-item-label v-else-if="parseInt((device.battery - 2900) / 10) >= 50">
@@ -26,8 +26,12 @@
</div>
</div>
<!-- split because of styling problem(treenode), combine together furture -->
<!-- Trigger -->
<div v-if="library && library.includes('TRIG')">
<Trigger :parameter="parameter" :parameterTable="parameterTable" @parameterChange="parameterChange"></Trigger>
</div>
<!-- EIS -->
<div v-if="library.includes('EIS')">
<div v-if="library && library.includes('EIS')">
<component
v-for="name in parameterArrayInMode"
:key="name"
@@ -44,7 +48,7 @@
/>
</div>
<!-- ZM15-PulseSensingMode -->
<div v-else-if="parameter.MODE === 14">
<div v-else-if="library && library.includes('EDC') && parameter.MODE === 14">
<EliteParameterRecordingElitePulseSensing
:parameter="parameter"
:device="device"
@@ -55,7 +59,7 @@
/>
</div>
<!-- ZM15-DPVMode -->
<div v-else-if="parameter.MODE === 15">
<div v-else-if="library && library.includes('EDC') && parameter.MODE === 15">
<EliteParameterRecordingEliteDPV
:parameter="parameter"
:device="device"
@@ -66,7 +70,7 @@
/>
</div>
<!-- ZM15-OtherModes -->
<div v-else>
<div v-else-if="library && library.includes('EDC')">
<va-tree-category
v-for="name in parameterArrayInMode"
:key="name"
@@ -94,7 +98,7 @@
<!-- guide picture button -->
<div>
<vue-final-modal
v-if="library.includes('Elite_EDC')"
v-if="library && library.includes('EDC')"
v-model="showModal"
classes="modal-container"
content-class="modal-content"
@@ -124,6 +128,7 @@ import InputField from '../parameter/itemNew/InputField'
import MultiInputField from '../parameter/itemNew/MultiInputField'
import EliteParameterRecordingEliteDPV from '../parameter/itemNew/DPVNew/EliteParameterRecordingEliteDPV'
import DevMode from '../parameter/itemNew/DevMode'
import Trigger from '../parameter/itemNew/TriggerNew/Trigger'
import EliteParameterRecordingElitePulseSensing from '../parameter/itemNew/PulseSensingNew/EliteParameterRecordingElitePulseSensing'
import { VueFinalModal } from 'vue-final-modal'
import { mapFields } from 'vuex-map-fields'
@@ -141,6 +146,7 @@ export default {
InputField,
MultiInputField,
DevMode,
Trigger,
},
props: {
parameter: {
@@ -148,7 +154,8 @@ export default {
required: true,
},
library: {
type: String,
type: [String, null],
default: null,
},
serialNumber: {
type: [String, Array],
@@ -161,6 +168,10 @@ export default {
type: String,
default: '',
},
resetParameterModeChange: {
type: Boolean,
default: false,
},
},
computed: {
parameterTable () {
@@ -179,7 +190,7 @@ export default {
return null
},
parameterArrayInMode () {
return this.workingModeSelect && this.parameterTable.MODE[this.workingModeSelect.id].parameter
return this.workingModeSelect && this.parameterTable && this.parameterTable.MODE[this.workingModeSelect.id].parameter
},
modeSelection () {
if (this.parameter.MODE) {
@@ -188,7 +199,7 @@ export default {
return this.workingModeSelect.id
},
getImageUrl () {
if (this.workingModeSelect === null) {
if (!this.workingModeSelect) {
return 'IV-Wire'
} else {
return this.workingModeSelect.img_src
@@ -247,11 +258,17 @@ export default {
refresh () {
},
workingModeSelectChange (val) {
if (val === undefined) return
this.workingModeSelect = val
console.log('workingModeSelectChange', this.workingModeSelect.id, this.parameter.MODE)
// console.log('workingModeSelectChange', this.workingModeSelect, this.parameter.MODE)
if (this.workingModeSelect.id !== this.parameter.MODE) {
this.parameterChange('MODE', this.workingModeSelect.id)
if (this.resetParameterModeChange === true) {
for (const parameter of this.parameterTable.MODE[this.workingModeSelect.id].parameter) {
this.$emit('setParameter', parameter, this.parameterTable[parameter].defaultValue)
}
}
// if device is idle, then setting highz when mode switch
if (this.deviceStatus === true) {
@@ -278,9 +295,11 @@ export default {
// this.developerMode === true
// ? this.workingModeOptions = this.workingModeDevOptions
// : this.workingModeOptions = this.workingModeNoDevOptions
this.workingModeOptions = this.parameterTable.MODE_OPTIONS
// init mode
this.workingModeSelect = (this.parameter.MODE !== undefined) ? this.workingModeOptions.find(ele => ele.id === this.parameter.MODE) : this.workingModeOptions[0]
if (this.parameterTable !== null) {
this.workingModeOptions = this.parameterTable.MODE_OPTIONS
// init mode
this.workingModeSelect = (this.parameter.MODE !== undefined) ? this.workingModeOptions.find(ele => ele.id === this.parameter.MODE) : this.workingModeOptions[0]
}
},
watch: {
parameter: {
@@ -290,6 +309,13 @@ export default {
this.workingModeSelect = (this.parameter.MODE !== undefined) ? this.workingModeOptions.find(ele => ele.id === this.parameter.MODE) : this.workingModeOptions[0]
},
},
library: {
handler: function () {
if (!this.parameterTable) return
this.workingModeOptions = this.parameterTable.MODE_OPTIONS
this.workingModeSelect = (this.parameter.MODE !== undefined) ? this.workingModeOptions.find(ele => ele.id === this.parameter.MODE) : this.workingModeOptions[0]
},
},
},
destroyed () {
},
@@ -0,0 +1,144 @@
<template>
<div class="flex sm12 xl12 md12 xs12 mb-2 pb-1 align--center">
<div class="row">
<div class="flex sm4 xl4 md4 xs4 my-1 py-0">
<p class="display-6"> CHANNEL {{ Number(channel) + 1 }} <p/>
</div>
<div class="flex sm3 xl3 md3 xs3 px-0 mx-0 my-0 py-0">
<va-input
class="mb-0 small-va-input"
v-model="inputStringText"
:disabled="!channelToggle"
@keyup.enter="inputChange(inputString)"
@blur="inputChange(inputString)"
>
<p slot="append" style="margin-right: 0;" small>
mA
</p>
</va-input>
</div>
<div class="flex sm5 xl5 md5 xs5 px-0 mx-0 my-0 py-0">
<va-toggle class="mb-0" v-model="channelToggle" color="success" style="float: right;" flat small @click.native="switchToggle()"/>
</div>
</div>
<div class="sm11 xl12 md12 xs12 my-1 py-1">
<va-slider
pins
:min="outputReadabilityData(range.min)"
:max="outputReadabilityData(range.max)"
value-visible
:step="10"
:color="channelToggle === true ? 'primary' : 'gray'"
:disabled="!channelToggle"
v-model="inputSlider"
/>
</div>
</div>
</template>
<script>
export default {
name: 'ChannelBlock',
components: {
},
computed: {
inputStringText: {
get () {
return String(this.outputReadabilityData(this.inputValue[this.parameterName]))
},
set (val) {
this.inputString = val
},
},
inputSlider: {
get () {
return this.outputReadabilityData(this.inputValue[this.parameterName])
},
set (val) {
this.inputChange(val)
},
},
},
props: {
inputValue: {
type: Object,
},
channel: {
type: Number,
required: true,
},
parameterName: {
type: String,
required: true,
},
toggleName: {
type: String,
required: true,
},
range: {
type: Object,
},
defaultUnit: {
type: String,
},
unit: {
type: Object,
},
outputReadabilityData: {
type: Function,
default: (val) => val,
},
outputRawData: {
type: Function,
default: (val) => val,
},
},
created () {
},
data () {
return {
inputString: '',
channelToggle: Boolean(this.inputValue[this.toggleName]),
}
},
mqtt: {
},
methods: {
inputChange (val) {
// if change from input field
if (typeof (val) === 'string') {
if (isNaN(val) || val === '') {
return false
}
val = this.outputRawData(val)
if (parseFloat(val) < this.range.min) {
val = this.range.min
} else if (parseFloat(val) > this.range.max) {
val = this.range.max
}
} else if (typeof (val) === 'number') {
val = this.outputRawData(val)
}
this.$emit('parameterChange', this.parameterName, val, true)
},
switchToggle () {
this.$emit('parameterChange', this.toggleName, this.channelToggle)
},
},
}
</script>
<style lang="scss">
.small-va-input {
.va-input {
&__container {
min-height: 1rem;
}
&__container__input {
margin-bottom: 0.001rem;
padding: 0.8rem 0.5rem;
}
}
}
</style>
@@ -0,0 +1,141 @@
<template>
<div class="flex sm12 xl12 md12 xs12 mb-2 pb-1 align--center">
<div class="row">
<div class="flex sm4 xl4 md4 xs4 my-1 py-0">
<p class="display-6 my-2"> Timer <p/>
</div>
<div class="flex sm3 xl3 md3 xs3 px-0 mx-0 my-2 py-0">
<va-input
class="mb-0 small-va-input"
v-model="inputStringText"
:disabled="!timerToggle"
@keyup.enter="inputChange(inputString)"
@blur="inputChange(inputString)"
>
<p slot="append" style="margin-right: 0;" small>
s
</p>
</va-input>
</div>
<div class="flex sm5 xl5 md5 xs5 px-0 mx-0 my-2 py-0">
<va-toggle class="mb-0" v-model="timerToggle" color="success" style="float: right;" flat small @click.native="switchToggle()"/>
</div>
</div>
<!-- <div class="sm11 xl12 md12 xs12 my-1 py-1">
<va-slider
pins
:min="outputReadabilityData(range.min)"
:max="outputReadabilityData(range.max)"
value-visible
:step="10"
:color="timerToggle === true ? 'primary' : 'gray'"
:disabled="!timerToggle"
v-model="inputSlider"
/>
</div> -->
</div>
</template>
<script>
export default {
name: 'TimerBlock',
components: {
},
computed: {
inputStringText: {
get () {
return String(this.outputReadabilityData(this.inputValue[this.parameterName]))
},
set (val) {
this.inputString = val
},
},
inputSlider: {
get () {
return this.outputReadabilityData(this.inputValue[this.parameterName])
},
set (val) {
this.inputChange(val)
},
},
},
props: {
inputValue: {
type: Object,
},
parameterName: {
type: String,
required: true,
},
range: {
type: Object,
},
defaultUnit: {
type: String,
},
unit: {
type: Object,
},
outputReadabilityData: {
type: Function,
default: (val) => val,
},
outputRawData: {
type: Function,
default: (val) => val,
},
},
created () {
},
data () {
return {
inputString: '',
timerToggle: !(this.inputValue[this.parameterName] === 0),
}
},
mqtt: {
},
methods: {
inputChange (val) {
// if change from input field
if (typeof (val) === 'string') {
if (isNaN(val) || val === '') {
return false
}
val = this.outputRawData(val)
if (parseFloat(val) < this.range.min) {
val = this.range.min
} else if (parseFloat(val) > this.range.max) {
val = this.range.max
}
} else if (typeof (val) === 'number') {
val = this.outputRawData(val)
}
this.$emit('parameterChange', this.parameterName, val, true)
},
switchToggle () {
if (this.timerToggle === true) {
this.$emit('parameterChange', this.parameterName, 1)
}
if (this.timerToggle === false) {
this.$emit('parameterChange', this.parameterName, 0)
}
},
},
}
</script>
<style lang="scss">
.small-va-input {
.va-input {
&__container {
min-height: 1rem;
}
&__container__input {
margin-bottom: 0.001rem;
padding: 0.8rem 0.5rem;
}
}
}
</style>
@@ -0,0 +1,106 @@
<template>
<div>
<div v-for="channel in channelList" :key="channel">
<ChannelBlock
:channel="channel"
:inputValue="parameter"
:parameterName="channelBlockCurrent(channel)"
:toggleName="channelBlockToggle(channel)"
v-bind="parameterTable[channelBlockCurrent()]"
@parameterChange="parameterChange"
></ChannelBlock>
</div>
<div class="row px-0 mx-0">
<p class="my-2 mr-2 display-5"> ADVANCED SETTING </p>
<!-- <va-toggle class="mb-0" flat small color="success" v-model="openAdvanced"/> -->
</div>
<div>
<TimerBlock
:inputValue="parameter"
:parameterName="'TIME_DURATION'"
v-bind="parameterTable.TIME_DURATION"
@parameterChange="parameterChange"
></TimerBlock>
</div>
<div>
<div v-for="triggerIndex in triggerList" :key="'trigger_' + triggerIndex">
<TriggerBlock
:triggerIndex="triggerIndex"
:inputValue="parameter"
:parameterName="triggerBlockType(triggerIndex)"
:toggleName="triggerBlockEnable(triggerIndex)"
v-bind="parameterTable[triggerBlockType()]"
@parameterChange="parameterChange"
></TriggerBlock>
</div>
</div>
</div>
</template>
<script>
import ChannelBlock from './ChannelBlock.vue'
import TriggerBlock from './TriggerBlock.vue'
import TimerBlock from './TimerBlock.vue'
export default {
name: 'Trigger',
components: {
ChannelBlock,
TriggerBlock,
TimerBlock,
},
computed: {
},
props: {
parameter: {
type: Object,
default: () => {},
},
parameterTable: {
type: Object,
default: () => {},
},
},
data () {
return {
channelList: [0, 1, 2, 3],
triggerList: [0, 1],
openAdvanced: Boolean(this.parameter.TRIG0_en || this.parameter.TRIG1_en),
}
},
methods: {
channelBlockToggle (channelIndex) {
let name = 'ACC_a_out'
if (channelIndex !== undefined) {
name += channelIndex
}
return name
},
channelBlockCurrent (channelIndex) {
let name = 'ACC_a_out'
if (channelIndex !== undefined) {
name += channelIndex
}
name += '_current'
return name
},
triggerBlockEnable (triggerIndex) {
let name = 'TRIG'
if (triggerIndex !== undefined) {
name += triggerIndex
}
name += '_en'
return name
},
triggerBlockType (triggerIndex) {
let name = 'TRIG'
if (triggerIndex !== undefined) {
name += triggerIndex
}
name += '_edge_type'
return name
},
parameterChange: function (name, value, debounce) {
this.$emit('parameterChange', name, value, debounce)
},
},
}
</script>
@@ -0,0 +1,91 @@
<template>
<div class="row flex sm12 xl12 md12 xs12 ma-0 pa-0">
<div class="d-flex sm12 xl12 md12 xs12 my-0 py-0">
<div class="flex sm8 xl8 md8 xs8 my-1 py-0">
<p class="display-6 my-2"> TRIGGER IN {{ triggerIndex }} <p/>
</div>
<div class="flex sm4 xl4 md4 xs4 ma-0 pa-0 my-2">
<va-toggle class="mb-0" v-model="triggerToggle" color="success" style="float: right;" flat small @click.native="switchToggle()"/>
</div>
</div>
<div class="flex sm12 xl12 md12 xs12 pa-0 ma-0">
<va-radio-button
v-for="(option, index) in optionTrigger"
:key="index"
style="float: left;"
v-model="selectTrigger"
:option="optionTrigger[index]"
:label="optionTrigger[index]"
:disabled="!triggerToggle"
@click.native.stop="inputChange(index)"
/>
</div>
</div>
</template>
<script>
export default {
name: 'TriggerBlock',
components: {
},
props: {
triggerIndex: {
type: Number,
required: true,
},
inputValue: {
type: Object,
},
parameterName: {
type: String,
required: true,
},
toggleName: {
type: String,
required: true,
},
range: {
type: Object,
},
defaultUnit: {
type: String,
},
unit: {
type: Object,
},
outputReadabilityData: {
type: Function,
default: (val) => val,
},
outputRawData: {
type: Function,
default: (val) => val,
},
},
created () {
},
data () {
return {
selectTrigger: 'RISING',
optionTrigger: [
'RISING',
'FALLING',
'BOTH',
],
triggerToggle: false,
}
},
methods: {
inputChange (val) {
this.$emit('parameterChange', this.parameterName, val)
},
switchToggle () {
this.$emit('parameterChange', this.toggleName, this.triggerToggle)
},
},
mounted () {
this.selectTrigger = this.optionTrigger[this.inputValue[this.parameterName]]
this.triggerToggle = Boolean(this.inputValue[this.toggleName])
},
}
</script>
+22
View File
@@ -0,0 +1,22 @@
export default {
name: 'Idle',
parameter: [], // 這個mode用到的參數
showParameter: [], // 有要秀給user看的參數
headerParameter: () => [], // export header的參數
valScales: {
linear: {
func: (val) => {
return val
},
},
log: {
func: (val) => {
return Math.log10(Math.abs(val))
},
},
},
channels: {
},
charts: {
},
}
+17 -9
View File
@@ -1,3 +1,4 @@
import Idle from '../Common/Idle'
import IV from './IV'
import CycleIV from './CycleIV'
import FunctionGenerator from './FunctionGenerator'
@@ -98,20 +99,20 @@ const EliteZM15 = {
showName: 'Current range',
componentType: 'input-button-toggle',
options: [
{ value: 0, label: '<4 μA' },
{ value: 1, label: '2.5-100 μA' },
{ value: 2, label: '85-2050 μA' },
{ value: 0, label: '<4 uA' },
{ value: 1, label: '2.5-100 uA' },
{ value: 2, label: '85-2050 uA' },
{ value: 3, label: '1800 uA' },
{ value: 4, label: 'Auto' },
],
range: ['<4 μA', '2.5-100 μA', '85-2050 μA', '1800 uA', 'Auto'],
range: ['<4 uA', '2.5-100 uA', '85-2050 uA', '1800 uA', 'Auto'],
defaultValue: 4,
outputRawData: (val) => {
const currentRangeArr = ['<4 μA', '2.5-100 μA', '85-2050 μA', '1800 uA', 'Auto']
const currentRangeArr = ['<4 uA', '2.5-100 uA', '85-2050 uA', '1800 uA', 'Auto']
return currentRangeArr.indexOf(val.toString())
},
outputReadabilityData: (idx) => {
const currentRangeArr = ['<4 μA', '2.5-100 μA', '85-2050 μA', '1800 uA', 'Auto']
const currentRangeArr = ['<4 uA', '2.5-100 uA', '85-2050 uA', '1800 uA', 'Auto']
return currentRangeArr[parseInt(idx)]
},
},
@@ -392,10 +393,10 @@ const EliteZM15 = {
componentType: 'input-range',
range: Object.freeze({ min: 0, max: 1500000 }),
defaultValue: 0,
defaultUnit: 'μA',
downloadUnit: 'mA',
defaultUnit: 'uA',
downloadUnit: 'uA',
unit: {
μA: 1,
uA: 1,
mA: 1e3,
},
outputRawData: (val) => {
@@ -952,6 +953,12 @@ const EliteZM15 = {
},
MODE_OPTIONS: [
{
id: 17,
description: 'Idle',
img_src: 'IV-Wire',
highz: 1,
},
{
id: 0,
description: 'I-V Curve',
@@ -1070,6 +1077,7 @@ const EliteZM15 = {
14: PulseSensing,
15: DPV,
16: Chronopotentiometry,
17: Idle,
},
}
@@ -0,0 +1,246 @@
export default {
name: 'Constant Frequency',
parameter: ['CF_DC_BIAS', 'CF_AC_AMP', 'CF_FREQ', 'CF_PPD', 'CF_SCALE', 'CF_DELAY', 'CF_AVERAGE_NUM', 'GENERAL_HS_RTIA'], // 這個mode用到的參數
showParameter: ['CF_DC_BIAS', 'CF_AC_AMP', 'CF_FREQ', 'CF_PPD', 'CF_SCALE', 'CF_DELAY', 'CF_AVERAGE_NUM', 'GENERAL_HS_RTIA'], // 有要秀給user看的參數
headerParameter: () => ['CF_DC_BIAS', 'CF_AC_AMP', 'CF_FREQ', 'CF_PPD', 'CF_SCALE', 'CF_DELAY', 'CF_AVERAGE_NUM', 'GENERAL_HS_RTIA'], // 有要秀給user看的參數
valScales: {
linear: {
func: (val) => {
return val
},
},
log: {
func: (val) => {
return Math.log10(Math.abs(val))
},
},
},
channels: {
time: {
name: 'Time',
unit: {
us: 1,
ms: 1e3,
s: 1e6,
m: 60 * 1e6,
h: 60 * 60 * 1e6,
auto: 1,
},
defaultUnit: 'auto',
downloadUnit: 'ms',
},
0: {
name: 'Z_Imag_Raw',
unit: {
ohm: 1,
},
downloadUnit: 'ohm',
defaultUnit: 'ohm',
},
1: {
name: 'Z_Real_Raw',
unit: {
default: 1,
},
downloadUnit: 'ohm',
defaultUnit: 'ohm',
},
2: {
name: 'Frequency',
unit: {
mHz: 1,
Hz: 1e3,
kHz: 1e6,
},
downloadUnit: 'mHz',
defaultUnit: 'mHz',
},
// 3: {
// name: 'Cycle',
// unit: {
// cycle: 1,
// },
// defaultUnit: 'cycle',
// downloadUnit: null,
// },
4: {
name: 'Z_Imag',
unit: {
mohm: 1e-3,
: 1e-3,
ohm: 1,
Ω: 1,
kohm: 1e3,
: 1e3,
Mohm: 1e6,
: 1e6,
},
downloadUnit: 'ohm',
defaultUnit: 'Ω',
},
5: {
name: 'Z_Real',
unit: {
mohm: 1e-3,
: 1e-3,
ohm: 1,
Ω: 1,
kohm: 1e3,
: 1e3,
Mohm: 1e6,
: 1e6,
},
downloadUnit: 'ohm',
defaultUnit: 'Ω',
},
6: {
name: 'Impedance',
unit: {
mohm: 1e-3,
: 1e-3,
ohm: 1,
Ω: 1,
kohm: 1e3,
: 1e3,
Mohm: 1e6,
: 1e6,
},
downloadUnit: 'ohm',
defaultUnit: 'Ω',
},
7: {
name: 'Phase',
unit: {
millidegree: 1,
'°': 1e3,
},
downloadUnit: 'millidegree',
defaultUnit: '°',
},
8: {
name: 'Current',
unit: {
nA: 1,
uA: 1e3,
mA: 1e6,
},
downloadUnit: 'nA',
defaultUnit: 'nA',
},
9: {
name: 'Level gain',
unit: {
default: 1,
},
downloadUnit: null,
defaultUnit: 'default',
},
10: {
name: 'notify_one',
unit: {
default: 1,
},
downloadUnit: null,
defaultUnit: 'default',
},
11: {
name: 'notify_two',
unit: {
default: 1,
},
downloadUnit: null,
defaultUnit: 'default',
},
12: {
name: 'notify_three',
unit: {
default: 1,
},
downloadUnit: null,
defaultUnit: 'default',
},
13: {
name: 'debug_amp[mV]',
unit: {
default: 1,
},
downloadUnit: null,
defaultUnit: 'default',
},
},
charts: {
default: [
{
name: 'Nyquist',
description: '',
subplot: [
{
x1: {
type: 'value',
valScale: 'linear',
min: 'dataMin',
max: 'dataMax',
},
y1: {
type: 'value',
valScale: 'linear',
min: 'dataMin',
max: 'dataMax',
},
data: [
{
legend: 'Nyquist',
x1: {
channel: 5,
},
y1: {
channel: 4,
},
},
],
},
],
},
{
name: 'Bode',
description: '',
subplot: [
{
x1: {
type: 'value',
valScale: 'log',
min: 'dataMin',
max: 'dataMax',
},
y1: {
type: 'value',
valScale: 'linear',
min: 'dataMin',
max: 'dataMax',
},
y2: {
type: 'value',
valScale: 'linear',
min: 'dataMin',
max: 'dataMax',
},
data: [
{
legend: 'Bode',
x1: {
channel: 2,
},
y1: {
channel: 6,
},
y2: {
channel: 7,
},
},
],
},
],
},
],
},
}
@@ -1,5 +1,5 @@
export default {
name: 'Potentiostatic Electrochemical Impedance Spectroscopy',
name: 'EIS',
parameter: ['EIS_DC_BIAS', 'EIS_AC_AMP', 'EIS_FREQ', 'EIS_PPD', 'EIS_SCALE', 'EIS_DELAY', 'EIS_AVERAGE_NUM', 'GENERAL_HS_RTIA'], // 這個mode用到的參數
showParameter: ['EIS_DC_BIAS', 'EIS_AC_AMP', 'EIS_FREQ', 'EIS_PPD', 'EIS_SCALE', 'EIS_DELAY', 'EIS_AVERAGE_NUM', 'GENERAL_HS_RTIA'], // 有要秀給user看的參數
headerParameter: () => ['EIS_DC_BIAS', 'EIS_AC_AMP', 'EIS_FREQ', 'EIS_PPD', 'EIS_SCALE', 'EIS_DELAY', 'EIS_AVERAGE_NUM', 'GENERAL_HS_RTIA'], // 有要秀給user看的參數
@@ -111,9 +111,10 @@ export default {
7: {
name: 'Phase',
unit: {
'°': 1,
millidegree: 1,
'°': 1e3,
},
downloadUnit: null,
downloadUnit: 'millidegree',
defaultUnit: '°',
},
8: {
@@ -134,6 +135,40 @@ export default {
downloadUnit: null,
defaultUnit: 'default',
},
10: {
name: 'notify_one',
unit: {
default: 1,
},
downloadUnit: null,
defaultUnit: 'default',
},
11: {
name: 'notify_two',
unit: {
default: 1,
},
downloadUnit: null,
defaultUnit: 'default',
},
12: {
name: 'notify_three',
unit: {
default: 1,
},
downloadUnit: null,
defaultUnit: 'default',
},
13: {
name: 'debug_amp[mV]',
unit: {
uV: 1,
mV: 1e3,
V: 1e6,
},
defaultUnit: 'mV',
downloadUnit: 'mV',
},
},
charts: {
default: [
+144 -1
View File
@@ -4,6 +4,8 @@ import DevMode from './DevMode'
import Chronoamperometry from './Chronoamperometry'
import VT from './VT'
import RT from './RT'
import ConstantFrequency from './ConstantFrequency'
import Idle from '../Common/Idle'
const EliteEIS = {
TIME_DURATION: {
@@ -237,6 +239,137 @@ const EliteEIS = {
},
},
EIS_AVERAGE_NUM: {
type: 'array',
showName: 'Average',
componentType: 'input-button-toggle',
options: [
{ value: 0, label: '2' },
{ value: 1, label: '4' },
{ value: 2, label: '6' },
{ value: 3, label: '8' },
],
range: ['2', '4', '6', '8'],
defaultValue: 0,
outputRawData: (val) => {
const numArr = ['2', '4', '6', '8']
return numArr.indexOf(val.toString())
},
outputReadabilityData: (idx) => {
const numArr = ['2', '4', '6', '8']
return numArr[parseInt(idx)]
},
},
CF_DC_BIAS: {
type: 'number',
showName: 'DC Volt',
componentType: 'input-field',
range: Object.freeze({ min: 2500, max: 50000 }), // UI上能輸入的最大最小值
outputRawData: (val, scale = 1) => {
return Math.round((parseInt(val) * 12.5 * scale) + 25000)
},
outputReadabilityData: (val, scale = 1) => {
return Math.round(parseInt(val - 25000) / 12.5) / scale
},
defaultValue: 25000,
defaultUnit: 'mV',
downloadUnit: 'mV',
unit: {
mV: 1,
V: 1e3,
},
},
CF_AC_AMP: {
type: 'number',
showName: 'AC Amp',
componentType: 'input-field',
range: Object.freeze({ min: 0, max: 2047 }),
outputRawData: (val, scale = 1) => {
return Math.round(parseInt(val * scale) / 800 * 2047)
},
outputReadabilityData: (val, scale = 1) => {
return Math.round(parseInt(val) / 2047 * 800) / scale
},
defaultValue: 25,
defaultUnit: 'mV',
downloadUnit: 'mV',
unit: {
mV: 1,
},
},
CF_FREQ: {
type: 'number',
showName: 'Frequency',
componentType: 'input-field',
range: Object.freeze({ min: 1, max: 13333333 }),
outputRawData: (val) => {
return parseFloat(val) < 0.1 ? Math.round(0.1 / 0.015) : Math.round(parseFloat(val) / 0.015)
},
outputReadabilityData: (val) => {
return (parseFloat(val) * 0.015).toFixed(1)
},
defaultValue: 13333333,
defaultUnit: 'Hz',
downloadUnit: 'Hz',
unit: {
Hz: 1,
},
},
CF_PPD: {
type: 'number',
showName: 'Points per decades',
componentType: 'input-field',
range: Object.freeze({ min: 1, max: 10 }),
outputRawData: (val) => {
return parseInt(val)
},
outputReadabilityData: (val) => {
return parseInt(val)
},
defaultValue: 10,
defaultUnit: 'points',
downloadUnit: null,
unit: {
points: 1,
},
},
CF_SCALE: {
type: 'array',
showName: 'Point spacing',
componentType: 'input-button-toggle',
options: [
{ value: 0, label: 'Logarithm' },
{ value: 1, label: 'Linear' },
],
range: ['Logarithm', 'Linear'],
defaultValue: 0,
outputRawData: (val) => {
const scaleArr = ['Logarithm', 'Linear']
return scaleArr.indexOf(val.toString())
},
outputReadabilityData: (idx) => {
const scaleArr = ['Logarithm', 'Linear']
return scaleArr[parseInt(idx)]
},
},
CF_DELAY: {
type: 'number',
showName: 'DELAY',
componentType: 'input-field',
range: Object.freeze({ min: 0, max: 100 }),
outputRawData: (val) => {
return parseInt(parseFloat(val) * 10)
},
outputReadabilityData: (val) => {
return parseFloat((val / 10)).toFixed(1)
},
defaultValue: 0,
defaultUnit: 'points',
downloadUnit: null,
unit: {
points: 1,
},
},
CF_AVERAGE_NUM: {
type: 'array',
showName: 'Average',
componentType: 'input-button-toggle',
@@ -398,6 +531,10 @@ const EliteEIS = {
},
MODE_OPTIONS: [
{
id: 7,
description: 'Idle',
},
{
id: 0,
description: 'Potentiostatic Electrochemical Impedance Spectroscopy',
@@ -420,6 +557,10 @@ const EliteEIS = {
},
{
id: 5,
description: 'Constant Frequency',
},
{
id: 6,
description: 'Dev Tools',
},
],
@@ -429,7 +570,9 @@ const EliteEIS = {
2: Chronoamperometry,
3: VT,
4: RT,
5: DevMode,
5: ConstantFrequency,
6: DevMode,
7: Idle,
},
}
+107
View File
@@ -0,0 +1,107 @@
import Idle from '../Common/Idle'
const EliteTrigger = {
TIME_DURATION: {
type: 'number',
showName: 'Time duration',
componentType: 'input-range',
range: Object.freeze({ min: 0, max: 86400 }), // UI上能輸入的最大最小值
defaultValue: 0,
defaultUnit: 's',
downloadUnit: 's',
unit: {
ms: 1e-3,
s: 1,
m: 60,
h: 3600,
},
outputRawData: (val) => {
return parseInt(parseFloat(val))
},
outputReadabilityData: (val) => {
return parseInt(parseFloat(val))
},
},
ACC_a_out: {
type: 'number',
showName: 'ACC OUT enable',
componentType: 'channelBlock',
range: Object.freeze({ min: 0, max: 1 }), // UI上能輸入的最大最小值
defaultValue: 0,
defaultUnit: null,
downloadUnit: null,
unit: {},
outputRawData: (val) => {
return parseInt(val)
},
outputReadabilityData: (val) => {
return parseInt(val)
},
},
ACC_a_out_current: {
type: 'number',
showName: 'ACC OUT CURRENT',
componentType: 'channelBlock',
range: Object.freeze({ min: 0, max: 50000 }), // UI上能輸入的最大最小值
defaultValue: 0,
defaultUnit: 'mA',
downloadUnit: null,
unit: {
mA: 1,
},
outputRawData: (val) => {
return val * 250
},
outputReadabilityData: (val) => {
return val / 250
},
},
TRIG_en: {
type: 'number',
showName: 'trigger enable',
componentType: 'triggerBlock',
range: Object.freeze({ min: 0, max: 1 }), // UI上能輸入的最大最小值
defaultValue: 0,
defaultUnit: null,
downloadUnit: null,
unit: {},
outputRawData: (val) => {
return parseInt(val)
},
outputReadabilityData: (val) => {
return parseInt(val)
},
},
TRIG_edge_type: {
type: 'number',
showName: 'trigger type',
componentType: 'triggerBlock',
range: Object.freeze({ min: 0, max: 2 }), // UI上能輸入的最大最小值
defaultValue: 0,
defaultUnit: null,
downloadUnit: null,
unit: {},
outputRawData: (val) => {
return parseInt(val)
},
outputReadabilityData: (val) => {
return parseInt(val)
},
},
MODE_OPTIONS: [
{
id: 0,
description: 'Analog Current Control (ACC)',
},
{
id: 1,
description: 'Idle',
},
],
MODE: {
0: null,
1: Idle,
},
}
export default EliteTrigger
+4 -2
View File
@@ -1,5 +1,6 @@
import EliteEDC from './EliteEDC/index'
import EliteEIS from './EliteEIS/index'
import EliteTrigger from './EliteTrigger/index'
import store from '@/store/index'
// object saving library name mapping table
@@ -15,7 +16,7 @@ const libraryNameMappingTable = {
'Elite_EIS_1.0': EliteEIS,
'Elite_EIS_1.1': EliteEIS,
'Elite_EIS_MINI_1.0': EliteEIS,
'Elite_TRIG_0.1': null,
'Elite_TRIG_0.1': EliteTrigger,
'Elite_MEGAFLY_0.1': null,
}
@@ -44,7 +45,7 @@ const serialNumberMappingTable = {
},
5: {
1: {
0: null, // TRIG0.1
0: EliteTrigger, // TRIG0.1
},
},
6: {
@@ -61,6 +62,7 @@ const serialNumberMappingTable = {
* @returns {Object} : config
*/
function getConfig (type) {
if (type === undefined || type === null) return
if (typeof type === 'number') {
const deviceList = store.getters.getField('taskContent').deviceListNew
if (deviceList === undefined) return
+1
View File
@@ -53,6 +53,7 @@ const getDefaultChartTypeByMode = (mode, lib) => {
settings[2] = ['Time', 2, 'Elite', 1]
settings[3] = ['Time', 2, 'Elite', 2]
settings[4] = ['Time', 2, 'Elite', 3]
settings[5] = ['EliteEIS', 6, 'EliteEIS', 5]
return settings[mode]
} else if (lib === 'Elite_TRI') {
// const settings = {}
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
+20
View File
@@ -48,3 +48,23 @@ $icon-font-path: './../fonts/';
font-family: 'Roboto';
src: url('~@/fonts/roboto/Roboto-Bold.ttf') format('truetype');
}
@font-face {
font-family: 'Inter-ExtraBold';
src: url('~@/fonts/inter/Inter-ExtraBold.ttf') format('truetype');
}
@font-face {
font-family: 'Inter-Bold';
src: url('~@/fonts/inter/Inter-Bold.ttf') format('truetype');
}
@font-face {
font-family: 'Inter-Regular';
src: url('~@/fonts/inter/Inter-Regular.ttf') format('truetype');
}
// @font-face {
// font-family: 'Inter';
// src: url('~@/fonts/inter/Inter-Regular.ttf') format('truetype');
// }
@@ -91,6 +91,7 @@ const projectActs = {
*/
[typePath.delete]: async ({ state, getters, commit }, payload) => {
const { project, index, api } = payload
if (project === undefined) return
await api.project.update(project.id, { deleted: true })
await api.project.del()
state.projectList.splice(index, 1)
@@ -105,6 +106,7 @@ const projectActs = {
*/
[typePath.copy]: async ({ state, getters, commit }, payload) => {
const { project, api } = payload
if (project === undefined) return
const copyProject = JSON.parse(JSON.stringify(project))
copyProject.name += ' copy'
+54 -9
View File
@@ -26,11 +26,22 @@ const taskActs = {
const task = newTask(name, uuid)
// check device needs to add auto
if (Object.keys(getters.getSelectProject.device).length === 1) {
task.device.push(Object.keys(getters.getSelectProject.device)[0])
const deviceArray = Object.keys(getters.getSelectProject.device)
if (deviceArray.length === 1) {
task.device.push(deviceArray[0])
await dispatch(typePath.createActionConditionPair, {
device: deviceArray[0],
action: 'start',
condition: {
type: 'previous_task_done',
comparsion: 'equal',
value: '',
},
task: task,
})
}
dispatch(typePath.insert, { project: selectProject, task: task, index: selectProject.task.length })
await dispatch(typePath.insert, { project: selectProject, task: task, index: selectProject.task.length })
},
[typePath.createCycle]: async ({ state, getters, commit, dispatch }, payload) => {
@@ -41,7 +52,7 @@ const taskActs = {
const max = cycleInfo.cycle
const useID = cycleInfo.useID
const id = cycleInfo.id
const count = 1
const count = 0
const cycleLength = selectProject.cycle.length + 1
const name = 'Loop' + cycleLength
@@ -179,7 +190,27 @@ const taskActs = {
* @param {}
*/
[typePath.deleteDevice]: async ({ state, getters, commit, dispatch }, payload) => {
const { deviceKey } = payload
const { deviceKey, onlySelectTask } = payload
if (onlySelectTask !== undefined) {
const task = getters.getSelectTask
task.device = task.device.filter(ele => ele !== deviceKey)
// delete task action & condition
for (const [key, value] of Object.entries(task.action)) {
if (value.target === deviceKey) {
for (const condition of value.condition) {
Vue.delete(task.action, condition)
}
Vue.delete(task.action, key)
}
}
// delete task parameter
for (const [key, value] of Object.entries(task.parameter_set)) {
if (value.target === deviceKey) {
Vue.delete(task.parameter_set, key)
}
}
return true
}
for (const task of getters.getSelectProject.task) {
// delete task device
task.device = task.device.filter(ele => ele !== deviceKey)
@@ -207,7 +238,7 @@ const taskActs = {
* @param {}
*/
[typePath.setCondition]: async ({ state, getters, commit }, payload) => {
const task = getters.getSelectTask
const task = payload.task ? payload.task : getters.getSelectTask
task.condition = Object.assign({}, task.condition, payload.condition)
},
@@ -217,7 +248,7 @@ const taskActs = {
* @param {}
*/
[typePath.setAction]: async ({ state, getters, commit }, payload) => {
const task = getters.getSelectTask
const task = payload.task ? payload.task : getters.getSelectTask
task.action = Object.assign({}, task.action, payload.action)
},
@@ -255,6 +286,15 @@ const taskActs = {
}
task.parameter_set = Object.assign({}, task.parameter_set)
},
[typePath.createActionConditionPair]: async ({ state, getters, commit, dispatch }, payload) => {
const { device, action, condition, task } = payload
const conditionUUID = global.getUUID()
const _condition = await dispatch(typePath.createCondition, { uuid: conditionUUID, condition: condition.type, compOp: condition.comparsion, value: condition.value })
await dispatch(typePath.setCondition, { task: task, condition: _condition })
const actionUUID = global.getUUID()
const _action = await dispatch(typePath.createAction, { uuid: actionUUID, action: action, target: device, condition: conditionUUID })
await dispatch(typePath.setAction, { task: task, action: _action })
},
[typePath.createCondition]: async ({ state, getters, commit }, payload) => {
const { uuid, condition, compOp, value } = payload
@@ -267,12 +307,17 @@ const taskActs = {
}
},
[typePath.createAction]: async ({ state, getters, commit }, payload) => {
const { uuid, action, target } = payload
const { uuid, action, target, condition } = payload
const conditionArray = []
if (condition !== undefined) {
if (typeof condition === 'string') conditionArray.push(condition)
if (typeof condition === 'object') conditionArray.push(...condition)
}
return {
[uuid]: {
type: action,
target: target,
condition: [],
condition: conditionArray,
},
}
},
@@ -17,6 +17,8 @@ const projectGets = {
},
[typePath.getDevice]: (state, getters) => (deviceKey) => {
/** if project is undefined */
if (getters[typePath.getSelect] === undefined) return
return getters[typePath.getSelect].device[deviceKey]
},
+2
View File
@@ -17,6 +17,8 @@ function newState () {
// library
projectLibrary: null,
projectTableSelectIndex: -1,
taskViewPanel: {
show: false,
type: '',
+1
View File
@@ -34,6 +34,7 @@ const types = {
createCycle: 'createCycleTask',
createAction: 'createActionTask',
createCondition: 'createConditionTask',
createActionConditionPair: 'createActionConditionPairTask',
insert: 'insertTask',
swap: 'swapTask',
delete: 'deleteTask',
@@ -437,7 +437,7 @@ const chartActs = {
// eslint-disable-next-line no-case-declarations
const device = state.deviceListNew.find((ele) => String(ele.memory_board) === String(source.id))
if (device === undefined) break
if (Number(device.configuration.MODE) === 0) {
if (Number(device.configuration.MODE) === 0 || Number(device.configuration.MODE) === 5) {
state.chartData[chartID].series[state.chartData[chartID].series.length - 1].showSymbol = true
state.chartData[chartID].series[state.chartData[chartID].series.length - 1].showAllSymbol = true
}
@@ -1246,7 +1246,7 @@ function getLegendName (sourceList, formulaID, deviceList) {
// eslint-disable-next-line no-case-declarations
channelName = getConfigChannel(device.library_name, device.configuration.MODE, source.channel - 1)
if (!channelName) break
if (device.configuration.MODE === 0) {
if ([0, 5].indexOf(Number(device.configuration.MODE)) !== -1) {
legendName += 'E' + source.id + '-' + channelName.name.split('_').join('')
break
}