diff --git a/.eslintrc.js b/.eslintrc.js index aed0e546..ddd93d07 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -17,7 +17,7 @@ module.exports = { rules: { "no-console": process.env.NODE_ENV === "production" ? "warn" : "off", - "no-debugger": process.env.NODE_ENV === "production" ? "warn" : "off", + "no-debugger": process.env.NODE_ENV === "production" ? "warn" : "off", "prettier/prettier": ["error", { endOfLine: "auto" }], }, diff --git a/package.json b/package.json index d1ebed90..310009d0 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "yattie", - "version": "0.4.2", + "version": "0.4.3", "private": true, "main": "background.js", "engines": { diff --git a/src/background.js b/src/background.js index 95ce19df..4c6ae817 100644 --- a/src/background.js +++ b/src/background.js @@ -32,7 +32,9 @@ async function createWindow() { if (process.env.WEBPACK_DEV_SERVER_URL) { // Load the url of the dev server if in development mode await win.loadURL(process.env.WEBPACK_DEV_SERVER_URL); - if (!process.env.IS_TEST) win.webContents.openDevTools(); + if (isDevelopment){ + win.webContents.openDevTools(); + } } else { createProtocol("app"); // Load the index.html when not in development diff --git a/src/components/CheckTaskWrapper.vue b/src/components/CheckTaskWrapper.vue index e1988afe..7fe7a4fb 100644 --- a/src/components/CheckTaskWrapper.vue +++ b/src/components/CheckTaskWrapper.vue @@ -46,7 +46,7 @@ export default { if (this.type === "preseesion") { return { title: this.$tc("caption.required_checkbox", 1), - description: this.$t("message.select_presesion_task"), + description: this.$t("message.select_presession_task"), }; } else { return { diff --git a/src/components/ControlPanel.vue b/src/components/ControlPanel.vue index 75940d19..3f6b4c0d 100644 --- a/src/components/ControlPanel.vue +++ b/src/components/ControlPanel.vue @@ -21,6 +21,20 @@ + {{ $tc("caption.start_quick_test", 1) }} + + - {{ $tc("caption.start_new_session", 1) }} + {{ $tc("caption.start_session", 1) }} @@ -416,16 +430,21 @@ v-model="resetConfirmDialog" :title="$tc('caption.confirm_reset', 1)" :text="$t('message.confirm_reset')" - @confirm="reset" + @confirm="resetSession" @cancel="resetConfirmDialog = false" /> + { + this.callback = () => this.clearSession(); + this.newSessionDialog = true; + }); + + // save session + window.ipc.on("SAVE_SESSION", () => { + this.saveSession(() => (this.saveConfirmDialog = true)); + }); + + // reset session + window.ipc.on("RESET_SESSION", () => { + this.resetConfirmDialog = true; + }); + this.$root.$on("close-sourcepickerdialog", this.hideSourcePickerDialog); this.$root.$on("close-notedialog", this.hideNoteDialog); this.$root.$on("close-summarydialog", () => { @@ -601,7 +667,7 @@ export default { if ( this.$store.state.status === SESSION_STATUSES.START || - this.$store.state.status === SESSION_STATUSES.PAUSE || + this.$store.state.status === SESSION_STATUSES.PROCEED || this.$store.state.status === SESSION_STATUSES.RESUME ) { this.status = this.$store.state.status; @@ -610,8 +676,15 @@ export default { if (this.$store.state.status === SESSION_STATUSES.START) { this.startSession(this.sourceId); } + this.startInterval(); } + if ( + this.$store.state.quickTest && + this.$store.state.status === SESSION_STATUSES.PENDING + ) { + this.showSourcePickerDialog(); + } this.bindIPCEvent(); }, beforeDestroy() { @@ -754,21 +827,25 @@ export default { this.noteDialog = false; }, startInterval() { - this.interval = setInterval(() => { - this.timer += 1; - if (this.duration > 0) { - this.duration -= 1; - } - this.updateStoreSession(); - if (this.isDuration && this.duration === 0) { - this.durationConfirmDialog = true; - this.isDuration = false; - this.stopInterval(); - } - }, 1000); + console.log("start interval"); + if (!this.interval) { + this.interval = setInterval(() => { + this.timer += 1; + if (this.duration > 0) { + this.duration -= 1; + } + this.updateStoreSession(); + if (this.isDuration && this.duration === 0) { + this.durationConfirmDialog = true; + this.isDuration = false; + this.stopInterval(); + } + }, 1000); + } }, stopInterval() { clearInterval(this.interval); + this.interval = null; this.updateStoreSession(); }, updateStoreSession() { @@ -847,8 +924,6 @@ export default { data: { width: 1440, height: 900, - minWidth: 1440, - minHeight: 900, }, }); } @@ -897,27 +972,22 @@ export default { } }, resume() { - this.status = SESSION_STATUSES.PAUSE; - this.changeSessionStatus(SESSION_STATUSES.PAUSE); + this.pauseSession(); this.timer = this.$store.state.timer; this.updateStoreSession(); - this.$router.push({ path: "/main/workspace" }); - }, - reset() { - this.resetConfirmDialog = false; - this.status = SESSION_STATUSES.PENDING; - this.changeSessionStatus(SESSION_STATUSES.PENDING); - this.$store.commit("resetState"); - try { - // reset database - window.ipc.invoke(IPC_HANDLERS.DATABASE, { - func: IPC_FUNCTIONS.INITIALIZE_SESSION, + const currentPath = this.$router.history.current.path; + if (currentPath !== "/main/workspace") { + this.$router.push({ path: "/main/workspace" }); + } + if (window.ipc) { + window.ipc.invoke(IPC_HANDLERS.WINDOW, { + func: IPC_FUNCTIONS.SET_WINDOW_SIZE, + data: { + width: 800, + height: 600, + }, }); - } catch (e) { - console.log(e); } - this.stopInterval(); - this.$router.push({ path: "/main" }); }, end() { this.durationConfirmDialog = false; @@ -1242,7 +1312,7 @@ export default { data: { width: 700, height: 800, data: data }, }); }, - async addNote(value) { + async addNote({ comment, tags }) { const date = dayjs().format("MM/DD/YYYY HH:mm:ss"); const fileName = dayjs().format("YYYY-MM-DD_HH-mm-ss-ms") + ".txt"; if (window.ipc) { @@ -1250,7 +1320,7 @@ export default { await window.ipc .invoke(IPC_HANDLERS.CAPTURE, { func: IPC_FUNCTIONS.SAVE_NOTE, - data: { fileName: fileName, comment: value }, + data: { fileName: fileName, comment: comment }, }) .then((filePath) => { let newItem = { @@ -1259,7 +1329,8 @@ export default { fileType: "text", fileName: fileName, filePath: filePath, - comment: value, + comment: comment, + tags: tags, time: this.timer, createdAt: date, }; @@ -1345,7 +1416,7 @@ export default { this.selected = []; this.$root.$emit("update-selected", this.selected); }, - async saveSession() { + async saveSession(callback = null) { this.newSessionDialog = false; const data = { title: this.$store.state.title, @@ -1356,19 +1427,95 @@ export default { timer: this.$store.state.timer, started: this.$store.state.started, ended: this.$store.state.ended, + quickTest: this.$store.state.quickTest, path: this.$route.path, }; if (!window.ipc) return; - await window.ipc.invoke(IPC_HANDLERS.FILE_SYSTEM, { - func: IPC_FUNCTIONS.SAVE_SESSION, - data: data, - }); + await window.ipc + .invoke(IPC_HANDLERS.FILE_SYSTEM, { + func: IPC_FUNCTIONS.SAVE_SESSION, + data: data, + }) + .then(() => { + if (callback) { + callback(); + } + }); }, - discardSession() { - this.$store.commit("resetState"); + discardSession(callback = null) { + this.newSessionDialog = false; + if (callback) { + callback(); + } + }, + async clearSession() { + console.log("clear session"); + this.$root.$emit("new-session"); + + this.status = SESSION_STATUSES.PENDING; this.changeSessionStatus(SESSION_STATUSES.PENDING); - clearInterval(this.interval); - this.$router.push({ path: "/" }); + + this.timer = 0; + this.isDuration = false; + this.duration = 0; + + this.$store.commit("clearState"); + + if (!window.ipc) return; + await window.ipc + .invoke(IPC_HANDLERS.DATABASE, { + func: IPC_FUNCTIONS.RESET_DATA, + }) + .then(() => { + window.ipc.invoke(IPC_HANDLERS.WINDOW, { + func: IPC_FUNCTIONS.SET_WINDOW_SIZE, + data: { + width: 800, + height: 600, + }, + }); + this.stopInterval(); + // const currentPath = this.$router.history.current.path; + // if (currentPath !== "/main") { + // this.$router.push({ path: "/main" }); + // } + }); + }, + async resetSession() { + if (this.resetConfirmDialog) { + this.resetConfirmDialog = false; + } + + this.$root.$emit("reset-duration"); + + this.status = SESSION_STATUSES.PENDING; + this.changeSessionStatus(SESSION_STATUSES.PENDING); + + this.timer = 0; + this.isDuration = false; + this.duration = 0; + + this.$store.commit("resetState"); + + if (!window.ipc) return; + await window.ipc + .invoke(IPC_HANDLERS.DATABASE, { + func: IPC_FUNCTIONS.RESET_DATA, + }) + .then(() => { + window.ipc.invoke(IPC_HANDLERS.WINDOW, { + func: IPC_FUNCTIONS.SET_WINDOW_SIZE, + data: { + width: 800, + height: 600, + }, + }); + this.stopInterval(); + const currentPath = this.$router.history.current.path; + if (currentPath !== "/main") { + this.$router.push({ path: "/main" }); + } + }); }, getCurrentDateTime() { const now = new Date(); @@ -1412,7 +1559,7 @@ export default { .nml-ctrl-wrapper .control-btn-wrapper { background: #f3f4f6; } -.nml-ctrl-wrapper .v-btn--disabled img { +.v-btn--disabled img { opacity: 0.5; } diff --git a/src/components/ReviewWrapper.vue b/src/components/ReviewWrapper.vue index 27af90bf..1e50f345 100644 --- a/src/components/ReviewWrapper.vue +++ b/src/components/ReviewWrapper.vue @@ -75,7 +75,7 @@ export default { type: String, default: () => "", }, - config: { + configItem: { type: Object, default: () => {}, }, @@ -90,6 +90,9 @@ export default { autoSave: function (newValue) { this.autoSaveEvent = newValue; }, + configItem: function (newValue) { + this.config = newValue; + }, }, data() { return { @@ -97,8 +100,12 @@ export default { triggerSaveEvent: this.triggerSave, autoSaveEvent: this.autoSave, currentViewName: this.currentView, + config: this.configItem, }; }, + mounted() { + console.log(this.config); + }, methods: { handleMindmap(value) { this.sessionItem.content.nodes = value.nodes; diff --git a/src/components/TestWrapper.vue b/src/components/TestWrapper.vue index 3ba04926..6b6b4dd8 100644 --- a/src/components/TestWrapper.vue +++ b/src/components/TestWrapper.vue @@ -157,8 +157,40 @@ export default { duration: "", }; }, - created() {}, - mounted() {}, + watch: { + "$store.state.title": { + deep: true, + handler(newValue) { + this.title = newValue; + }, + }, + "$store.state.charter": { + deep: true, + handler(newValue) { + this.charter.content = newValue.content; + this.charter.text = newValue.text; + }, + }, + "$store.state.precondition": { + deep: true, + handler(newValue) { + this.precondition.content = newValue.content; + this.precondition.text = newValue.text; + }, + }, + "$store.state.mindmap": { + deep: true, + handler(newValue) { + this.mindmap.nodes = newValue.nodes; + this.mindmap.connections = newValue.connections; + }, + }, + }, + mounted() { + this.$root.$on("new-session", () => { + this.duration = ""; + }); + }, methods: { updateTitle() { this.$store.commit("setTitle", this.title); diff --git a/src/components/TimelineWrapper.vue b/src/components/TimelineWrapper.vue index 54db6e60..3a19da9c 100644 --- a/src/components/TimelineWrapper.vue +++ b/src/components/TimelineWrapper.vue @@ -14,8 +14,8 @@ class="timeline-wrap pt-3" @dragenter="dragEnter($event)" @dragleave="dragLeave($event)" - @drop="dropFile($event)" @dragover="dragOver($event)" + @drop="dropFile($event)" > {{ formatTime }} - -
- -
-
-
- mdi-clock-outline - {{ calculateTime(item.time) }} -
-
- -
+
+
+
+ mdi-clock-outline + {{ calculateTime(item.time) }}
-
- +
-
- {{ - item.comment.text - ? item.comment.type + ": " + item.comment.text - : "" - }} - -
- - -
-
-
- mdi-clock-outline - {{ calculateTime(item.time) }} -
-
- -
-
-
+ +
+
+ {{ + item.comment.text + ? item.comment.type + ": " + item.comment.text + : "" + }} + +
+
+ - + {{ tag.text }} + +
+
+
+ +
+
+
+ mdi-clock-outline + {{ calculateTime(item.time) }}
-
- {{ - item.comment.text - ? item.comment.type + ": " + item.comment.text - : "" - }} - +
+
- - -
-
-
- mdi-clock-outline - {{ calculateTime(item.time) }} -
-
- -
-
-
+ +
+
+ {{ + item.comment.text + ? item.comment.type + ": " + item.comment.text + : "" + }} + +
+
+ -
- -
-
- mdi-play-circle -
+ {{ tag.text }} +
+
+
+
+ +
+
+
+ mdi-clock-outline + {{ calculateTime(item.time) }}
-
- {{ - item.comment.text - ? item.comment.type + ": " + item.comment.text - : "" - }} - +
+
- - -
-
-
- mdi-clock-outline - {{ calculateTime(item.time) }} -
-
- -
+
+
+
-
- {{ item.comment.type + ": " + item.comment.text }} - +
+ mdi-play-circle
-
+
+ {{ + item.comment.text + ? item.comment.type + ": " + item.comment.text + : "" + }} + +
+
+ - - {{ tag.text }} - -
+ {{ tag.text }} +
- - -
-
-
- mdi-clock-outline - {{ calculateTime(item.time) }} -
-
- -
+
+ + +
+
+
+ mdi-clock-outline + {{ calculateTime(item.time) }}
-
- +
-
+
+ {{ item.comment.type + ": " + item.comment.text }} + +
+
+ -
- {{ item.fileName }} -
-
- mdi-file -
+ {{ tag.text }} +
+
+
+ + +
+
+
+ mdi-clock-outline + {{ calculateTime(item.time) }}
-
- {{ - item.comment.text - ? item.comment.type + ": " + item.comment.text - : "" - }} - +
+
- - -
-
-
- mdi-clock-outline - {{ calculateTime(item.time) }} -
-
- -
+
+ +
+
+
+ {{ item.fileName }}
-
+ mdi-file +
+
+
+ {{ + item.comment.text + ? item.comment.type + ": " + item.comment.text + : "" + }} + +
+
+ - + {{ tag.text }} + +
+
+ + +
+
+
+ mdi-clock-outline + {{ calculateTime(item.time) }}
-
- {{ - item.comment.text - ? item.comment.type + ": " + item.comment.text - : "" - }} - +
+
- - -
-
-
- mdi-clock-outline - {{ calculateTime(item.time) }} -
-
- -
+
+ +
+
+ {{ + item.comment.text + ? item.comment.type + ": " + item.comment.text + : "" + }} + +
+
+ + {{ tag.text }} + +
+
+ + +
+
+
+ mdi-clock-outline + {{ calculateTime(item.time) }}
-
- {{ item.comment.type + ": " + item.comment.text }} - +
+
- -
- +
+ {{ item.comment.type + ": " + item.comment.text }} + +
+
+
+

@@ -394,7 +433,6 @@ import { VTimelineItem, VBtn, } from "vuetify/lib/components"; -import Draggable from "vuedraggable"; import dayjs from "dayjs"; import { IPC_HANDLERS, IPC_FUNCTIONS, STATUSES } from "../modules/constants"; @@ -409,7 +447,6 @@ export default { VTimeline, VTimelineItem, VBtn, - Draggable, }, props: { items: { @@ -445,6 +482,7 @@ export default { eventName: this.eventType, clicks: 0, isDragging: false, + itemDragging: false, }; }, computed: { @@ -551,46 +589,51 @@ export default { }, dragItem(event, item) { event.preventDefault(); - + this.itemDragging = true; if (!window.ipc) return; - console.log(item); - window.ipc.invoke(IPC_HANDLERS.FILE_SYSTEM, { - func: IPC_FUNCTIONS.DRAG_ITEM, - data: item, - }); + window.ipc + .invoke(IPC_HANDLERS.FILE_SYSTEM, { + func: IPC_FUNCTIONS.DRAG_ITEM, + data: item, + }) + .then(() => { + this.itemDragging = false; + }); }, async dropFile(event) { event.preventDefault(); event.stopPropagation(); + this.isDragging = false; + if (!this.itemDragging) { + if (event.dataTransfer.files.length === 0 || !window.ipc) { + return; + } - if (event.dataTransfer.files.length === 0 || !window.ipc) { - return; - } + const f = event.dataTransfer.files[0]; + const { status, error, result } = await window.ipc.invoke( + IPC_HANDLERS.CAPTURE, + { + func: IPC_FUNCTIONS.DROP_FILE, + data: { + path: f.path, + name: f.name, + }, + } + ); - const f = event.dataTransfer.files[0]; - const { status, error, result } = await window.ipc.invoke( - IPC_HANDLERS.CAPTURE, - { - func: IPC_FUNCTIONS.DROP_FILE, - data: { - path: f.path, - name: f.name, - }, + if (status === STATUSES.ERROR) { + console.log(error); + } else { + const data = { + sessionType: "File", + fileType: result.fileType, + fileName: result.fileName, + filePath: result.filePath, + time: this.$store.state.timer, + }; + this.openEditorModal(data); + this.isDragging = false; } - ); - - if (status === STATUSES.ERROR) { - console.log(error); - } else { - const data = { - sessionType: "File", - fileType: result.fileType, - fileName: result.fileName, - filePath: result.filePath, - time: this.$store.state.timer, - }; - this.openEditorModal(data); - this.isDragging = false; } }, dragEnter(event) { diff --git a/src/components/__tests__/ControlPanel.spec.js b/src/components/__tests__/ControlPanel.spec.js index 8618688b..0a45937d 100644 --- a/src/components/__tests__/ControlPanel.spec.js +++ b/src/components/__tests__/ControlPanel.spec.js @@ -35,7 +35,7 @@ describe("ControlPanel.vue", () => { store = new Vuex.Store(cloneDeep(storeConfig)); }); - test('displays "Start New Session" button', () => { + test('displays "Start Session" button', () => { const wrapper = mount(ControlPanel, { mocks: { $t: () => {}, diff --git a/src/components/__tests__/TextEditor.spec.js b/src/components/__tests__/TextEditor.spec.js deleted file mode 100644 index dc84bc5d..00000000 --- a/src/components/__tests__/TextEditor.spec.js +++ /dev/null @@ -1,63 +0,0 @@ -import { mount } from "@vue/test-utils"; - -import TextEditor from "../TextEditor"; - -describe("TextEditor.vue", () => { - const dataInfo = { - apiKey: "gsamuimia341odbjm3dbaxstm3a8ttjg458ce840htiimyk5", - config: { - selector: "textarea", - plugins: [ - "lists", - "advlist", - "image", - "link", - "code", - "table", - "emoticons", - ], - toolbar: - "block | bold italic formatgroup | forecolor | bullist | link emoticons insertgroup", - block_formats: "Paragraph=p;Header 1=h1;Header 2=h2;Header 3=h3", - font_formats: - "Arial=arial,helvetica,sans-serif;Courier New=courier new,courier,monospace;AkrutiKndPadmini=Akpdmi-n", - toolbar_groups: { - formatgroup: { - icon: "more-drawer", - tooltip: "More rormatting", - items: - "underline strikethrough | superscript subscript | code removeformat", - }, - - insertgroup: { - icon: "plus", - tooltip: "Insert", - items: "code blockquote table hr", - }, - }, - menubar: false, - statusbar: false, - }, - }; - - test("displays label text", () => { - const wrapper = mount(TextEditor, { - mocks: { - $t: () => {}, - $tc: () => {}, - }, - propsData: { - label: "subtitle", - placeholder: "", - content: "", - height: 100, - }, - data() { - return dataInfo; - }, - }); - - expect(wrapper.find(".subtitle-2.label-text")).toBeTruthy(); - expect(wrapper.find(".subtitle-2.label-text").text()).toBe("subtitle"); - }); -}); diff --git a/src/components/dialogs/NoteDialog.vue b/src/components/dialogs/NoteDialog.vue index c5bfce5f..04857f8f 100644 --- a/src/components/dialogs/NoteDialog.vue +++ b/src/components/dialogs/NoteDialog.vue @@ -39,7 +39,7 @@ item !== "Summary"), tag: "", @@ -163,22 +162,24 @@ export default { this.$root.$emit("close-notedialog"); }, handleSave() { - const data = { ...this.comment }; - this.handleClear(); + const data = { + comment: this.comment, + tags: this.tags, + }; this.$emit("submit-comment", data); }, handleClear() { this.comment.type = "Comment"; this.comment.content = ""; this.comment.text = ""; - this.comment.tags = []; + this.tags = []; }, handleComment() { const regex = /(<([^>]+)>)/gi; this.comment.text = this.comment.content.replace(regex, ""); }, handleTags(newTags) { - this.comment.tags = newTags; + this.tags = newTags; }, }, }; diff --git a/src/components/dialogs/SaveConfirmDialog.vue b/src/components/dialogs/SaveConfirmDialog.vue new file mode 100644 index 00000000..615016e1 --- /dev/null +++ b/src/components/dialogs/SaveConfirmDialog.vue @@ -0,0 +1,72 @@ + + + + + diff --git a/src/components/dialogs/SummaryDialog.vue b/src/components/dialogs/SummaryDialog.vue index 67eb507d..18e8db1f 100644 --- a/src/components/dialogs/SummaryDialog.vue +++ b/src/components/dialogs/SummaryDialog.vue @@ -133,7 +133,6 @@ export default { this.isEmpty = true; return; } - this.handleClear(); this.$emit("submit-comment", this.comment); }, handleClear() { diff --git a/src/layouts/Default.vue b/src/layouts/Default.vue index 7ccb4aee..1ac807dd 100644 --- a/src/layouts/Default.vue +++ b/src/layouts/Default.vue @@ -8,7 +8,7 @@