Skip to content

Sketch collections #1164

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
122 commits
Select commit Hold shift + click to select a range
37fcf46
Public API: Create new project (fixes #1095) (#1106)
andrewn Aug 30, 2019
210e8b6
Public API: Namespace private and public APIs (#1148)
andrewn Aug 30, 2019
0ae7a9e
Display Access Token tab depending on UI_ACCESS_TOKEN_ENABLED feature…
andrewn Aug 30, 2019
83978ac
Adds Collections model and Editor API to manage collections
andrewn Jul 8, 2019
9c36f2b
Adds collections Nav item behind a feature flag
andrewn Jul 9, 2019
d02a413
Displays existing collection
andrewn Jul 9, 2019
dcf65c6
Create Collection
andrewn Jul 9, 2019
1c97152
EditableInput component
andrewn Sep 8, 2019
2df3670
WIP Display collection
andrewn Sep 8, 2019
b258d7c
Fix routing bug displaying Sketch list tab
andrewn Sep 8, 2019
3dbaa90
Splits CollectionList into smaller files
andrewn Sep 9, 2019
55e6b31
Logged in user can use "Add to collection" menu item
andrewn Sep 9, 2019
c575559
Show toast message when creating collection or adding/removing sketches
andrewn Sep 9, 2019
ee896b0
Assets routes should be parsed after server routes so /add-to-collect…
andrewn Sep 9, 2019
fef4bd8
Shorten date displayed in Collection List items for better layout
andrewn Sep 11, 2019
cf3c132
Padding for table cells to align with header
andrewn Sep 11, 2019
a0384f1
Do not empty table when fetching new data
andrewn Sep 11, 2019
5575c63
Sets Collection List modal in addMode to fixed width
andrewn Sep 11, 2019
5011c1f
Display icon-based add/remove button in Collection List
andrewn Sep 16, 2019
d2ec686
Remove logging
andrewn Sep 16, 2019
8b058d8
Edit sketch name/description
andrewn Sep 16, 2019
709aa8e
Fix sketch list padding in collection view
andrewn Sep 16, 2019
b980ec7
Add sketch to collection from collection view
andrewn Sep 17, 2019
a93ac48
Enable collection and sketch to be created from dashboard page
andrewn Sep 17, 2019
52e9872
Collection metadata area layout improvements
andrewn Sep 18, 2019
c9551a3
Adds Collections model and Editor API to manage collections
andrewn Jul 8, 2019
af955b1
Adds collections Nav item behind a feature flag
andrewn Jul 9, 2019
6ca6e78
Displays existing collection
andrewn Jul 9, 2019
c57ead4
Create Collection
andrewn Jul 9, 2019
521e117
EditableInput component
andrewn Sep 8, 2019
8781036
WIP Display collection
andrewn Sep 8, 2019
959ff3e
Splits CollectionList into smaller files
andrewn Sep 9, 2019
f98919e
Logged in user can use "Add to collection" menu item
andrewn Sep 9, 2019
20a5ac5
Show toast message when creating collection or adding/removing sketches
andrewn Sep 9, 2019
95f6105
Assets routes should be parsed after server routes so /add-to-collect…
andrewn Sep 9, 2019
c288481
Shorten date displayed in Collection List items for better layout
andrewn Sep 11, 2019
a385b47
Padding for table cells to align with header
andrewn Sep 11, 2019
679304d
Do not empty table when fetching new data
andrewn Sep 11, 2019
0086601
Sets Collection List modal in addMode to fixed width
andrewn Sep 11, 2019
2a0a560
Display icon-based add/remove button in Collection List
andrewn Sep 16, 2019
60ec678
Remove logging
andrewn Sep 16, 2019
7a1fa66
Edit sketch name/description
andrewn Sep 16, 2019
7f78fda
Fix sketch list padding in collection view
andrewn Sep 16, 2019
27804ac
Add sketch to collection from collection view
andrewn Sep 17, 2019
f535600
Enable collection and sketch to be created from dashboard page
andrewn Sep 17, 2019
0f3ce8e
Collection metadata area layout improvements
andrewn Sep 18, 2019
e2f8fe7
fix merge conflicts
catarak Sep 25, 2019
067e065
update nav on collection view
catarak Sep 25, 2019
c84f590
Fix eslint errors
andrewn Oct 2, 2019
ec32eb1
Collection Create is a modal
andrewn Oct 2, 2019
38f13c2
Remove modals from IDEView now that they are part of DashboardView
andrewn Oct 2, 2019
fc02f49
Fix layout of Searchbar in IDEView
andrewn Oct 2, 2019
bcebc07
Collection Add Sketch and Share buttons
andrewn Oct 3, 2019
cf9a601
Share and Add Sketch button copy
andrewn Oct 3, 2019
c981bc8
Fixes collection metadata spacing when user is not the owner
andrewn Oct 3, 2019
3573253
Add/Remove sketch to collection by clicking on entire row
andrewn Oct 19, 2019
a82e079
Delete collection from list
andrewn Oct 20, 2019
4c5e62b
Remove "Add sketches" link as it have been replaced by primary button
andrewn Oct 20, 2019
45dbb8e
Remove sketch from collection view page
andrewn Oct 20, 2019
36f305e
Fix bug where "empty" view is shown when loading
andrewn Oct 20, 2019
66704e3
Dashboard tabs should match other tabs on the site
andrewn Oct 20, 2019
3554fe9
Show Searchbar clear button only when text is entered
andrewn Oct 20, 2019
edfddcc
Export unconnected Searchbar for use elsewhere (with sketch search)
andrewn Oct 20, 2019
af8d25f
Popover component to add sketches to collection from SketchList
andrewn Oct 20, 2019
48c4183
Add missing check image
andrewn Oct 20, 2019
ad09ce1
Filter collections using Searchbar
andrewn Oct 20, 2019
7e5613b
Show if sketch is in collection and allow removal
andrewn Oct 20, 2019
7137c7b
Increase hit area of dashboard switcher tabs
andrewn Oct 20, 2019
f928665
Show empty state when no collections
andrewn Oct 20, 2019
126bdca
Entire SketchList row adds/removes sketch to collection
andrewn Oct 20, 2019
5611d32
Allow extra elements to be injected into Overlay header
andrewn Oct 21, 2019
935dd12
Add sketch Searchbar when displaying modal in Collection view
andrewn Oct 21, 2019
59469d9
Remove unused code
andrewn Oct 21, 2019
14a8f48
Fix all linting errors/warnings
andrewn Oct 21, 2019
846d2bb
Merge branch 'feature/public-api' into feature/sketch-collections
catarak Oct 31, 2019
e738221
Style DashboardActions below tabs
andrewn Nov 4, 2019
18af6ae
Show add/remove/in collection icon in SketchList
andrewn Nov 4, 2019
08fd6b8
New simplfied collection list when adding a sketch
andrewn Nov 5, 2019
7135f5f
update spacing on preview nav
catarak Nov 7, 2019
ad13684
New simplified sketch list when adding from Collection view
andrewn Nov 10, 2019
161725c
Remove popover and "add to collection" code from SketchList
andrewn Nov 10, 2019
ff86e45
Put border around lists
andrewn Nov 10, 2019
e3949a7
Tidy up Asset styles
andrewn Nov 10, 2019
9ac0cc1
Use bar chart for current size of used assets
andrewn Nov 10, 2019
b6e6018
Remove addMode code
andrewn Nov 10, 2019
ed1945a
Rename collection from collection list view
andrewn Nov 10, 2019
ecba54e
Remove padding
andrewn Nov 10, 2019
e00cc30
Fix layout of sketch add
andrewn Nov 10, 2019
212ad64
Implement CollectionSearchbar in addition to SketchSearchbar
andrewn Nov 10, 2019
13c4549
Merge branch 'feature/public-api' into feature/sketch-collections
andrewn Nov 10, 2019
b751353
collections: add styling changes for dashboard pages
catarak Nov 14, 2019
fbb1e9a
re #1207, update mongoose options for fetch example scripts
catarak Nov 14, 2019
00b788f
update collection view, update nav list so that 'my collections' does…
catarak Nov 24, 2019
1056005
"View" should link to sketch
andrewn Nov 25, 2019
8adb134
Merge branch 'feature/sketch-collections' of https://github.com/andre…
andrewn Nov 25, 2019
8132a02
Improve progress bar layout
andrewn Nov 25, 2019
0d1a4d2
Keep theme in sync with state across the app
andrewn Nov 25, 2019
e114a74
Quick add button theme support
andrewn Nov 25, 2019
001c285
Editable Input theme icon
andrewn Nov 25, 2019
e0b6f88
Use secondary button style for now
andrewn Nov 25, 2019
5860b9b
Quick-add item should show hover state when accessed from keyboard
andrewn Nov 25, 2019
1d4771e
Show placeholder label when Collection has no description
andrewn Nov 25, 2019
df44a62
Remove sketch from collection via icon button
andrewn Nov 25, 2019
7ec30dd
Merge pull request #1214 from andrewn/feature/theme-sync
catarak Nov 25, 2019
5319bbb
merge master into sketch collections, to include updating theming
catarak Nov 25, 2019
ce1c389
Use same remove icon as in QuickAdd panel
andrewn Nov 25, 2019
4f7c9f2
Rename import to match file name
andrewn Nov 25, 2019
387cec1
Merge branch 'feature/sketch-collections' of https://github.com/andre…
andrewn Nov 25, 2019
001a30f
potentional option for collection sharing
catarak Dec 10, 2019
20c2c6c
Merge branch 'feature/sketch-collections' of https://github.com/andre…
andrewn Dec 11, 2019
740401d
Make navigation back to Collection List more obvious
andrewn Dec 11, 2019
0c68327
Fixed-height Overlay for QuickAdd views
andrewn Dec 11, 2019
a2da26d
Better min-width for QuickAdd views
andrewn Dec 11, 2019
4d0aa23
Display Add Sketches Overlay from Collection List
andrewn Dec 11, 2019
a5b6256
Fix linter warnings
andrewn Dec 11, 2019
903550b
Collection owner's username links to their sketches page
andrewn Jan 15, 2020
0660031
Make "Add sketch" copy consistent
andrewn Jan 15, 2020
811c88f
Description should be inactive color if a collection doesn't have one
andrewn Jan 15, 2020
ed481b9
Don't allow Collection name to be empty
andrewn Jan 15, 2020
58b800d
Align pencil icon with label
andrewn Jan 15, 2020
442360c
Increase contrast between in/out of collection icon state in quick ad…
andrewn Jan 15, 2020
8087a3f
Revert "Make navigation back to Collection List more obvious"
andrewn Jan 15, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions client/components/AddRemoveButton.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import React from 'react';
import PropTypes from 'prop-types';
import InlineSVG from 'react-inlinesvg';

const addIcon = require('../images/plus.svg');
const removeIcon = require('../images/minus.svg');

const AddRemoveButton = ({ type, onClick }) => {
const alt = type === 'add' ? 'add to collection' : 'remove from collection';
const icon = type === 'add' ? addIcon : removeIcon;

return (
<button className="overlay__close-button" onClick={onClick}>
<InlineSVG src={icon} alt={alt} />
</button>
);
};

AddRemoveButton.propTypes = {
type: PropTypes.oneOf(['add', 'remove']).isRequired,
onClick: PropTypes.func.isRequired,
};

export default AddRemoveButton;
25 changes: 25 additions & 0 deletions client/components/Nav.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -326,6 +326,19 @@ class Nav extends React.PureComponent {
Open
</Link>
</li> }
{__process.env.UI_COLLECTIONS_ENABLED &&
this.props.user.authenticated &&
this.props.project.id &&
<li className="nav__dropdown-item">
<Link
to={`/${this.props.user.username}/sketches/${this.props.project.id}/add-to-collection`}
onFocus={this.handleFocusForFile}
onBlur={this.handleBlur}
onClick={this.setDropdownForNone}
>
Add to Collection
</Link>
</li>}
{ __process.env.EXAMPLES_ENABLED &&
<li className="nav__dropdown-item">
<Link
Expand Down Expand Up @@ -576,6 +589,18 @@ class Nav extends React.PureComponent {
My sketches
</Link>
</li>
{__process.env.UI_COLLECTIONS_ENABLED &&
<li className="nav__dropdown-item">
<Link
to={`/${this.props.user.username}/collections`}
onFocus={this.handleFocusForAccount}
onBlur={this.handleBlur}
onClick={this.setDropdownForNone}
>
My collections
</Link>
</li>
}
<li className="nav__dropdown-item">
<Link
to={`/${this.props.user.username}/assets`}
Expand Down
2 changes: 1 addition & 1 deletion client/components/PreviewNav.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ const logoUrl = require('../images/p5js-logo-small.svg');
const editorUrl = require('../images/code.svg');

const PreviewNav = ({ owner, project }) => (
<nav className="nav">
<nav className="nav preview-nav">
<div className="nav__items-left">
<div className="nav__item-logo">
<InlineSVG src={logoUrl} alt="p5.js logo" />
Expand Down
8 changes: 8 additions & 0 deletions client/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,14 @@ export const HIDE_EDIT_PROJECT_NAME = 'HIDE_EDIT_PROJECT_NAME';
export const SET_PROJECT = 'SET_PROJECT';
export const SET_PROJECTS = 'SET_PROJECTS';

export const SET_COLLECTIONS = 'SET_COLLECTIONS';
export const CREATE_COLLECTION = 'CREATED_COLLECTION';
export const DELETE_COLLECTION = 'DELETE_COLLECTION';

export const ADD_TO_COLLECTION = 'ADD_TO_COLLECTION';
export const REMOVE_FROM_COLLECTION = 'REMOVE_FROM_COLLECTION';
export const EDIT_COLLECTION = 'EDIT_COLLECTION';

export const DELETE_PROJECT = 'DELETE_PROJECT';

export const SET_SELECTED_FILE = 'SET_SELECTED_FILE';
Expand Down
6 changes: 6 additions & 0 deletions client/images/check.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
11 changes: 11 additions & 0 deletions client/images/check_encircled.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
12 changes: 12 additions & 0 deletions client/images/close.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
20 changes: 17 additions & 3 deletions client/modules/App/App.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ class App extends React.Component {

componentDidMount() {
this.setState({ isMounted: true }); // eslint-disable-line react/no-did-mount-set-state
document.body.className = 'light';
document.body.className = this.props.theme;
}

componentWillReceiveProps(nextProps) {
Expand All @@ -26,6 +26,12 @@ class App extends React.Component {
}
}

componentDidUpdate(prevProps) {
if (this.props.theme !== prevProps.theme) {
document.body.className = this.props.theme;
}
}

render() {
return (
<div className="app">
Expand All @@ -45,10 +51,18 @@ App.propTypes = {
}),
}).isRequired,
setPreviousPath: PropTypes.func.isRequired,
theme: PropTypes.string,
};

App.defaultProps = {
children: null
children: null,
theme: 'light'
};

export default connect(() => ({}), { setPreviousPath })(App);
const mapStateToProps = state => ({
theme: state.preferences.theme,
});

const mapDispatchToProps = { setPreviousPath };

export default connect(mapStateToProps, mapDispatchToProps)(App);
23 changes: 16 additions & 7 deletions client/modules/App/components/Overlay.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -64,10 +64,12 @@ class Overlay extends React.Component {
const {
ariaLabel,
title,
children
children,
actions,
isFixedHeight,
} = this.props;
return (
<div className="overlay">
<div className={`overlay ${isFixedHeight ? 'overlay--is-fixed-height' : ''}`}>
<div className="overlay__content">
<section
role="main"
Expand All @@ -77,9 +79,12 @@ class Overlay extends React.Component {
>
<header className="overlay__header">
<h2 className="overlay__title">{title}</h2>
<button className="overlay__close-button" onClick={this.close} >
<InlineSVG src={exitUrl} alt="close overlay" />
</button>
<div className="overlay__actions">
{actions}
<button className="overlay__close-button" onClick={this.close} >
<InlineSVG src={exitUrl} alt="close overlay" />
</button>
</div>
</header>
{children}
</section>
Expand All @@ -91,18 +96,22 @@ class Overlay extends React.Component {

Overlay.propTypes = {
children: PropTypes.element,
actions: PropTypes.element,
closeOverlay: PropTypes.func,
title: PropTypes.string,
ariaLabel: PropTypes.string,
previousPath: PropTypes.string
previousPath: PropTypes.string,
isFixedHeight: PropTypes.bool,
};

Overlay.defaultProps = {
children: null,
actions: null,
title: 'Modal',
closeOverlay: null,
ariaLabel: 'modal',
previousPath: '/'
previousPath: '/',
isFixedHeight: false,
};

export default Overlay;
173 changes: 173 additions & 0 deletions client/modules/IDE/actions/collections.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,173 @@
import axios from 'axios';
import * as ActionTypes from '../../../constants';
import { startLoader, stopLoader } from './loader';
import { setToastText, showToast } from './toast';

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

const TOAST_DISPLAY_TIME_MS = 1500;

// eslint-disable-next-line
export function getCollections(username) {
return (dispatch) => {
dispatch(startLoader());
let url;
if (username) {
url = `${ROOT_URL}/${username}/collections`;
} else {
url = `${ROOT_URL}/collections`;
}
axios.get(url, { withCredentials: true })
.then((response) => {
dispatch({
type: ActionTypes.SET_COLLECTIONS,
collections: response.data
});
dispatch(stopLoader());
})
.catch((response) => {
dispatch({
type: ActionTypes.ERROR,
error: response.data
});
dispatch(stopLoader());
});
};
}

export function createCollection(collection) {
return (dispatch) => {
dispatch(startLoader());
const url = `${ROOT_URL}/collections`;
return axios.post(url, collection, { withCredentials: true })
.then((response) => {
dispatch({
type: ActionTypes.CREATE_COLLECTION
});
dispatch(stopLoader());

const collectionName = response.data.name;
dispatch(setToastText(`Created "${collectionName}"`));
dispatch(showToast(TOAST_DISPLAY_TIME_MS));

return response.data;
})
.catch((response) => {
dispatch({
type: ActionTypes.ERROR,
error: response.data
});
dispatch(stopLoader());

return response.data;
});
};
}

export function addToCollection(collectionId, projectId) {
return (dispatch) => {
dispatch(startLoader());
const url = `${ROOT_URL}/collections/${collectionId}/${projectId}`;
return axios.post(url, { withCredentials: true })
.then((response) => {
dispatch({
type: ActionTypes.ADD_TO_COLLECTION,
payload: response.data
});
dispatch(stopLoader());

const collectionName = response.data.name;

dispatch(setToastText(`Added to "${collectionName}`));
dispatch(showToast(TOAST_DISPLAY_TIME_MS));

return response.data;
})
.catch((response) => {
dispatch({
type: ActionTypes.ERROR,
error: response.data
});
dispatch(stopLoader());

return response.data;
});
};
}

export function removeFromCollection(collectionId, projectId) {
return (dispatch) => {
dispatch(startLoader());
const url = `${ROOT_URL}/collections/${collectionId}/${projectId}`;
return axios.delete(url, { withCredentials: true })
.then((response) => {
dispatch({
type: ActionTypes.REMOVE_FROM_COLLECTION,
payload: response.data
});
dispatch(stopLoader());

const collectionName = response.data.name;

dispatch(setToastText(`Removed from "${collectionName}`));
dispatch(showToast(TOAST_DISPLAY_TIME_MS));

return response.data;
})
.catch((response) => {
dispatch({
type: ActionTypes.ERROR,
error: response.data
});
dispatch(stopLoader());

return response.data;
});
};
}

export function editCollection(collectionId, { name, description }) {
return (dispatch) => {
const url = `${ROOT_URL}/collections/${collectionId}`;
return axios.patch(url, { name, description }, { withCredentials: true })
.then((response) => {
dispatch({
type: ActionTypes.EDIT_COLLECTION,
payload: response.data
});
return response.data;
})
.catch((response) => {
dispatch({
type: ActionTypes.ERROR,
error: response.data
});

return response.data;
});
};
}

export function deleteCollection(collectionId) {
return (dispatch) => {
const url = `${ROOT_URL}/collections/${collectionId}`;
return axios.delete(url, { withCredentials: true })
.then((response) => {
dispatch({
type: ActionTypes.DELETE_COLLECTION,
payload: response.data,
collectionId,
});
return response.data;
})
.catch((response) => {
dispatch({
type: ActionTypes.ERROR,
error: response.data
});

return response.data;
});
};
}
Loading