Skip to content

Commit 3f8a93a

Browse files
Shanon LeeShanon Lee
authored andcommitted
Fix bugs in SaveProjectComponent: Remove remote module, replace this. (deprecated in Vue3) with corresponding action/mutation
1 parent 06ff88d commit 3f8a93a

File tree

8 files changed

+220
-4
lines changed

8 files changed

+220
-4
lines changed

package-lock.json

Lines changed: 11 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
"lodash.clonedeep": "^4.5.0",
2727
"lodash.isequal": "^4.5.0",
2828
"lodash.throttle": "^4.1.1",
29+
"mousetrap": "^1.6.5",
2930
"quasar": "^2.0.0",
3031
"quasar-dotenv": "^1.0.5",
3132
"vue-draggable-resizable": "^2.3.0",

src-electron/electron-main.js

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,12 +38,18 @@ if (process.env.PROD) {
3838
});
3939
}
4040

41-
// ******************* Handling dialogs for ExportProject *********************
41+
// Handle dialogs for ExportProjectComponent
4242
ipcMain.handle('exportProject', async (event, arg) => {
4343
const result = await dialog.showSaveDialog(arg)
4444
return result;
4545
})
4646

47+
// Handle dialogs for SaveProjectComponent
48+
ipcMain.handle('saveProject', async (event, arg) => {
49+
const result = await dialog.showSaveDialog(arg);
50+
return result;
51+
})
52+
4753
// ************** Slack OAuth functions **********************
4854
// Sends request to Slack for User's information,
4955
// then sends user information back to renderer process

src-electron/electron-preload.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ const fs = require('fs-extra');
3737
// fs from fs-extra, used in ExportProject
3838
contextBridge.exposeInMainWorld("fs", {
3939
writeFileSync: (file, data, options) => fs.writeFileSync(file, data, options),
40+
readFileSync: (path, options) => fs.readFileSync(path, options),
4041
existsSync: (data) => fs.existsSync(data),
4142
mkdirSync: (data) => fs.mkdirSync(data)
4243
})
Lines changed: 191 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,191 @@
1+
/* eslint-disable no-unused-vars */
2+
/* eslint-disable no-unused-vars */
3+
<!--
4+
Description:
5+
Displays Save button
6+
Functionality includes: Allows users to save their project as json object
7+
-->
8+
9+
<template>
10+
<q-btn class="export-btn" color="secondary" label="Save" @click="saveProjectJSON" />
11+
</template>
12+
13+
<script>
14+
import localforage from 'localforage'
15+
import { mapActions } from 'vuex';
16+
// import fs from 'fs-extra'
17+
// const { remote } = require('electron')
18+
const Mousetrap = require('mousetrap')
19+
const { fs, ipcRenderer } = window;
20+
21+
// might not be optimal to import like this, since entire slackApiStuff object is imported while only one of its properties is used
22+
export default {
23+
name: 'SaveProjectComponent',
24+
methods: {
25+
// Action to addProject to store before save
26+
...mapActions([
27+
'addProject', //also supports payload `this.nameOfAction(amount)`
28+
]),
29+
30+
// displays save dialog, success calls saveJSONLocation
31+
showSaveJSONDialog () {
32+
// ************** With outdated remote package ***************
33+
// remote.dialog.showSaveDialog({
34+
// title: 'Choose location to save JSON object in',
35+
// // defaultPath: remote.app.getPath('desktop'),
36+
// message: 'Choose location to save JSON object in',
37+
// nameFieldLabel: 'Application State Name',
38+
// filters: [{
39+
// name: 'JSON Files',
40+
// extensions: ['json']
41+
// }]
42+
// },
43+
// result => {
44+
// this.saveJSONLocation(result)
45+
// })
46+
47+
// ************ New, with ipcRenderer and ipcMain *****************
48+
ipcRenderer.invoke('saveProject', {
49+
title: 'Choose location to save JSON object in',
50+
message: 'Choose location to save JSON object in',
51+
nameFieldLabel: 'Application State Name',
52+
filters: [{
53+
name: 'JSON Files',
54+
extensions: ['json']
55+
}]
56+
})
57+
.then(res => this.saveJSONLocation(res.filePath))
58+
.catch(err => console.log(err))
59+
},
60+
// returns location of where file is stored
61+
parseFileName (file) {
62+
// 'asdf/asdff/sdf.txt -> sdf.txt
63+
if (file) return file.split('/').pop()
64+
},
65+
// deletes anything attached to html element
66+
parseAndDelete (htmlList) {
67+
// console.log('htmlList in saveProjectComp: ', htmlList)
68+
htmlList.forEach(element => {
69+
if (!Array.isArray(element.children)) console.log('This should be an array', element.children)
70+
if (element.children.length > 0) {
71+
// console.log('in recurse')
72+
this.parseAndDelete(element.children)
73+
}
74+
delete element._vm
75+
delete element.parent
76+
delete element.open
77+
delete element.active
78+
delete element.style
79+
delete element.class
80+
delete element.innerStyle
81+
delete element.innerClass
82+
delete element.innerBackStyle
83+
delete element.innerBackClass
84+
})
85+
},
86+
// displays save dialog
87+
saveProjectJSON () {
88+
this.showSaveJSONDialog()
89+
},
90+
// saves where JSON object is stored in state
91+
saveJSONLocation (data) {
92+
// delete original key from local forage
93+
let deleteKey = this.$store.state.projects[this.$store.state.activeTab].filename
94+
localforage
95+
.removeItem(deleteKey)
96+
.then(function () {
97+
// console.log(deleteKey, 'Key is cleared!')
98+
})
99+
.catch(function (err) {
100+
// console.log(err)
101+
})
102+
103+
let fileName = this.parseFileName(data)
104+
// if valid fileName
105+
if (fileName) {
106+
// $set is not available in Vue3
107+
// this.$set(this.$store.state.projects, this.$store.state.activeTab, {
108+
// filename: fileName,
109+
// lastSavedLocation: data
110+
// })
111+
112+
// Modified to remove use of this.$set, no longer needed in Vue3
113+
this.addProject({
114+
filename: fileName,
115+
lastSavedLocation: data
116+
})
117+
118+
let state = this.$store.state
119+
let routes = state.routes
120+
console.log(state);
121+
122+
// for each route call parseAndDelete on htmlList
123+
// eslint-disable-next-line no-unused-vars
124+
for (let view in routes) {
125+
// console.log('views in Routes', routes[view])
126+
routes[view].forEach(component => {
127+
let htmlList = component.htmlList
128+
this.parseAndDelete(htmlList)
129+
})
130+
}
131+
let componentMap = this.$store.state.componentMap
132+
// eslint-disable-next-line no-unused-vars
133+
for (let component in componentMap) {
134+
if (component.htmlList) {
135+
let comphtml = component.htmlList
136+
this.parseAndDelete(comphtml)
137+
}
138+
}
139+
140+
fs.writeFileSync(data, JSON.stringify(state))
141+
localforage
142+
.setItem(fileName, JSON.parse(fs.readFileSync(data, 'utf8')))
143+
// .then(result => {
144+
// console.log('saved ', fileName, 'to local forage')
145+
// console.log('result is', result)
146+
// })
147+
148+
// console.log('PROJECT SAVED AS A JSON OBJECT!')
149+
localforage.getItem('slackWebhookURL', (err, value) => {
150+
// TODO: handle error
151+
console.log('error: ', err)
152+
// console.log('slackWebhookURL: ', value)
153+
if (value) this.notifySlack(fileName, value)
154+
})
155+
}
156+
},
157+
// creates a popup dialog box, where if you click on yes, it will send a message to our test Slack workspace
158+
notifySlack (fileName, url) {
159+
// TODO: add feature to store slack user's name into local memory here if we decide to
160+
161+
remote.dialog.showMessageBox({
162+
title: 'Notify Slack?',
163+
message: 'Save successful. Would you like to notify your team on Slack?',
164+
buttons: ['No', 'Yes'],
165+
defaultId: 1
166+
},
167+
response => {
168+
if (response === 1) {
169+
fetch(url, {
170+
method: 'POST',
171+
body: JSON.stringify({ 'text': `A team member has saved an OverVue project file: ${fileName}` }),
172+
headers: { 'Content-Type': 'application/json' }
173+
})
174+
}
175+
})
176+
}
177+
},
178+
// on components creation these key presses will trigger save project
179+
created () {
180+
Mousetrap.bind(['command+s', 'ctrl+s'], () => {
181+
this.saveProjectJSON()
182+
})
183+
}
184+
}
185+
</script>
186+
187+
<style scoped>
188+
.mr-sm {
189+
margin-right: 2px;
190+
}
191+
</style>

