Skip to content

Commit d7454a1

Browse files
committed
Allow Writing Cloud Code
1 parent 44eea2a commit d7454a1

File tree

4 files changed

+55
-19
lines changed

4 files changed

+55
-19
lines changed

src/components/SaveButton/SaveButton.example.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,9 @@ export const demos = [
5555
<div style={{padding: 10}}>
5656
<SaveButton state={SaveButton.States.FAILED} />
5757
</div>
58+
<div style={{padding: 10}}>
59+
<SaveButton state={SaveButton.States.WAITING} />
60+
</div>
5861
</div>
5962
)
6063
}, {

src/components/SaveButton/SaveButton.react.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ let SaveButton = ({
5252
</span>;
5353
};
5454

55-
SaveButton.States = keyMirror(['SAVING', 'SUCCEEDED', 'FAILED']);
55+
SaveButton.States = keyMirror(['SAVING', 'SUCCEEDED', 'FAILED', 'WAITING']);
5656

5757
let {...forwardedButtonProps} = Button.propTypes;
5858
delete forwardedButtonProps.value;

src/dashboard/Data/CloudCode/CloudCode.react.js

Lines changed: 41 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,15 @@
55
* This source code is licensed under the license found in the LICENSE file in
66
* the root directory of this source tree.
77
*/
8-
import CodeSnippet from 'components/CodeSnippet/CodeSnippet.react';
8+
import CodeEditor from 'components/CodeEditor/CodeEditor.react';
99
import DashboardView from 'dashboard/DashboardView.react';
1010
import EmptyState from 'components/EmptyState/EmptyState.react';
1111
import FileTree from 'components/FileTree/FileTree.react';
1212
import history from 'dashboard/history';
1313
import React from 'react';
1414
import styles from 'dashboard/Data/CloudCode/CloudCode.scss';
1515
import Toolbar from 'components/Toolbar/Toolbar.react';
16+
import SaveButton from 'components/SaveButton/SaveButton.react';
1617

1718
function getPath(params) {
1819
const last = params.location.pathname.split('cloud_code/')[1]
@@ -27,7 +28,9 @@ export default class CloudCode extends DashboardView {
2728

2829
this.state = {
2930
files: undefined,
30-
source: undefined
31+
source: undefined,
32+
saveState: SaveButton.States.WAITING,
33+
saveError: '',
3134
};
3235
}
3336

@@ -56,8 +59,14 @@ export default class CloudCode extends DashboardView {
5659
history.replace(this.context.generatePath(`cloud_code/${Object.keys(release.files)[0]}`))
5760
} else {
5861
// Means we can load /cloud_code/<fileName>
62+
this.setState({ source: undefined })
5963
app.getSource(fileName).then(
60-
(source) => this.setState({ source: source }),
64+
(source) => {
65+
this.setState({ source: source })
66+
if (this.editor) {
67+
this.editor.value = source;
68+
}
69+
},
6170
() => this.setState({ source: undefined })
6271
);
6372
}
@@ -87,7 +96,23 @@ export default class CloudCode extends DashboardView {
8796
</div>
8897
);
8998
}
90-
99+
async getCode() {
100+
if (!this.editor) {
101+
return;
102+
}
103+
this.setState({ saveState: SaveButton.States.SAVING });
104+
let fileName = getPath(this.props);
105+
try {
106+
await this.context.currentApp.saveSource(fileName,this.editor.value);
107+
this.setState({ saveState: SaveButton.States.SUCCEEDED });
108+
setTimeout(()=> {
109+
this.setState({ saveState: SaveButton.States.WAITING });
110+
},2000);
111+
} catch (e) {
112+
this.setState({ saveState: SaveButton.States.FAILED });
113+
this.setState({ saveError: e.message || e });
114+
}
115+
}
91116
renderContent() {
92117
let toolbar = null;
93118
let content = null;
@@ -111,10 +136,20 @@ export default class CloudCode extends DashboardView {
111136
subsection={fileName} />;
112137

113138
let source = this.state.files[fileName];
114-
if (source && source.source) {
139+
if ((source && source.source) || this.state.source) {
115140
content = (
116141
<div className={styles.content}>
117-
<CodeSnippet source={source.source} language='javascript' />
142+
<CodeEditor
143+
placeHolder={this.state.source || source.source}
144+
ref={editor => (this.editor = editor)}
145+
fontSize={'14px'}
146+
/>
147+
<SaveButton
148+
state={this.state.saveState}
149+
waitingText={this.state.submitText}
150+
savingText={this.state.inProgressText}
151+
failedText={this.state.saveError}
152+
onClick={() => this.getCode(this)}></SaveButton>
118153
</div>
119154
);
120155
}

src/lib/ParseApp.js

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,15 @@ export default class ParseApp {
119119
return this.apiRequest('GET', path, {}, { useMasterKey: true });
120120
}
121121

122+
/**
123+
* Saves source of a Cloud Code hosted file from api.parse.com
124+
* fileName - the name of the file to be fetched
125+
* data - the text to save to the cloud file
126+
*/
127+
saveSource(fileName,data) {
128+
return this.apiRequest('POST', `scripts/${fileName}`, {data}, { useMasterKey: true });
129+
}
130+
122131
/**
123132
* Fetches source of a Cloud Code hosted file from api.parse.com
124133
* fileName - the name of the file to be fetched
@@ -129,22 +138,11 @@ export default class ParseApp {
129138
// No release yet
130139
return Promise.resolve(null);
131140
}
132-
133-
let fileMetaData = release.files[fileName];
134-
if (fileMetaData && fileMetaData.source) {
135-
return Promise.resolve(fileMetaData.source);
136-
}
137-
138-
let params = {
139-
version: fileMetaData.version,
140-
checksum: fileMetaData.checksum
141-
}
142-
return this.apiRequest('GET', `scripts/${fileName}`, params, { useMasterKey: true });
141+
return this.apiRequest('GET', `scripts/${fileName}`, {}, { useMasterKey: true });
143142
}).then((source) => {
144143
if (this.latestRelease.files) {
145144
this.latestRelease.files[fileName].source = source;
146145
}
147-
148146
return Promise.resolve(source);
149147
});
150148
}

0 commit comments

Comments
 (0)