Skip to content

Commit 735adcf

Browse files
LakshSinglacatarak
authored andcommitted
Update sketch list styling (#819)
* parent b3c3efc author Laksh Singla <lakshsingla@gmail.com> 1549106083 +0530 committer Cassie Tarakajian <ctarakajian@gmail.com> 1560540243 -0400 parent b3c3efc author Laksh Singla <lakshsingla@gmail.com> 1549106083 +0530 committer Cassie Tarakajian <ctarakajian@gmail.com> 1560540198 -0400 parent b3c3efc author Laksh Singla <lakshsingla@gmail.com> 1549106083 +0530 committer Cassie Tarakajian <ctarakajian@gmail.com> 1560539667 -0400 Created initial html structure and styling for new SketchList design Final styling of ActionDialogueBox commplete Dropdown menu disappearing while clicking anywhere on the table Fixed linting issues and renamed variables Minor tweaks in the SketchList dropdown dialogue UI Themifyed the dropdown Made changes in the dropdown: Arrow positioned slightly updwards, Removed blank space and added box-shadow in dropdown, themifyed dropdowns dashed border color Added Delete and Share functionality to Dialog box Added Duplicate functionality to Dialog box Added download functionality to Dialog box SketchList does not open a sketch if dialogue box is opened SketchList Rename initial UI completed Enter key handled for rename project option [WIP] Updating rename functionality Download option now working for all the sketches Duplicate functionality extended for non opened sketches too Modified overlay behaviour to close only the last overlay Share modal can now display different projects Dropdown closes when Share and Delete are closing for a more natural UX fix broken files from rebasing Created initial html structure and styling for new SketchList design Final styling of ActionDialogueBox commplete Added Delete and Share functionality to Dialog box Added Duplicate functionality to Dialog box [WIP] Updating rename functionality Duplicate functionality extended for non opened sketches too Modified overlay behaviour to close only the last overlay Share modal can now display different projects Final styling of ActionDialogueBox commplete Fixed linting issues and renamed variables Minor tweaks in the SketchList dropdown dialogue UI Themifyed the dropdown Added Delete and Share functionality to Dialog box [WIP] Updating rename functionality Modified overlay behaviour to close only the last overlay Share modal can now display different projects Dropdown closes when Share and Delete are closing for a more natural UX fix broken files from rebasing Final styling of ActionDialogueBox commplete Minor tweaks in the SketchList dropdown dialogue UI Themifyed the dropdown [WIP] Updating rename functionality Duplicate functionality extended for non opened sketches too Modified overlay behaviour to close only the last overlay Share modal can now display different projects Dropdown closes when Share and Delete are closing for a more natural UX * fix bugs in merge commit * move sketch list dialogue to ul/li * update sketch option dropdown to use dropdown placeholder, remove unused css * major refactor of sketchlist component, fix showShareModal action, minor updates ot icon sizing * fix broken links on asset list * remove unused image, fix options for different users in sketch list
1 parent 4bd081b commit 735adcf

File tree

14 files changed

+447
-144
lines changed

14 files changed

+447
-144
lines changed

client/constants.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ export const AUTH_ERROR = 'AUTH_ERROR';
2020
export const SETTINGS_UPDATED = 'SETTINGS_UPDATED';
2121

2222
export const SET_PROJECT_NAME = 'SET_PROJECT_NAME';
23+
export const RENAME_PROJECT = 'RENAME_PROJECT';
2324

2425
export const PROJECT_SAVE_SUCCESS = 'PROJECT_SAVE_SUCCESS';
2526
export const PROJECT_SAVE_FAIL = 'PROJECT_SAVE_FAIL';

client/modules/App/components/Overlay.jsx

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ class Overlay extends React.Component {
3333
return;
3434
}
3535

36-
this.handleClickOutside();
36+
this.handleClickOutside(e);
3737
}
3838

