Skip to content

Commit 1a46bdb

Browse files
authored
Merge pull request #42 from Aviral09/dev
Create files and save files features
2 parents 9d5d6ca + 4fe015d commit 1a46bdb

8 files changed

Lines changed: 163 additions & 21 deletions

File tree

src/component/Header.jsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,11 +47,12 @@ const Header = ({ superState, dispatcher }) => {
4747
<section className="toolbar">
4848
{
4949
actions.map(({
50-
text, active, action, icon, type, hotkey,
50+
text, active, visibility, action, icon, type, hotkey,
5151
}, i) => {
5252
const props = {
5353
text,
5454
active,
55+
visibility,
5556
tabIndex: i + 1,
5657
key: text,
5758
action: (e) => action(superState, dispatcher, e),

src/component/HeaderComps.jsx

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,13 @@ import Switch from 'rc-switch';
33
import { Menu, MenuItem, MenuButton } from '@szhsin/react-menu';
44

55
function DropDown({
6-
Icon, text, action, active, tabIndex, hotkey,
6+
Icon, text, action, active, visibility, tabIndex, hotkey,
77
}) {
88
return (
99
<Menu menuButton={(
1010
<MenuButton>
1111
<ActionButton {...{
12-
Icon, text, action, active, tabIndex, hotkey,
12+
Icon, text, action, active, visibility, tabIndex, hotkey,
1313
}}
1414
/>
1515
</MenuButton>
@@ -21,10 +21,10 @@ function DropDown({
2121
}
2222

2323
const FileUploader = ({
24-
Icon, text, active, tabIndex, hotkey, superState,
24+
Icon, text, active, visibility, tabIndex, hotkey, superState,
2525
}) => (
2626
<ActionButton {...{
27-
Icon, text, active, tabIndex, action: () => superState.fileRef.current.click(), hotkey,
27+
Icon, text, active, visibility, tabIndex, action: () => superState.fileRef.current.click(), hotkey,
2828
}}
2929
/>
3030
);
@@ -51,7 +51,7 @@ const Switcher = ({
5151
);
5252

5353
const ActionButton = ({
54-
Icon, text, action, active, tabIndex, hotkey,
54+
Icon, text, action, active, visibility, tabIndex, hotkey,
5555
}) => (
5656
<div
5757
role="button"
@@ -61,6 +61,7 @@ const ActionButton = ({
6161
onClick={() => (active && action())}
6262
onKeyDown={(ev) => active && ev.key === ' ' && action()}
6363
data-tip={hotkey ? hotkey.split(',')[0] : ''}
64+
style={{ display: `${visibility ? '' : 'none'}` }}
6465
>
6566
<div className="icon"><Icon size="20" /></div>
6667
<div style={{ fontSize: 14 }}>{text}</div>

src/component/fileBrowser.jsx

Lines changed: 50 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,25 @@ const LocalFileBrowser = ({ superState, dispatcher }) => {
8585
setFileState(state);
8686
};
8787

88+
const newFeatureFile = async () => {
89+
const pickerOpts = {
90+
types: [
91+
{
92+
description: 'Graphml',
93+
accept: {
94+
'text/graphml': ['.graphml'],
95+
},
96+
},
97+
],
98+
excludeAcceptAllOption: true,
99+
multiple: false,
100+
};
101+
102+
const [fileHandle] = await window.showOpenFilePicker(pickerOpts);
103+
const fileObj = await fileHandle.getFile();
104+
readFile(superState, dispatcher, fileObj, fileHandle);
105+
};
106+
88107
return (
89108
<div>
90109
{!dirButton && (
@@ -96,7 +115,6 @@ const LocalFileBrowser = ({ superState, dispatcher }) => {
96115
<input
97116
type="file"
98117
accept=".py, .m, .c, .cpp, .v, .sh"
99-
ref={fileRef}
100118
id="fileButton"
101119
style={{ display: 'none' }}
102120
onClick={(e) => { e.target.value = null; }}
@@ -126,11 +144,41 @@ const LocalFileBrowser = ({ superState, dispatcher }) => {
126144
className="inputButton"
127145
disabled={!dirButton}
128146
onClick={newFeature}
129-
ref={fileRef}
130147
>
131148
Upload Directory
132149
</button>
133150
)}
151+
{!dirButton
152+
&& (
153+
<input
154+
type="file"
155+
ref={fileRef}
156+
onClick={(e) => { e.target.value = null; }}
157+
style={{ display: 'none' }}
158+
accept=".graphml"
159+
onChange={(e) => readFile(superState, dispatcher, e.target.files[0])}
160+
/>
161+
)}
162+
{dirButton
163+
&& (
164+
<button
165+
type="button"
166+
ref={fileRef}
167+
className="inputButton"
168+
disabled={!dirButton}
169+
style={{ display: 'none' }}
170+
onClick={newFeatureFile}
171+
label="File Upload"
172+
/>
173+
// <input
174+
// type="file"
175+
// ref={fileRef}
176+
// onClick={(e) => { e.target.value = null; }}
177+
// style={{ display: 'none' }}
178+
// accept=".graphml"
179+
// onChange={(e) => readFile(superState, dispatcher, e.target.files[0])}
180+
// />
181+
)}
134182
<h4>
135183
Folder Name :
136184
{' '}

src/component/modals/FileEdit.jsx

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import React, { useState, useEffect } from 'react';
22
import Editor from 'react-simple-code-editor';
33
import { highlight, languages } from 'prismjs/components/prism-core';
4+
import { saveAs } from 'file-saver';
45
import Modal from './ParentModal';
56
import './file-edit.css';
67
import 'prismjs/components/prism-clike';
@@ -11,6 +12,14 @@ import { actionType as T } from '../../reducer';
1112
const FileEditModal = ({ superState, dispatcher }) => {
1213
const [codeStuff, setCodeStuff] = useState('');
1314
const [fileName, setFileName] = useState('');
15+
const [dirButton, setDirButton] = useState(false);
16+
17+
useEffect(() => {
18+
if (navigator.userAgent.indexOf('Edg') !== -1 || navigator.userAgent.indexOf('Chrome') !== -1) {
19+
setDirButton(true);
20+
}
21+
}, []);
22+
1423
const close = () => dispatcher({ type: T.EDIT_TEXTFILE, payload: { show: false } });
1524
// TODO - Save file
1625
async function submit() {
@@ -25,6 +34,23 @@ const FileEditModal = ({ superState, dispatcher }) => {
2534
dispatcher({ type: T.EDIT_TEXTFILE, payload: { show: false } });
2635
}
2736

37+
async function saveAsSubmit() {
38+
const handle = await window.showSaveFilePicker();
39+
const stream = await handle.createWritable();
40+
await stream.write(codeStuff);
41+
await stream.close();
42+
// dispatcher({ type: T.EDIT_TEXTFILE, payload: { show: false } });
43+
}
44+
45+
async function saveSubmit() {
46+
// eslint-disable-next-line no-alert
47+
const newFileName = prompt('Filename:');
48+
const bytes = new TextEncoder().encode(codeStuff);
49+
const blob = new Blob([bytes], { type: 'application/json;charset=utf-8' });
50+
saveAs(blob, newFileName);
51+
// dispatcher({ type: T.EDIT_TEXTFILE, payload: { show: false } });
52+
}
53+
2854
useEffect(() => {
2955
if (superState.fileObj) {
3056
setFileName(superState.fileObj.name);
@@ -44,7 +70,16 @@ const FileEditModal = ({ superState, dispatcher }) => {
4470
>
4571
<div className="File Edit Container">
4672
<div className="footer">
47-
<button type="submit" className="btn btn-primary" onClick={submit}>Save</button>
73+
{fileName
74+
&& (
75+
<button type="submit" className="btn btn-primary" onClick={submit}>Save</button>
76+
)}
77+
{dirButton && (
78+
<button type="submit" className="btn btn-primary" onClick={saveAsSubmit}>Save As</button>
79+
)}
80+
{!dirButton && (
81+
<button type="submit" className="btn btn-primary" onClick={saveSubmit}>Save As</button>
82+
)}
4883
</div>
4984
<div
5085
style={{

src/component/modals/NodeDetails.jsx

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ const NodeDetails = ({
1313
const [widthSet] = useState(false);
1414
const [labelName, setLabelName] = useState('');
1515
const [labelFile, setLabelFile] = useState('');
16+
const indexOfFile = [];
17+
indexOfFile.push(0);
1618

1719
const setStyle = (prop) => {
1820
setData({ ...data, style: { ...data.style, ...prop } });
@@ -117,14 +119,17 @@ const NodeDetails = ({
117119
{
118120
localStorageManager.getFileList()
119121
// eslint-disable-next-line max-len, prefer-arrow-callback
120-
? JSON.parse(localStorageManager.getFileList()).map(function fn(item, index) {
122+
? JSON.parse(localStorageManager.getFileList()).map(function fn(item) {
121123
const acceptedTypes = ['.v', '.c', '.cpp', '.py', '.m', '.sh'];
122124
const list = [];
125+
let index;
123126
// eslint-disable-next-line max-len
124127
if ((acceptedTypes.some((substring) => item.key.toString().includes(substring)))) {
125128
list.push(item.key.toString());
129+
indexOfFile.push(indexOfFile[indexOfFile.length - 1] + 1);
130+
index = indexOfFile[indexOfFile.length - 1] + 1;
126131
}
127-
// eslint-disable-next-line jsx-a11y/control-has-associated-label, react/no-array-index-key
132+
// eslint-disable-next-line jsx-a11y/control-has-associated-label
128133
return <option value={list} key={index} />;
129134
})
130135
: ''

src/graph-builder/graph-core/5-load-save.js

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -100,18 +100,35 @@ class GraphLoadSave extends GraphUndoRedo {
100100
return `${this.projectName}`;
101101
}
102102

103-
saveToDisk(fileName) {
103+
async saveToDisk() {
104104
const str = graphmlBuilder(this.jsonifyGraph());
105105
const bytes = new TextEncoder().encode(str);
106106
const blob = new Blob([bytes], { type: 'application/json;charset=utf-8' });
107-
saveAs(blob, `${fileName || `${this.getName()}-concore`}.graphml`);
107+
if (navigator.userAgent.indexOf('Edg') !== -1 || navigator.userAgent.indexOf('Chrome') !== -1) {
108+
const options = {
109+
types: [
110+
{
111+
description: 'GraphMl Files',
112+
accept: {
113+
'text/graphml': ['.graphml'],
114+
},
115+
},
116+
],
117+
};
118+
const handle = await window.showSaveFilePicker(options);
119+
const stream = await handle.createWritable();
120+
await stream.write(blob);
121+
await stream.close();
122+
} else {
123+
// eslint-disable-next-line no-alert
124+
const fileName = prompt('Filename:');
125+
saveAs(blob, `${fileName || `${this.getName()}-concore`}.graphml`);
126+
}
108127
}
109128

110129
saveToFolder() {
111130
const str = graphmlBuilder(this.jsonifyGraph());
112-
const bytes = new TextEncoder().encode(str);
113-
const blob = new Blob([bytes], { type: 'application/json;charset=utf-8' });
114-
return blob;
131+
return str;
115132
}
116133

117134
getGraphML() {

src/toolbarActions/toolbarFunctions.js

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -75,8 +75,8 @@ const downloadImg = (state, setState, format) => {
7575
getGraphFun(state).downloadImg(format);
7676
};
7777

78-
const saveAction = (state, d, fileName) => {
79-
getGraphFun(state).saveToDisk(fileName);
78+
const saveAction = (state) => {
79+
getGraphFun(state).saveToDisk();
8080
};
8181

8282
async function saveGraphMLFile(state) {
@@ -123,6 +123,13 @@ const readTextFile = (state, setState, file, fileHandle) => {
123123
}
124124
};
125125

126+
const createFile = (state, setState) => {
127+
setState({
128+
type: T.EDIT_TEXTFILE,
129+
payload: { show: true },
130+
});
131+
};
132+
126133
const newProject = (state, setState) => {
127134
setState({ type: T.NEW_GRAPH });
128135
};
@@ -167,7 +174,7 @@ const toggleServer = (state, dispatcher) => {
167174

168175
export {
169176
createNode, editElement, deleteElem, downloadImg, saveAction, saveGraphMLFile,
170-
readFile, readTextFile, newProject, clearAll, editDetails, undo, redo,
177+
createFile, readFile, readTextFile, newProject, clearAll, editDetails, undo, redo,
171178
openShareModal, openSettingModal, viewHistory,
172179
toggleServer,
173180
};

0 commit comments

Comments
 (0)