diff --git a/client/modules/IDE/components/CollectionPopover/CollectionPopover.jsx b/client/modules/IDE/components/CollectionPopover/CollectionPopover.jsx
new file mode 100644
index 00000000..96471d8f
--- /dev/null
+++ b/client/modules/IDE/components/CollectionPopover/CollectionPopover.jsx
@@ -0,0 +1,105 @@
+import PropTypes from 'prop-types';
+import React from 'react';
+import InlineSVG from 'react-inlinesvg';
+import { connect } from 'react-redux';
+import { bindActionCreators } from 'redux';
+
+import * as CollectionsActions from '../../actions/collections';
+import getSortedCollections from '../../selectors/collections';
+
+// import { Link } from 'react-router';
+
+import exitUrl from '../../../../images/exit.svg';
+
+import { Searchbar } from '../Searchbar';
+import Item from './Item';
+
+// const reducer = () => {
+// switch ()
+// case 'noItems':
+// return 'NoCollections';
+// case
+// }
+
+const NoCollections = () => (
+
+
No collections
+ {/*
+ {}}
+ >Create
+
+
*/}
+
);
+
+
+const CollectionPopover = ({
+ onClose, project, collections, addToCollection, getCollections, user
+}) => {
+ const [searchTerm, setSearchTerm] = React.useState('');
+
+ React.useEffect(() => {
+ getCollections(user.username);
+ }, [user]);
+
+ const handleAddToCollection = (collectionId) => {
+ addToCollection(collectionId, project.id);
+ };
+
+ return (
+
+
+
Add to collection
+
+
+
+
+
+
+
+
+
+ {
+ collections.map(collection => - handleAddToCollection(collection.id)} />)
+ }
+
+
+
+ );
+};
+
+CollectionPopover.propTypes = {
+ onClose: PropTypes.func.isRequired,
+ getCollections: PropTypes.func.isRequired,
+ addToCollection: PropTypes.func.isRequired,
+ user: PropTypes.shape({
+ username: PropTypes.string.isRequired,
+ }).isRequired,
+ collections: PropTypes.arrayOf(PropTypes.shape({
+ name: PropTypes.string,
+ })).isRequired,
+ project: PropTypes.shape({
+ id: PropTypes.string,
+ }).isRequired,
+};
+
+function mapStateToProps(state, ownProps) {
+ return {
+ user: state.user,
+ collections: getSortedCollections(state),
+ loading: state.loading,
+ };
+}
+
+function mapDispatchToProps(dispatch) {
+ return bindActionCreators(
+ Object.assign({}, CollectionsActions),
+ dispatch
+ );
+}
+
+export default connect(mapStateToProps, mapDispatchToProps)(CollectionPopover);
diff --git a/client/modules/IDE/components/CollectionPopover/Item.jsx b/client/modules/IDE/components/CollectionPopover/Item.jsx
new file mode 100644
index 00000000..1d3d4efa
--- /dev/null
+++ b/client/modules/IDE/components/CollectionPopover/Item.jsx
@@ -0,0 +1,26 @@
+import PropTypes from 'prop-types';
+import React from 'react';
+import { Link } from 'react-router';
+
+const CollectionItem = ({ collection, onSelect }) => (
+
+
+
+
+
+
+ View
+
+
+);
+
+CollectionItem.propTypes = {
+ onSelect: PropTypes.func.isRequired,
+ collection: PropTypes.shape({
+ name: PropTypes.string,
+ }).isRequired,
+};
+
+export default CollectionItem;
diff --git a/client/modules/IDE/components/CollectionPopover/index.js b/client/modules/IDE/components/CollectionPopover/index.js
new file mode 100644
index 00000000..2457586e
--- /dev/null
+++ b/client/modules/IDE/components/CollectionPopover/index.js
@@ -0,0 +1 @@
+export { default } from './CollectionPopover.jsx';
diff --git a/client/modules/IDE/components/SketchList.jsx b/client/modules/IDE/components/SketchList.jsx
index 268d5d89..3cfa421e 100644
--- a/client/modules/IDE/components/SketchList.jsx
+++ b/client/modules/IDE/components/SketchList.jsx
@@ -17,6 +17,7 @@ import * as IdeActions from '../actions/ide';
import getSortedSketches from '../selectors/projects';
import Loader from '../../App/components/loader';
import AddRemoveButton from '../../../components/AddRemoveButton';
+import CollectionPopover from './CollectionPopover';
const arrowUp = require('../../../images/sort-arrow-up.svg');
const arrowDown = require('../../../images/sort-arrow-down.svg');
@@ -29,7 +30,8 @@ class SketchListRowBase extends React.Component {
optionsOpen: false,
renameOpen: false,
renameValue: props.sketch.name,
- isFocused: false
+ isFocused: false,
+ showPopover: false,
};
}
@@ -119,6 +121,18 @@ class SketchListRowBase extends React.Component {
this.props.exportProjectAsZip(this.props.sketch.id);
}
+ handleShowCollectionPopover = () => {
+ this.setState({
+ showPopover: true
+ });
+ }
+
+ handleCloseCollectionPopover = () => {
+ this.setState({
+ showPopover: false
+ });
+ }
+
handleSketchDuplicate = () => {
this.closeAll();
this.props.cloneProject(this.props.sketch.id);
@@ -186,6 +200,17 @@ class SketchListRowBase extends React.Component {
Duplicate
}
+ {this.props.user.authenticated &&
+
+
+ }
{ /*
}
}
+ {this.state.showPopover && }
);
}
@@ -231,15 +257,16 @@ class SketchListRowBase extends React.Component {
url = `/${username}/sketches/${slugify(sketch.name, '_')}`;
}
return (
-
-
-
- {renameOpen ? '' : sketch.name}
-
- {renameOpen
+
+
+
+
+ {renameOpen ? '' : sketch.name}
+
+ {renameOpen
&&
e.stopPropagation()}
/>
- }
- |
- {format(new Date(sketch.createdAt), 'MMM D, YYYY h:mm A')} |
- {format(new Date(sketch.updatedAt), 'MMM D, YYYY h:mm A')} |
- {this.renderActions()}
- );
+ }
+ |
+ {format(new Date(sketch.createdAt), 'MMM D, YYYY h:mm A')} |
+ {format(new Date(sketch.updatedAt), 'MMM D, YYYY h:mm A')} |
+ {this.renderActions()}
+
+ );
}
}
@@ -290,6 +318,18 @@ class SketchList extends React.Component {
this.props.getProjects(this.props.username);
this.props.resetSorting();
this._renderFieldHeader = this._renderFieldHeader.bind(this);
+
+ this.state = {
+ isInitialDataLoad: true,
+ };
+ }
+
+ componentWillReceiveProps(nextProps) {
+ if (this.props.sketches !== nextProps.sketches && Array.isArray(nextProps.sketches)) {
+ this.setState({
+ isInitialDataLoad: false,
+ });
+ }
}
getSketchesTitle() {
@@ -300,16 +340,20 @@ class SketchList extends React.Component {
}
hasSketches() {
- return !this.props.loading && this.props.sketches.length > 0;
+ return !this.isLoading() && this.props.sketches.length > 0;
+ }
+
+ isLoading() {
+ return this.props.loading && this.state.isInitialDataLoad;
}
_renderLoader() {
- if (this.props.loading) return ;
+ if (this.isLoading()) return ;
return null;
}
_renderEmptyTable() {
- if (!this.props.loading && this.props.sketches.length === 0) {
+ if (!this.isLoading() && this.props.sketches.length === 0) {
return (No sketches.
);
}
return null;
diff --git a/client/styles/components/_collection-popover.scss b/client/styles/components/_collection-popover.scss
new file mode 100644
index 00000000..3c65dda5
--- /dev/null
+++ b/client/styles/components/_collection-popover.scss
@@ -0,0 +1,89 @@
+.collection-popover {
+ position: absolute;
+ height: auto;
+ width: #{400 / $base-font-size}rem;
+ top: 63%;
+ right: calc(100% - 26px);
+
+ z-index: 9999;
+
+ display: flex;
+ flex-direction: column;
+
+ border-radius: #{6 / $base-font-size}rem;
+
+ @include themify() {
+ background-color: map-get($theme-map, 'modal-background-color');
+ border: 1px solid map-get($theme-map, 'modal-border-color');
+ box-shadow: 0 0 18px 0 getThemifyVariable('shadow-color');
+ color: getThemifyVariable('dropdown-color');
+ }
+
+ text-align: left;
+}
+
+.collection-popover__header {
+ display: flex;
+ margin-left: #{17 / $base-font-size}rem;
+ margin-right: #{17 / $base-font-size}rem;
+}
+
+.collection-popover__filter {
+ display: flex;
+ margin-bottom: #{8 / $base-font-size}rem;
+}
+
+.collection-popover__exit-button {
+ @include icon();
+ margin-left: auto;
+}
+
+.collection-popover__items {
+ height: #{70 * 4 / $base-font-size}rem;
+ overflow: auto;
+}
+
+
+.collection-popover__item {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+
+ height: #{60 / $base-font-size}rem;
+ margin: 5px;
+ padding: 5px;
+}
+
+.collection-popover__item:nth-child(odd) {
+ @include themify() {
+ background: getThemifyVariable('table-row-stripe-color');
+ }
+}
+
+.collection-popover__item__info {
+ flex: 1;
+ width: 100%;
+ height: 100%;
+
+ display: flex;
+ justify-content: stretch;
+ align-items: stretch;
+}
+
+.collection-popover__item__info button,
+.collection-popover__item__info button:hover {
+ flex: 1;
+ width: 100%;
+ height: 100%;
+
+ text-align: left;
+ color: black;
+}
+
+.collection-popover__item__view {
+}
+
+
+.collection-popover__item__view-button {
+ @extend %button;
+}
diff --git a/client/styles/main.scss b/client/styles/main.scss
index afcc2d14..d0b9833b 100644
--- a/client/styles/main.scss
+++ b/client/styles/main.scss
@@ -51,6 +51,7 @@
@import 'components/editable-input';
@import 'components/collection';
@import 'components/collection-create';
+@import 'components/collection-popover';
@import 'layout/dashboard';
@import 'layout/ide';