3939
handleClickOutside() {
@@ -49,6 +49,10 @@ class Overlay extends React.Component {
4949
}
5050

5151
close() {
52+
// Only close if it is the last (and therefore the topmost overlay)
53+
const overlays = document.getElementsByClassName('overlay');
54+
if (this.node.parentElement.parentElement !== overlays[overlays.length - 1]) return;
55+
5256
if (!this.props.closeOverlay) {
5357
browserHistory.push(this.props.previousPath);
5458
} else {

client/modules/IDE/actions/ide.js

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -134,9 +134,17 @@ export function closeNewFolderModal() {
134134
};
135135
}
136136

137-
export function showShareModal() {
138-
return {
139-
type: ActionTypes.SHOW_SHARE_MODAL
137+
export function showShareModal(projectId, projectName, ownerUsername) {
138+
return (dispatch, getState) => {
139+
const { project, user } = getState();
140+
dispatch({
141+
type: ActionTypes.SHOW_SHARE_MODAL,
142+
payload: {
143+
shareModalProjectId: projectId || project.id,
144+
shareModalProjectName: projectName || project.name,
145+
shareModalProjectUsername: ownerUsername || user.username
146+
}
147+
});
140148
};
141149
}
142150

client/modules/IDE/actions/project.js

Lines changed: 107 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,8 @@ import {
99
setUnsavedChanges,
1010
justOpenedProject,
1111
resetJustOpenedProject,
12-
showErrorModal
12+
showErrorModal,
13+
setPreviousPath
1314
} from './ide';
1415
import { clearState, saveState } from '../../../persistState';
1516

@@ -246,47 +247,61 @@ function generateNewIdsForChildren(file, files) {
246247
file.children = newChildren; // eslint-disable-line
247248
}
248249

249-
export function cloneProject() {
250+
export function cloneProject(id) {
250251
return (dispatch, getState) => {
251252
dispatch(setUnsavedChanges(false));
252-
const state = getState();
253-
const newFiles = state.files.map((file) => { // eslint-disable-line
254-
return { ...file };
255-
});
253+
new Promise((resolve, reject) => {
254+
if (!id) {
255+
resolve(getState());
256+
} else {
257+
fetch(`${ROOT_URL}/projects/${id}`)
258+
.then(res => res.json())
259+
.then(data => resolve({
260+
files: data.files,
261+
project: {
262+
name: data.name
263+
}
264+
}));
265+
}
266+
}).then((state) => {
267+
const newFiles = state.files.map((file) => { // eslint-disable-line
268+
return { ...file };
269+
});
256270

257-
// generate new IDS for all files
258-
const rootFile = newFiles.find(file => file.name === 'root');
259-
const newRootFileId = objectID().toHexString();
260-
rootFile.id = newRootFileId;
261-
rootFile._id = newRootFileId;
262-
generateNewIdsForChildren(rootFile, newFiles);
271+
// generate new IDS for all files
272+
const rootFile = newFiles.find(file => file.name === 'root');
273+
const newRootFileId = objectID().toHexString();
274+
rootFile.id = newRootFileId;
275+
rootFile._id = newRootFileId;
276+
generateNewIdsForChildren(rootFile, newFiles);
263277

264-
// duplicate all files hosted on S3
265-
each(newFiles, (file, callback) => {
266-
if (file.url && file.url.includes('amazonaws')) {
267-
const formParams = {
268-
url: file.url
269-
};
270-
axios.post(`${ROOT_URL}/S3/copy`, formParams, { withCredentials: true })
278+
// duplicate all files hosted on S3
279+
each(newFiles, (file, callback) => {
280+
if (file.url && file.url.includes('amazonaws')) {
281+
const formParams = {
282+
url: file.url
283+
};
284+
axios.post(`${ROOT_URL}/S3/copy`, formParams, { withCredentials: true })
285+
.then((response) => {
286+
file.url = response.data.url;
287+
callback(null);
288+
});
289+
} else {
290+
callback(null);
291+
}
292+
}, (err) => {
293+
// if not errors in duplicating the files on S3, then duplicate it
294+
const formParams = Object.assign({}, { name: `${state.project.name} copy` }, { files: newFiles });
295+
axios.post(`${ROOT_URL}/projects`, formParams, { withCredentials: true })
271296
.then((response) => {
272-
file.url = response.data.url;
273-
callback(null);
274-
});
275-
} else {
276-
callback(null);
277-
}
278-
}, (err) => {
279-
// if not errors in duplicating the files on S3, then duplicate it
280-
const formParams = Object.assign({}, { name: `${state.project.name} copy` }, { files: newFiles });
281-
axios.post(`${ROOT_URL}/projects`, formParams, { withCredentials: true })
282-
.then((response) => {
283-
browserHistory.push(`/${response.data.user.username}/sketches/${response.data.id}`);
284-
dispatch(setNewProject(response.data));
285-
})
286-
.catch(response => dispatch({
287-
type: ActionTypes.PROJECT_SAVE_FAIL,
288-
error: response.data
289-
}));
297+
browserHistory.push(`/${response.data.user.username}/sketches/${response.data.id}`);
298+
dispatch(setNewProject(response.data));
299+
})
300+
.catch(response => dispatch({
301+
type: ActionTypes.PROJECT_SAVE_FAIL,
302+
error: response.data
303+
}));
304+
});
290305
});
291306
};
292307
}
@@ -309,3 +324,58 @@ export function setProjectSavedTime(updatedAt) {
309324
value: updatedAt
310325
};
311326
}
327+
328+
export function changeProjectName(id, newName) {
329+
return (dispatch, getState) => {
330+
const state = getState();
331+
axios.put(`${ROOT_URL}/projects/${id}`, { name: newName }, { withCredentials: true })
332+
.then((response) => {
333+
if (response.status === 200) {
334+
dispatch({
335+
type: ActionTypes.RENAME_PROJECT,
336+
payload: { id: response.data.id, name: response.data.name }
337+
});
338+
if (state.project.id === response.data.id) {
339+
dispatch({
340+
type: ActionTypes.SET_PROJECT_NAME,
341+
name: response.data.name
342+
});
343+
}
344+
}
345+
})
346+
.catch((response) => {
347+
console.log(response);
348+
dispatch({
349+
type: ActionTypes.PROJECT_SAVE_FAIL,
350+
error: response.data
351+
});
352+
});
353+
};
354+
}
355+
356+
export function deleteProject(id) {
357+
return (dispatch, getState) => {
358+
axios.delete(`${ROOT_URL}/projects/${id}`, { withCredentials: true })
359+
.then(() => {
360+
const state = getState();
361+
if (id === state.project.id) {
362+
dispatch(resetProject());
363+
dispatch(setPreviousPath('/'));
364+
}
365+
dispatch({
366+
type: ActionTypes.DELETE_PROJECT,
367+
id
368+
});
369+
})
370+
.catch((response) => {
371+
if (response.status === 403) {
372+
dispatch(showErrorModal('staleSession'));
373+
} else {
374+
dispatch({
375+
type: ActionTypes.ERROR,
376+
error: response.data
377+
});
378+
}
379+
});
380+
};
381+
}
Lines changed: 1 addition & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
11
import axios from 'axios';
22
import * as ActionTypes from '../../../constants';
3-
import { showErrorModal, setPreviousPath } from './ide';
4-
import { resetProject } from './project';
53
import { startLoader, stopLoader } from './loader';
64

75
const __process = (typeof global !== 'undefined' ? global : window).process;
86
const ROOT_URL = __process.env.API_URL;
97

8+
// eslint-disable-next-line
109
export function getProjects(username) {
1110
return (dispatch) => {
1211
dispatch(startLoader());
@@ -33,30 +32,3 @@ export function getProjects(username) {
3332
});
3433
};
3534
}
36-
37-
export function deleteProject(id) {
38-
return (dispatch, getState) => {
39-
axios.delete(`${ROOT_URL}/projects/${id}`, { withCredentials: true })
40-
.then(() => {
41-
const state = getState();
42-
if (id === state.project.id) {
43-
dispatch(resetProject());
44-
dispatch(setPreviousPath('/'));
45-
}
46-
dispatch({
47-
type: ActionTypes.DELETE_PROJECT,
48-
id
49-
});
50-
})
51-
.catch((response) => {
52-
if (response.status === 403) {
53-
dispatch(showErrorModal('staleSession'));
54-
} else {
55-
dispatch({
56-
type: ActionTypes.ERROR,
57-
error: response.data
58-
});
59-
}
60-
});
61-
};
62-
}

client/modules/IDE/components/AssetList.jsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,14 @@ class AssetList extends React.Component {
1717
}
1818

1919
getAssetsTitle() {
20-
if (this.props.username === this.props.user.username) {
20+
if (!this.props.username || this.props.username === this.props.user.username) {
2121
return 'p5.js Web Editor | My assets';
2222
}
2323
return `p5.js Web Editor | ${this.props.username}'s assets`;
2424
}
2525

2626
render() {
27+
const username = this.props.username !== undefined ? this.props.username : this.props.user.username;
2728
return (
2829
<div className="asset-table-container">
2930
<Helmet>
@@ -49,7 +50,7 @@ class AssetList extends React.Component {
4950
<td>{asset.name}</td>
5051
<td>{prettyBytes(asset.size)}</td>
5152
<td><Link to={asset.url} target="_blank">View</Link></td>
52-
<td><Link to={`/${this.props.username}/sketches/${asset.sketchId}`}>{asset.sketchName}</Link></td>
53+
<td><Link to={`/${username}/sketches/${asset.sketchId}`}>{asset.sketchName}</Link></td>
5354
</tr>
5455
))}
5556
</tbody>

0 commit comments

Comments
 (0)