From 481f2bbabc90cbeed6ec34bd1fc730d342b2de2b Mon Sep 17 00:00:00 2001 From: David Acosta Date: Wed, 7 Dec 2022 10:59:51 -0800 Subject: [PATCH] More tests, improved reports, and UI fixes. --- package.json | 5 +- src/App.vue | 47 ++-- src/assets/avatar.png | Bin 0 -> 5428 bytes src/assets/icon/camera-white.svg | 3 + src/assets/icon/expand.svg | 3 + src/assets/icon/jira.png | Bin 0 -> 710 bytes src/assets/icon/jira.svg | 9 + src/assets/icon/microphone-slash-solid.svg | 10 + src/assets/icon/microphone-solid.svg | 10 + src/assets/icon/microphone-white.svg | 4 + src/assets/icon/microphone.svg | 4 - src/assets/icon/pause-white.svg | 3 + src/assets/icon/pencil-white1.svg | 4 + src/assets/icon/practitest.png | Bin 0 -> 1020 bytes src/assets/icon/practitest.svg | 9 + src/assets/icon/qtest.png | Bin 0 -> 662 bytes src/assets/icon/qtest.svg | 9 + src/assets/icon/stop-white.svg | 3 + src/assets/icon/testrail.png | Bin 0 -> 684 bytes src/assets/icon/testrail.svg | 9 + src/assets/icon/union.svg | 3 + src/assets/icon/video-slash-solid.svg | 10 + src/assets/icon/video-solid.svg | 10 + src/assets/icon/video-white.svg | 4 + src/assets/icon/video.svg | 4 - src/assets/icon/yattie.png | Bin 0 -> 424 bytes src/assets/icon/yattie.svg | 3 + src/components/AudioWrapper.vue | 28 +- src/components/CheckTaskWrapper.vue | 2 +- src/components/ControlPanel.vue | 245 +++++++++++++++--- src/components/FileWrapper.vue | 3 +- src/components/ImageEditor.vue | 113 ++++---- src/components/ReviewWrapper.vue | 3 +- src/components/TestWrapper.vue | 15 +- src/components/TimelineWrapper.vue | 54 +++- src/components/VideoWrapper.vue | 56 ++-- .../__tests__/CheckTaskWrapper.spec.js | 61 +++++ src/components/__tests__/ControlPanel.spec.js | 131 ++++++++++ src/components/__tests__/ImageEditor.spec.js | 2 - .../__tests__/MindmapEditor.spec.js | 20 ++ .../__tests__/ReviewWrapper.spec.js | 16 +- src/components/__tests__/TestWrapper.spec.js | 32 +++ .../__tests__/TimelineWrapper.spec.js | 80 +++++- .../authentication/SigninWrapper.vue | 167 ++++++++++++ .../authentication/Signup1Wrapper.vue | 126 +++++++++ .../authentication/Signup2Wrapper.vue | 216 +++++++++++++++ .../authentication/Signup3Wrapper.vue | 148 +++++++++++ src/components/dialogs/EndSessionDialog.vue | 9 +- src/components/dialogs/NodeEditDialog.vue | 4 +- src/components/dialogs/NoteDialog.vue | 40 ++- src/components/dialogs/SummaryDialog.vue | 145 +++++++++++ .../__tests__/EndSessionDialog.spec.js | 73 ++++++ .../dialogs/__tests__/NodeEditDialog.spec.js | 86 ++++++ .../dialogs/__tests__/NoteDialog.spec.js | 11 + .../settings/ConfigCheckListTab.vue | 7 +- src/components/settings/ConnectionsTab.vue | 12 +- src/components/settings/GeneralTab.vue | 124 ++++----- src/components/settings/ReportsTab.vue | 85 ++++++ src/components/settings/TemplateTab.vue | 21 +- .../__tests__/ConfigCheckListTab.spec.js | 159 ++++++++++++ .../settings/__tests__/ConnectionsTab.spec.js | 96 +++++++ .../settings/__tests__/GeneralTab.spec.js | 60 +++++ .../settings/__tests__/SupportTab.spec.js | 20 ++ .../settings/__tests__/TemplateTab.spec.js | 102 ++++++++ src/layouts/Default.vue | 47 ++++ src/layouts/Minimize.vue | 10 + src/main.js | 6 + src/menu.js | 12 +- src/modules/CaptureUtility.js | 106 ++++++-- src/modules/DatabaseUtility.js | 30 ++- src/modules/IpcHandlers.js | 14 + src/modules/MenuUtility.js | 23 ++ src/modules/constants.js | 97 ++++--- src/plugins/svg.js | 7 - src/router/index.js | 50 ++++ src/store/index.js | 8 +- src/views/AddSession.vue | 53 +++- src/views/AuthenticationView.vue | 23 ++ src/views/EditSession.vue | 44 +++- src/views/HomeView.vue | 9 +- src/views/MainView.vue | 32 ++- src/views/MinimizeView.vue | 160 ++++++++++++ src/views/PrintView.vue | 201 +++++++++++++- src/views/ResultView.vue | 60 +++-- src/views/SettingView.vue | 18 +- src/views/__tests__/AddSession.spec.js | 149 +++++++++++ .../{EditView.spec.js => EditSession.spec.js} | 12 +- src/views/__tests__/EditorView.spec.js | 76 ------ src/views/__tests__/ResultView.spec.js | 4 +- src/views/__tests__/SettingView.spec.js | 34 +++ yarn.lock | 99 ++++++- 91 files changed, 3576 insertions(+), 546 deletions(-) create mode 100644 src/assets/avatar.png create mode 100644 src/assets/icon/camera-white.svg create mode 100644 src/assets/icon/expand.svg create mode 100644 src/assets/icon/jira.png create mode 100644 src/assets/icon/jira.svg create mode 100644 src/assets/icon/microphone-slash-solid.svg create mode 100644 src/assets/icon/microphone-solid.svg create mode 100644 src/assets/icon/microphone-white.svg delete mode 100644 src/assets/icon/microphone.svg create mode 100644 src/assets/icon/pause-white.svg create mode 100644 src/assets/icon/pencil-white1.svg create mode 100644 src/assets/icon/practitest.png create mode 100644 src/assets/icon/practitest.svg create mode 100644 src/assets/icon/qtest.png create mode 100644 src/assets/icon/qtest.svg create mode 100644 src/assets/icon/stop-white.svg create mode 100644 src/assets/icon/testrail.png create mode 100644 src/assets/icon/testrail.svg create mode 100644 src/assets/icon/union.svg create mode 100644 src/assets/icon/video-slash-solid.svg create mode 100644 src/assets/icon/video-solid.svg create mode 100644 src/assets/icon/video-white.svg delete mode 100644 src/assets/icon/video.svg create mode 100644 src/assets/icon/yattie.png create mode 100644 src/assets/icon/yattie.svg create mode 100644 src/components/__tests__/CheckTaskWrapper.spec.js create mode 100644 src/components/__tests__/MindmapEditor.spec.js create mode 100644 src/components/authentication/SigninWrapper.vue create mode 100644 src/components/authentication/Signup1Wrapper.vue create mode 100644 src/components/authentication/Signup2Wrapper.vue create mode 100644 src/components/authentication/Signup3Wrapper.vue create mode 100644 src/components/dialogs/SummaryDialog.vue create mode 100644 src/components/dialogs/__tests__/EndSessionDialog.spec.js create mode 100644 src/components/dialogs/__tests__/NodeEditDialog.spec.js create mode 100644 src/components/settings/ReportsTab.vue create mode 100644 src/components/settings/__tests__/ConfigCheckListTab.spec.js create mode 100644 src/components/settings/__tests__/ConnectionsTab.spec.js create mode 100644 src/components/settings/__tests__/GeneralTab.spec.js create mode 100644 src/components/settings/__tests__/SupportTab.spec.js create mode 100644 src/components/settings/__tests__/TemplateTab.spec.js create mode 100644 src/layouts/Default.vue create mode 100644 src/layouts/Minimize.vue create mode 100644 src/modules/MenuUtility.js delete mode 100644 src/plugins/svg.js create mode 100644 src/views/AuthenticationView.vue create mode 100644 src/views/MinimizeView.vue create mode 100644 src/views/__tests__/AddSession.spec.js rename src/views/__tests__/{EditView.spec.js => EditSession.spec.js} (91%) delete mode 100644 src/views/__tests__/EditorView.spec.js create mode 100644 src/views/__tests__/SettingView.spec.js diff --git a/package.json b/package.json index 531bb2ea..9f393534 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "yattie", - "version": "0.1.0", + "version": "0.1.1", "private": true, "main": "background.js", "engines": { @@ -27,7 +27,7 @@ "@fortawesome/fontawesome-free": "^6.2.1", "@johmun/vue-tags-input": "^2.1.0", "@tinymce/tinymce-vue": "^3.2.0", - "@toast-ui/vue-image-editor": "^3.15.2", + "tui-image-editor": "^3.15.3", "adm-zip": "^0.5.9", "core-js": "^3.8.3", "d3": "^5.14.2", @@ -39,6 +39,7 @@ "fluent-ffmpeg": "^2.1.2", "lodash": "^4.17.21", "simple-json-db": "^2.0.0", + "sinon": "^15.0.0", "tinymce": "^6.2.0", "uuid": "3.3.3", "v-mask": "^2.3.0", diff --git a/src/App.vue b/src/App.vue index b8c585c5..7f61d7ca 100644 --- a/src/App.vue +++ b/src/App.vue @@ -1,41 +1,28 @@ + diff --git a/src/assets/avatar.png b/src/assets/avatar.png new file mode 100644 index 0000000000000000000000000000000000000000..737cf25b0190e86069161f0f9a3876f3073455ad GIT binary patch literal 5428 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 zue + + diff --git a/src/assets/icon/expand.svg b/src/assets/icon/expand.svg new file mode 100644 index 00000000..72262a40 --- /dev/null +++ b/src/assets/icon/expand.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/assets/icon/jira.png b/src/assets/icon/jira.png new file mode 100644 index 0000000000000000000000000000000000000000..6c5aa9f2be6907696f67fdafef5a268409571239 GIT binary patch literal 710 zcmV;%0y+JOP)X1^@s6D=Y3@00009a7bBm000XU z000XU0RWnu7ytkO0drDELIAGL9O(c600d`2O+f$vv5yP0NhJMYZ@H#Jvjddp`QWW10jWgP;$j8vw<( zZ|?k z-jD*o_Bq3vyC`mJZUH!p4B|Kr{5t;*wN?Y6dGQ1t2qD~ME|vv_Hz14Oe`Y8&>jNQq zaqDp9oI+$GFh)V7G#IUCKi=#KJGB2I6&N|K1rdpF07*qoM6N<$f>D_?(*OVf literal 0 HcmV?d00001 diff --git a/src/assets/icon/jira.svg b/src/assets/icon/jira.svg new file mode 100644 index 00000000..612e4c42 --- /dev/null +++ b/src/assets/icon/jira.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/src/assets/icon/microphone-slash-solid.svg b/src/assets/icon/microphone-slash-solid.svg new file mode 100644 index 00000000..b69e019e --- /dev/null +++ b/src/assets/icon/microphone-slash-solid.svg @@ -0,0 +1,10 @@ + + + +Created with Fabric.js 4.6.0 + + + + + + \ No newline at end of file diff --git a/src/assets/icon/microphone-solid.svg b/src/assets/icon/microphone-solid.svg new file mode 100644 index 00000000..8028507e --- /dev/null +++ b/src/assets/icon/microphone-solid.svg @@ -0,0 +1,10 @@ + + + +Created with Fabric.js 4.6.0 + + + + + + \ No newline at end of file diff --git a/src/assets/icon/microphone-white.svg b/src/assets/icon/microphone-white.svg new file mode 100644 index 00000000..eaccc705 --- /dev/null +++ b/src/assets/icon/microphone-white.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/assets/icon/microphone.svg b/src/assets/icon/microphone.svg deleted file mode 100644 index 16c93e0a..00000000 --- a/src/assets/icon/microphone.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/src/assets/icon/pause-white.svg b/src/assets/icon/pause-white.svg new file mode 100644 index 00000000..850db3d6 --- /dev/null +++ b/src/assets/icon/pause-white.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/assets/icon/pencil-white1.svg b/src/assets/icon/pencil-white1.svg new file mode 100644 index 00000000..7cb6e4a0 --- /dev/null +++ b/src/assets/icon/pencil-white1.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/assets/icon/practitest.png b/src/assets/icon/practitest.png new file mode 100644 index 0000000000000000000000000000000000000000..4b9f3e27fdba42deebaf4ba5dc9b831a6dd53cad GIT binary patch literal 1020 zcmVP}H9Dk8;wU1*C~q}CdAQ)2N= zeSuVws;J!A@@y$H`;S)BTi{i5-;mu!yYS|`+iok4a zy*Y%SOT(nj;9wRWCsJ@1*bz&na6Oj5xNgAb(6DCVEG+XB!p6VzW4San$rS8-grO-$ zYlAj%a;3xLu;Jb0M+lw=W*Fe=Nn^{(d1zX*6a_XL7-P9Lm0nT?Aef*vQ%($%Vf?)g zgWKr8AZ<-0fA4VynCMpVS>w(1YlEZu8uI7K}w_yk|qUy z{&^DDo(-!+@@z#pTv|S=7tI2<7y-~GddmIzIIwyS+E;n8Ddpd zKLTb5bFB0_2wiGVWQhIZ!UDYL>xWieUY+FoE1A~KuXm2})hK2@YA!by7 z)2>0a9Wm9&uxVK#dT!nza#C1XTU5Mtb#-vNo!~aoNN}ZdN5?Vbx*kkoclk*|B{7d! z?kX)p|K+oA*zG@N-|cpzwzf9Igj>p4BoaYeTbt5wddPdBC-w%X`bIF<$#7`x68K}c z5jhosj6AEOrlzJ43Wd}xfrQBPe;^P*eSJO3%F5Kma`)9+{9owAMEogE9BD^?^bxA5 zYMS;p?G)Rr!n3&q97O0Kb?VT_E8Qu&#f@AV;k@&vp-Uv5xo zYH4Y~)vMQ3#|X;sG`Mmgq!gB#)8x2lK>)3XTTv7!Qj)QsUDA@}@s2RgoH+|a=-+J9 zpcc)VrlF#;65F!1VmH@mHXKI=%o-OzbzGp1!pJ0000~ literal 0 HcmV?d00001 diff --git a/src/assets/icon/practitest.svg b/src/assets/icon/practitest.svg new file mode 100644 index 00000000..76ef7b1d --- /dev/null +++ b/src/assets/icon/practitest.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/src/assets/icon/qtest.png b/src/assets/icon/qtest.png new file mode 100644 index 0000000000000000000000000000000000000000..6c5e5f4b336ac62e41fe4d3b25c5035d50407911 GIT binary patch literal 662 zcmV;H0%`q;P)1z?#;9#Ang|g+L|f1zN);j!%O!<=@7=H-dTdly;zxoyWQ| zf$cpXZ=1}A_v#^J`h~DC)vC1IEm$rFYs(Ah@E(2QB6{%LzsY=bCeg!V;yfQ&wj;Atw#CjY&O>PlYE^LL zDta?w)zRFL*$*>ugo*CvxcCkCMjxj1v&D&Z=|1}8<%Z4Hkay#UY*y#WcAC1c@Bd2X z!}~DXw6UCsE^>#c(6d!nh(&oRR;BqL)ZBFvnr8TPII%`_B-Tf0!h~JvSR<9*8>@@H zvRermWwEbL;(dJGC=R}Rjq2WkI(#PNIECuZ1>^0zeZtT~RDMNIa&!bsWG(39qjg!G zN3>tw(Jmq(doLeBdLQ~gF8Dn+^#)m?EOG5e(uhXs#+>>!ApfFDZj*GBOsd{KV$9qu zZ9@*AvO~f@c$N);99SPZC4{GMqK7WfE>vF*oxd(EpwUyj7Z32>PQzS53d6j#4!@sB wUvWcO;Xk2vf`KFD%jtriok7{lkJY#Q0VqA8-zd??NB{r;07*qoM6N<$g3l%^(f|Me literal 0 HcmV?d00001 diff --git a/src/assets/icon/qtest.svg b/src/assets/icon/qtest.svg new file mode 100644 index 00000000..f900d4b4 --- /dev/null +++ b/src/assets/icon/qtest.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/src/assets/icon/stop-white.svg b/src/assets/icon/stop-white.svg new file mode 100644 index 00000000..c1887907 --- /dev/null +++ b/src/assets/icon/stop-white.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/assets/icon/testrail.png b/src/assets/icon/testrail.png new file mode 100644 index 0000000000000000000000000000000000000000..dae6f408296d646265786e71e6bbb1a7e080fdb8 GIT binary patch literal 684 zcmV;d0#p5oP)P0018d1^@s660l}|00009a7bBm000XU z000XU0RWnu7ytkO0drDELIAGL9O(c600d`2O+f$vv5yP5tX4Sg8~&UKRWU6tv#Fi3bnrMG(|dQY5KDZ{7qc#I(Km^Q?b?c=OPM zf_PF0w6qlwPol+Uvzy(S=ge+5-A#x@)0Q6cf%*OBedoOy2B1fe-2$5@vd@a+-&*VR16$RLYK5$yj3b(=Nyljz5=F1#((bIdh{LkJE=%U=VwQLqW2hq4aLjK z6O;9s2bJLM;AOztBp`-+2=JqI)-QGL7`ZW(gw0(e3*Kq+j6gpt?usIBwaDj)(VNwjW zjijMV1ph|(XSZEVi7?Bm2H}~uHxObyYQamoLKB=O%b43NAVIYkaq^q^Vr7j_U-3wenz04UtJ=X!*nl2A_JBW*sm)c0 S+Rz>V0000 + + + + + + + + diff --git a/src/assets/icon/union.svg b/src/assets/icon/union.svg new file mode 100644 index 00000000..874e20e6 --- /dev/null +++ b/src/assets/icon/union.svg @@ -0,0 +1,3 @@ + + + diff --git a/src/assets/icon/video-slash-solid.svg b/src/assets/icon/video-slash-solid.svg new file mode 100644 index 00000000..c9c72329 --- /dev/null +++ b/src/assets/icon/video-slash-solid.svg @@ -0,0 +1,10 @@ + + + +Created with Fabric.js 4.6.0 + + + + + + \ No newline at end of file diff --git a/src/assets/icon/video-solid.svg b/src/assets/icon/video-solid.svg new file mode 100644 index 00000000..2050d262 --- /dev/null +++ b/src/assets/icon/video-solid.svg @@ -0,0 +1,10 @@ + + + +Created with Fabric.js 4.6.0 + + + + + + \ No newline at end of file diff --git a/src/assets/icon/video-white.svg b/src/assets/icon/video-white.svg new file mode 100644 index 00000000..3649798e --- /dev/null +++ b/src/assets/icon/video-white.svg @@ -0,0 +1,4 @@ + + + + diff --git a/src/assets/icon/video.svg b/src/assets/icon/video.svg deleted file mode 100644 index b66284eb..00000000 --- a/src/assets/icon/video.svg +++ /dev/null @@ -1,4 +0,0 @@ - - - - diff --git a/src/assets/icon/yattie.png b/src/assets/icon/yattie.png new file mode 100644 index 0000000000000000000000000000000000000000..19bce1b9cb7c7aa3edd919fbd8ec1bd720181e22 GIT binary patch literal 424 zcmV;Z0ayNsP)yB84VtvNtw-<%;0eTykh-Zi&|MSd8^3`R0cm5S zo4(|OftfdNet`P!%QZn9WJn(-iFb!J7`X8T&^lAwka=obVh`C-uwK@Z1?buMbG1o0 zWc&eDvdA&EK!q&Chu8va)!vE+lA}$*w$Dm(7M9mSS+J1|qQY+nw_rQLMak_9oyW!m zLpOH5x1vJw&U+&FwfrimAdRl=`eE~oQu)+(Xa+b3Exsqk8j_YyF-*#;SBoZ}+{o{|Z+hpDQ2TW&m+RJ6*z`g)=ly@66 SCRND*0000 + + diff --git a/src/components/AudioWrapper.vue b/src/components/AudioWrapper.vue index a45ba8c0..459e3936 100644 --- a/src/components/AudioWrapper.vue +++ b/src/components/AudioWrapper.vue @@ -98,7 +98,7 @@ diff --git a/src/components/CheckTaskWrapper.vue b/src/components/CheckTaskWrapper.vue index 51e2d0b6..87f077de 100644 --- a/src/components/CheckTaskWrapper.vue +++ b/src/components/CheckTaskWrapper.vue @@ -9,7 +9,7 @@ -
+
@@ -201,7 +201,11 @@ :disabled="status === 'pause'" @click="stopRecordVideo()" > - mdi-video-off + Stop Video Record @@ -242,9 +246,9 @@ @click="startRecordAudio()" > @@ -263,7 +267,11 @@ :disabled="status === 'pause'" @click="stopRecordAudio()" > - mdi-microphone-off + Stop Audio Record @@ -311,6 +319,26 @@ Mind Map + - + + [], + }, selectedItems: { type: Array, default: () => [], }, + configItem: { + type: Object, + default: () => {}, + }, checkedStatusOfPreSessionTask: { type: Boolean, default: () => false, @@ -422,15 +475,30 @@ export default { default: () => {}, }, }, + created() { + try { + audioContext = new AudioContext(); + dest = audioContext.createMediaStreamDestination(); + } catch (e) { + console.log(e); + } + }, watch: { + items: function (newValue) { + this.itemLists = newValue; + }, selectedItems: function (newValue) { this.selected = newValue; }, + configItem: function (newValue) { + this.config = newValue; + }, }, data() { return { sourcePickerDialog: false, noteDialog: false, + summaryDialog: false, deleteConfirmDialog: false, resetConfirmDialog: false, @@ -441,6 +509,8 @@ export default { sources: [], sourceId: "", + itemLists: this.items, + config: this.configItem, audioDevices: [], loaded: false, status: this.$store.state.status, @@ -460,6 +530,10 @@ export default { mounted() { this.$root.$on("close-sourcepickerdialog", this.hideSourcePickerDialog); this.$root.$on("close-notedialog", this.hideNoteDialog); + this.$root.$on("close-summarydialog", () => { + this.summaryDialog = false; + this.endSession(); + }); }, beforeDestroy() { this.$root.$off("close-sourcepickerdialog", this.hideSourcePickerDialog); @@ -509,9 +583,6 @@ export default { this.updateStoreSession(); }, updateStoreSession() { - console.log(` - status: ${this.status}, timer: ${this.timer}, duration: ${this.duration} - `); this.$store.commit("updateSession", { status: this.status, timer: this.timer, @@ -531,6 +602,7 @@ export default { this.$store.commit("setStarted", this.started); this.startInterval(); + this.changeSessionStatus(SESSION_STATUSES.START); const currentPath = this.$router.history.current.path; if (currentPath !== "/main/timeline") { @@ -539,6 +611,7 @@ export default { }, pauseSession() { this.status = SESSION_STATUSES.PAUSE; + this.changeSessionStatus(SESSION_STATUSES.PAUSE); this.stopInterval(); }, resumeSession() { @@ -562,6 +635,7 @@ export default { this.$store.commit("setEnded", this.ended); this.status = SESSION_STATUSES.END; + this.changeSessionStatus(SESSION_STATUSES.END); this.stopInterval(); if (window.ipc) { @@ -580,14 +654,17 @@ export default { }, resume() { this.status = SESSION_STATUSES.PAUSE; + this.changeSessionStatus(SESSION_STATUSES.PAUSE); this.timer = this.$store.state.timer; this.updateStoreSession(); + this.removeSummary(); this.$router.push({ path: "/main/timeline" }); }, reset() { this.resetConfirmDialog = false; this.status = SESSION_STATUSES.PENDING; + this.changeSessionStatus(SESSION_STATUSES.PENDING); this.$store.commit("resetState"); try { @@ -610,11 +687,13 @@ export default { proceed() { this.durationConfirmDialog = false; this.status = SESSION_STATUSES.PROCEED; + this.changeSessionStatus(SESSION_STATUSES.PROCEED); this.startInterval(); }, updateStatus(value) { this.status = value; + this.changeSessionStatus(this.status); this.$store.commit("setStatus", this.status); }, async getSourceList() { @@ -653,7 +732,7 @@ export default { }) .then(({ fileName, filePath }) => { const data = { - sessionType: "screenshot", + sessionType: "Screenshot", fileType: "image", fileName: fileName, filePath: filePath, @@ -690,6 +769,9 @@ export default { }, async startRecordVideo() { this.handleStream = (stream) => { + if (this.config.audioCapture && this.audioDevices.length > 0) { + stream.addTrack(dest.stream.getAudioTracks()[0]); + } mediaRecorder = new MediaRecorder(stream, { mimeType: "video/webm;codecs=h264", }); @@ -739,7 +821,7 @@ export default { }) .then(({ fileName, filePath }) => { const data = { - sessionType: "video", + sessionType: "Video", fileType: "video", fileName: fileName, filePath: filePath, @@ -761,21 +843,39 @@ export default { }; try { - const stream = await navigator.mediaDevices.getUserMedia({ + const videoQuality = this.config.videoQuality; + let resolution; + VIDEO_RESOLUTION.map((item) => { + let temp = Object.assign({}, item); + if (temp.type === videoQuality) { + resolution = temp; + } + }); + const constraints = { audio: false, video: { mandatory: { chromeMediaSource: "desktop", chromeMediaSourceId: this.sourceId, - minWidth: 640, - maxWidth: 1920, - minHeight: 480, - maxHeight: 1080, + minWidth: resolution.width, + maxWidth: resolution.width, + minHeight: resolution.height, + maxHeight: resolution.height, }, }, - }); + }; + + if (this.config.audioCapture) { + this.audioDevices = await this.getAudioSources(); + if (this.audioDevices.length > 0) { + await this.setAudio(this.audioDevices); + } + } + + const stream = await navigator.mediaDevices.getUserMedia(constraints); stream.getVideoTracks()[0].applyConstraints({ frameRate: 30 }); + this.handleStream(stream); } catch (e) { console.log(e); @@ -788,6 +888,29 @@ export default { console.log(error); } }, + async getAudioSources() { + return await navigator.mediaDevices.enumerateDevices().then((devices) => { + const audioDevices = devices.filter( + (d) => + d.kind === "audioinput" && + d.deviceId != "communications" && + d.deviceId != "default" + ); + return audioDevices; + }); + }, + async setAudio(source) { + const audioStream = await navigator.mediaDevices.getUserMedia({ + audio: { + deviceId: source.deviceId, + autoGainControl: false, + latency: 0.0, + }, + }); + let audioIn_01 = audioContext.createMediaStreamSource(audioStream); + audioIn_01.connect(dest); + return audioIn_01; + }, async startRecordAudio() { this.setAudioSource = async () => { try { @@ -829,21 +952,23 @@ export default { const blob = new Blob(recordedChunks, { type: "audio/mpeg-3", }); + const buffer = await blob.arrayBuffer(); - const fileName = dayjs().format("YYYY-MM-DD_HH-mm-ss-ms") + ".mp3"; + if (window.ipc) { await window.ipc .invoke(IPC_HANDLERS.CAPTURE, { - func: IPC_FUNCTIONS.CREATE_TEMP_USER_MEDIA, - data: { buffer: buffer, fileName: fileName }, + func: IPC_FUNCTIONS.CREATE_AUDIO, + data: { buffer: buffer }, }) - .then((filePath) => { + .then(({ fileName, filePath }) => { const data = { - sessionType: "audio", + sessionType: "Audio", fileType: "audio", fileName: fileName, filePath: filePath, time: this.timer, + poster: "", }; this.openAddWindow(data); @@ -859,6 +984,18 @@ export default { console.log("Error:", error); }; + // try { + // this.audioDevices = await this.getAudioSources(); + // if (!this.audioDevices.length) { + // this.audioErrorDialog = true; + // return; + // } + // const stream = this.setAudio(this.audioDevices); + // this.handleStream(stream); + // } catch (e) { + // console.log(e); + // } + await navigator.mediaDevices.enumerateDevices().then((devices) => { this.audioDevices = devices.filter( (d) => @@ -888,7 +1025,7 @@ export default { data: { width: 700, height: 800, data: data }, }); }, - async addNote(comment) { + async addNote(value) { const date = dayjs().format("MM/DD/YYYY HH:mm:ss"); const fileName = dayjs().format("YYYY-MM-DD_HH-mm-ss-ms") + ".txt"; @@ -897,16 +1034,16 @@ export default { await window.ipc .invoke(IPC_HANDLERS.CAPTURE, { func: IPC_FUNCTIONS.SAVE_NOTE, - data: { fileName: fileName, comment: comment }, + data: { fileName: fileName, comment: value }, }) .then((filePath) => { let newItem = { id: Date.now(), - sessionType: "note", + sessionType: "Note", fileType: "text", fileName: fileName, filePath: filePath, - comment: comment, + comment: value, time: this.timer, createdAt: date, }; @@ -916,20 +1053,55 @@ export default { this.noteDialog = false; }, + async addSummary(value) { + const date = dayjs().format("MM/DD/YYYY HH:mm:ss"); + + const data = { + id: Date.now(), + sessionType: "Summary", + comment: value, + time: this.timer, + createdAt: date, + }; + + this.$emit("add-item", data); + this.summaryDialog = false; + this.endSession(); + }, + async removeSummary() { + let summary = []; + this.items.map((item) => { + if (item.sessionType === "Summary") { + summary.push(item.id); + } + }); + if (window.ipc) { + await window.ipc.invoke(IPC_HANDLERS.DATABASE, { + func: IPC_FUNCTIONS.DELETE_ITEMS, + data: summary, + }); + } + }, mindMap() { const data = { - sessionType: "mindmap", + sessionType: "Mindmap", fileType: "mindmap", fileName: "", filePath: "", content: { - nodes: MAP_NODES, - connections: MAP_CONNECTIONS, + nodes: DEFAULT_MAP_NODES, + connections: DEFAULT_MAP_CONNECTIONS, }, time: this.timer, }; this.openAddWindow(data); }, + async minimize() { + await window.ipc.invoke(IPC_HANDLERS.CAPTURE, { + func: IPC_FUNCTIONS.OPEN_MINIMIZE_WINDOW, + data: { width: 700, height: 800 }, + }); + }, async deleteItems() { if (window.ipc) { await window.ipc.invoke(IPC_HANDLERS.DATABASE, { @@ -973,6 +1145,7 @@ export default { }, discardSession() { this.$store.commit("resetState"); + this.changeSessionStatus(SESSION_STATUSES.PENDING); clearInterval(this.interval); this.$router.push({ path: "/" }); }, @@ -991,6 +1164,12 @@ export default { return currentDateTime; }, + changeSessionStatus(status) { + window.ipc.invoke(IPC_HANDLERS.MENU, { + func: IPC_FUNCTIONS.CHANGE_MENUITEM_STATUS, + data: { sessionStatus: status }, + }); + }, }, }; diff --git a/src/components/FileWrapper.vue b/src/components/FileWrapper.vue index 14db5b82..6e3c6555 100644 --- a/src/components/FileWrapper.vue +++ b/src/components/FileWrapper.vue @@ -27,7 +27,8 @@ export default { }, triggerSave: function (newValue) { if (newValue) { - this.$root.$emit("save-data", this.sessionItem); + this.$root.$emit("update-session", this.sessionItem); + this.$root.$emit("save-data"); } }, }, diff --git a/src/components/ImageEditor.vue b/src/components/ImageEditor.vue index 09e9ce30..350320fe 100644 --- a/src/components/ImageEditor.vue +++ b/src/components/ImageEditor.vue @@ -3,39 +3,20 @@ class="d-flex flex-column" style="width: 100%; height: 100%; row-gap: 10px" > - -
- - Cancel - - - Apply - -
+
+ diff --git a/src/components/authentication/Signup1Wrapper.vue b/src/components/authentication/Signup1Wrapper.vue new file mode 100644 index 00000000..6d797e33 --- /dev/null +++ b/src/components/authentication/Signup1Wrapper.vue @@ -0,0 +1,126 @@ + + + + + diff --git a/src/components/authentication/Signup2Wrapper.vue b/src/components/authentication/Signup2Wrapper.vue new file mode 100644 index 00000000..62dfbf79 --- /dev/null +++ b/src/components/authentication/Signup2Wrapper.vue @@ -0,0 +1,216 @@ + + + + diff --git a/src/components/authentication/Signup3Wrapper.vue b/src/components/authentication/Signup3Wrapper.vue new file mode 100644 index 00000000..ef4e872b --- /dev/null +++ b/src/components/authentication/Signup3Wrapper.vue @@ -0,0 +1,148 @@ + + + + diff --git a/src/components/dialogs/EndSessionDialog.vue b/src/components/dialogs/EndSessionDialog.vue index d1759d72..625b4149 100644 --- a/src/components/dialogs/EndSessionDialog.vue +++ b/src/components/dialogs/EndSessionDialog.vue @@ -3,7 +3,7 @@ @@ -11,7 +11,7 @@ End Session @@ -35,6 +35,11 @@ export default { default: () => {}, }, }, + computed: { + tasks() { + return this.postSessionData ? this.postSessionData.tasks : []; + }, + }, data() { return { showTaskError: false, diff --git a/src/components/dialogs/NodeEditDialog.vue b/src/components/dialogs/NodeEditDialog.vue index c98d34f6..e068eaa2 100644 --- a/src/components/dialogs/NodeEditDialog.vue +++ b/src/components/dialogs/NodeEditDialog.vue @@ -8,7 +8,7 @@ @@ -48,7 +48,7 @@ export default { return { text: "", valid: false, - textRules: [(v) => !!v || "Title is required"], + textRules: [(v) => !!v || "Node title is required"], }; }, methods: { diff --git a/src/components/dialogs/NoteDialog.vue b/src/components/dialogs/NoteDialog.vue index bfca1f8d..8cb367a9 100644 --- a/src/components/dialogs/NoteDialog.vue +++ b/src/components/dialogs/NoteDialog.vue @@ -4,7 +4,7 @@ Take a Note - + {}, + }, + }, + watch: { + configItem: function (newValue) { + this.config = newValue; + + // set comment type by config + if (this.config.commentType && this.config.commentType !== "") { + this.comment.type = this.config.commentType; + } + + // set templates by config + this.config.templates.map((item) => { + let temp = Object.assign({}, item); + if (temp.type === "Note") { + this.comment.content = temp.precondition.content; + this.comment.text = temp.precondition.text; + } + }); + }, + }, data() { return { + config: this.configItem, comment: { - type: "Comment", + type: + this.conifgItem && + this.configItem.commentType && + this.configItem.commentType !== "" + ? this.configItem.commentType + : "Comment", content: "", text: "", tags: [], }, - commentTypes: TEXT_TYPES, + commentTypes: TEXT_TYPES.filter((item) => item !== "Summary"), tag: "", tags: [], }; @@ -116,7 +146,7 @@ export default { this.$root.$emit("close-notedialog"); }, handleSave() { - this.$emit("submit-note", this.comment); + this.$emit("submit-comment", this.comment); }, handleClear() { this.comment.type = "Comment"; diff --git a/src/components/dialogs/SummaryDialog.vue b/src/components/dialogs/SummaryDialog.vue new file mode 100644 index 00000000..b5753feb --- /dev/null +++ b/src/components/dialogs/SummaryDialog.vue @@ -0,0 +1,145 @@ + + + + + diff --git a/src/components/dialogs/__tests__/EndSessionDialog.spec.js b/src/components/dialogs/__tests__/EndSessionDialog.spec.js new file mode 100644 index 00000000..66c4fda1 --- /dev/null +++ b/src/components/dialogs/__tests__/EndSessionDialog.spec.js @@ -0,0 +1,73 @@ +import Vuetify from "vuetify"; + +import CheckTaskWrapper from "../../CheckTaskWrapper.vue"; +import EndSessionDialog from "../EndSessionDialog.vue"; + +import { mount, createLocalVue } from "@vue/test-utils"; + +let vuetify; +let wrapper; +let localVue; + +describe("EndSessionDialog.vue", () => { + beforeEach(() => { + const rootDiv = document.createElement("div"); + rootDiv.id = "root"; + document.body.appendChild(rootDiv); + + localVue = createLocalVue(); + vuetify = new Vuetify(); + + const App = localVue.component("App", { + components: { EndSessionDialog }, + data() { + return { + dialog: false, + showTaskError: false, + }; + }, + template: ` + + + + `, + }); + + wrapper = mount(App, { + localVue, + vuetify, + attachTo: "#root", + }); + }); + + test("render a dialog", async () => { + wrapper.setData({ + dialog: true, + }); + + await wrapper.vm.$nextTick(); + + expect(wrapper.findComponent(CheckTaskWrapper).exists()).toBe(true); + expect(wrapper.find(".btn-end").exists()).toBe(true); + }); + + test('trigger the click event of "End Session" button', async () => { + wrapper.setData({ + dialog: true, + }); + + await wrapper.vm.$nextTick(); + + const button = wrapper.find(".btn-end"); + const event = jest.fn(); + + button.vm.$on("click", event); + button.trigger("click"); + + expect(event).toHaveBeenCalled(); + }); +}); diff --git a/src/components/dialogs/__tests__/NodeEditDialog.spec.js b/src/components/dialogs/__tests__/NodeEditDialog.spec.js new file mode 100644 index 00000000..926165ce --- /dev/null +++ b/src/components/dialogs/__tests__/NodeEditDialog.spec.js @@ -0,0 +1,86 @@ +import Vuetify from "vuetify"; +import LogoWrapper from "../../LogoWrapper.vue"; +import NodeEditDialog from "../NodeEditDialog.vue"; + +import { mount, createLocalVue } from "@vue/test-utils"; + +let vuetify; +let wrapper; +let localVue; + +describe("NodeEditDialog.vue", () => { + beforeEach(() => { + const rootDiv = document.createElement("div"); + rootDiv.id = "root"; + document.body.appendChild(rootDiv); + + localVue = createLocalVue(); + vuetify = new Vuetify(); + + const App = localVue.component("App", { + components: { NodeEditDialog }, + data() { + return { + dialog: false, + }; + }, + template: ` + + + + `, + }); + + wrapper = mount(App, { + localVue, + vuetify, + attachTo: "#root", + }); + }); + + test("render a dialog", async () => { + wrapper.setData({ dialog: true }); + + await wrapper.vm.$nextTick(); + + expect(wrapper.findComponent(LogoWrapper).exists()).toBe(true); + expect(wrapper.find("form").exists()).toBe(true); + expect(wrapper.find("form input").exists()).toBe(true); + + expect(wrapper.findAll("button").length).toBe(2); + expect(wrapper.find("button:first-child").text()).toContain("Save"); + expect(wrapper.find("button:last-child").text()).toContain("Cancel"); + }); + + test('trigger the click event of "Save" button', async () => { + wrapper.setData({ dialog: true }); + + await wrapper.vm.$nextTick(); + + const button = wrapper.find("button:first-child"); + const event = jest.fn(); + + button.vm.$on("click", event); + button.trigger("click"); + + expect(event).toHaveBeenCalled(); + }); + + test('trigger the click event of "Cancel" button', async () => { + wrapper.setData({ dialog: true }); + + await wrapper.vm.$nextTick(); + + const button = wrapper.find("button:last-child"); + const event = jest.fn(); + + button.vm.$on("click", event); + button.trigger("click"); + + expect(event).toHaveBeenCalled(); + }); +}); diff --git a/src/components/dialogs/__tests__/NoteDialog.spec.js b/src/components/dialogs/__tests__/NoteDialog.spec.js index 4aabecf2..dd5426ed 100644 --- a/src/components/dialogs/__tests__/NoteDialog.spec.js +++ b/src/components/dialogs/__tests__/NoteDialog.spec.js @@ -20,6 +20,17 @@ describe("NoteDialog.vue", () => { const App = localVue.component("App", { components: { NoteDialog }, + propsData: { + configItem: { + commentType: "", + templates: [ + { + precondition: { comment: "", text: "" }, + type: "Note", + }, + ], + }, + }, data() { return { dialog: false, diff --git a/src/components/settings/ConfigCheckListTab.vue b/src/components/settings/ConfigCheckListTab.vue index a50f1001..536303dc 100644 --- a/src/components/settings/ConfigCheckListTab.vue +++ b/src/components/settings/ConfigCheckListTab.vue @@ -1,6 +1,9 @@ diff --git a/src/components/settings/GeneralTab.vue b/src/components/settings/GeneralTab.vue index 0c7a064b..f1896466 100644 --- a/src/components/settings/GeneralTab.vue +++ b/src/components/settings/GeneralTab.vue @@ -1,12 +1,12 @@ @@ -168,7 +134,7 @@ export default { content: "", text: "", }, - commentTypes: TEXT_TYPES, + commentTypes: TEXT_TYPES.filter((item) => item !== "Summary"), }; }, methods: { diff --git a/src/components/settings/ReportsTab.vue b/src/components/settings/ReportsTab.vue new file mode 100644 index 00000000..e754123c --- /dev/null +++ b/src/components/settings/ReportsTab.vue @@ -0,0 +1,85 @@ + + + + diff --git a/src/components/settings/TemplateTab.vue b/src/components/settings/TemplateTab.vue index bb143fd1..4b2bac2f 100644 --- a/src/components/settings/TemplateTab.vue +++ b/src/components/settings/TemplateTab.vue @@ -1,9 +1,14 @@