src/layouts/MyLayout.vue

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ Description:
4040
></i>
4141
<i v-else class="fa fa-forward" id="unavailable" aria-hidden="true"></i> -->
4242
<!-- <OpenProjectComponent /> -->
43-
<!-- <SaveProjectComponent /> -->
43+
<SaveProjectComponent />
4444
<ExportProjectComponent />
4545
<!-- </div> -->
4646
<!-- this button will open the right drawer -->
@@ -106,7 +106,7 @@ Description:
106106
// HomeSideDropDown contains RouteDisplay, VuexForm and Edit but we'll be separating these components across different tabs
107107
import Dashboard from "../components/dashboard_items/Dashboard.vue";
108108
import ExportProjectComponent from "../components/file_system_interface/ExportProject.vue";
109-
// import SaveProjectComponent from "../components/file_system_interface/SaveProjectComponent.vue";
109+
import SaveProjectComponent from "../components/file_system_interface/SaveProjectComponent.vue";
110110
// import OpenProjectComponent from "../c omponents/file_system_interface/OpenProjectComponent.vue";
111111
// import UploadImage from "../components/home_sidebar_items/UploadImage.vue";
112112
import SlackLoginWindow from "../components/slack_login/SlackLoginWindow.vue";
@@ -128,7 +128,7 @@ export default {
128128
// VuexForm,
129129
Dashboard,
130130
ExportProjectComponent,
131-
// SaveProjectComponent,
131+
SaveProjectComponent,
132132
// OpenProjectComponent,
133133
// UploadImage,
134134
SlackLoginWindow,

src/store/actions.js

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -275,6 +275,11 @@ const actions = {
275275
commit(types.SET_ROUTES, payload.routes)
276276
},
277277

278+
// Add project
279+
[types.addProject]: ({ commit }, payload) => {
280+
commit(types.ADD_PROJECT, payload)
281+
},
282+
278283
// end of loading///////////////////////////////////////////////////
279284
}
280285

src/store/mutations.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -656,6 +656,7 @@ const mutations = {
656656

657657
[types.ADD_PROJECT]: (state, payload) => {
658658
// console.log('PUSHING ', payload)
659+
state.projects = [];
659660
state.projects.push(payload)
660661
state.projectNumber++
661662
},

0 commit comments

Comments
 (0)