* re #168, add totalsize to response from API, add loader to asset list, add totalsize to asset list ui * re #168, add totalsize to response from API, add loader to asset list, add totalsize to asset list ui * update asset list copy to remove limit, since that's not implemented yet
This commit is contained in:
parent
4c1ebdf83d
commit
d64498ef1f
5 changed files with 61 additions and 20 deletions
|
@ -1,26 +1,32 @@
|
||||||
import axios from 'axios';
|
import axios from 'axios';
|
||||||
|
|
||||||
import * as ActionTypes from '../../../constants';
|
import * as ActionTypes from '../../../constants';
|
||||||
|
import { startLoader, stopLoader } from './loader';
|
||||||
|
|
||||||
const __process = (typeof global !== 'undefined' ? global : window).process;
|
const __process = (typeof global !== 'undefined' ? global : window).process;
|
||||||
const ROOT_URL = __process.env.API_URL;
|
const ROOT_URL = __process.env.API_URL;
|
||||||
|
|
||||||
function setAssets(assets) {
|
function setAssets(assets, totalSize) {
|
||||||
return {
|
return {
|
||||||
type: ActionTypes.SET_ASSETS,
|
type: ActionTypes.SET_ASSETS,
|
||||||
assets
|
assets,
|
||||||
|
totalSize
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getAssets() {
|
export function getAssets() {
|
||||||
return (dispatch, getState) => {
|
return (dispatch) => {
|
||||||
|
dispatch(startLoader());
|
||||||
axios.get(`${ROOT_URL}/S3/objects`, { withCredentials: true })
|
axios.get(`${ROOT_URL}/S3/objects`, { withCredentials: true })
|
||||||
.then((response) => {
|
.then((response) => {
|
||||||
dispatch(setAssets(response.data.assets));
|
dispatch(setAssets(response.data.assets, response.data.totalSize));
|
||||||
|
dispatch(stopLoader());
|
||||||
})
|
})
|
||||||
.catch(response => dispatch({
|
.catch(() => {
|
||||||
type: ActionTypes.ERROR
|
dispatch({
|
||||||
}));
|
type: ActionTypes.ERROR
|
||||||
|
});
|
||||||
|
dispatch(stopLoader());
|
||||||
|
});
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,12 +4,11 @@ import { connect } from 'react-redux';
|
||||||
import { bindActionCreators } from 'redux';
|
import { bindActionCreators } from 'redux';
|
||||||
import { Link } from 'react-router';
|
import { Link } from 'react-router';
|
||||||
import { Helmet } from 'react-helmet';
|
import { Helmet } from 'react-helmet';
|
||||||
|
|
||||||
import prettyBytes from 'pretty-bytes';
|
import prettyBytes from 'pretty-bytes';
|
||||||
|
|
||||||
|
import Loader from '../../App/components/loader';
|
||||||
import * as AssetActions from '../actions/assets';
|
import * as AssetActions from '../actions/assets';
|
||||||
|
|
||||||
|
|
||||||
class AssetList extends React.Component {
|
class AssetList extends React.Component {
|
||||||
constructor(props) {
|
constructor(props) {
|
||||||
super(props);
|
super(props);
|
||||||
|
@ -23,17 +22,37 @@ class AssetList extends React.Component {
|
||||||
return `p5.js Web Editor | ${this.props.username}'s assets`;
|
return `p5.js Web Editor | ${this.props.username}'s assets`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
hasAssets() {
|
||||||
|
return !this.props.loading && this.props.assetList.length > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
renderLoader() {
|
||||||
|
if (this.props.loading) return <Loader />;
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
renderEmptyTable() {
|
||||||
|
if (!this.props.loading && this.props.assetList.length === 0) {
|
||||||
|
return (<p className="asset-table__empty">No uploaded assets.</p>);
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const username = this.props.username !== undefined ? this.props.username : this.props.user.username;
|
const username = this.props.username !== undefined ? this.props.username : this.props.user.username;
|
||||||
|
const { assetList, totalSize } = this.props;
|
||||||
return (
|
return (
|
||||||
<div className="asset-table-container">
|
<div className="asset-table-container">
|
||||||
|
{/* Eventually, this copy should be Total / 250 MB Used */}
|
||||||
|
{this.hasAssets() &&
|
||||||
|
<p className="asset-table__total">{`${prettyBytes(totalSize)} Total`}</p>
|
||||||
|
}
|
||||||
<Helmet>
|
<Helmet>
|
||||||
<title>{this.getAssetsTitle()}</title>
|
<title>{this.getAssetsTitle()}</title>
|
||||||
</Helmet>
|
</Helmet>
|
||||||
{this.props.assets.length === 0 &&
|
{this.renderLoader()}
|
||||||
<p className="asset-table__empty">No uploaded assets.</p>
|
{this.renderEmptyTable()}
|
||||||
}
|
{this.hasAssets() &&
|
||||||
{this.props.assets.length > 0 &&
|
|
||||||
<table className="asset-table">
|
<table className="asset-table">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
|
@ -44,7 +63,7 @@ class AssetList extends React.Component {
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
{this.props.assets.map(asset =>
|
{assetList.map(asset =>
|
||||||
(
|
(
|
||||||
<tr className="asset-table__row" key={asset.key}>
|
<tr className="asset-table__row" key={asset.key}>
|
||||||
<td>{asset.name}</td>
|
<td>{asset.name}</td>
|
||||||
|
@ -65,20 +84,24 @@ AssetList.propTypes = {
|
||||||
username: PropTypes.string
|
username: PropTypes.string
|
||||||
}).isRequired,
|
}).isRequired,
|
||||||
username: PropTypes.string.isRequired,
|
username: PropTypes.string.isRequired,
|
||||||
assets: PropTypes.arrayOf(PropTypes.shape({
|
assetList: PropTypes.arrayOf(PropTypes.shape({
|
||||||
key: PropTypes.string.isRequired,
|
key: PropTypes.string.isRequired,
|
||||||
name: PropTypes.string.isRequired,
|
name: PropTypes.string.isRequired,
|
||||||
url: PropTypes.string.isRequired,
|
url: PropTypes.string.isRequired,
|
||||||
sketchName: PropTypes.string.isRequired,
|
sketchName: PropTypes.string.isRequired,
|
||||||
sketchId: PropTypes.string.isRequired
|
sketchId: PropTypes.string.isRequired
|
||||||
})).isRequired,
|
})).isRequired,
|
||||||
|
totalSize: PropTypes.number.isRequired,
|
||||||
getAssets: PropTypes.func.isRequired,
|
getAssets: PropTypes.func.isRequired,
|
||||||
|
loading: PropTypes.bool.isRequired
|
||||||
};
|
};
|
||||||
|
|
||||||
function mapStateToProps(state) {
|
function mapStateToProps(state) {
|
||||||
return {
|
return {
|
||||||
user: state.user,
|
user: state.user,
|
||||||
assets: state.assets
|
assetList: state.assets.list,
|
||||||
|
totalSize: state.assets.totalSize,
|
||||||
|
loading: state.loading
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,9 +1,15 @@
|
||||||
import * as ActionTypes from '../../../constants';
|
import * as ActionTypes from '../../../constants';
|
||||||
|
|
||||||
const assets = (state = [], action) => {
|
// 1,000,000 bytes in a MB. can't upload if totalSize is bigger than this.
|
||||||
|
const initialState = {
|
||||||
|
list: [],
|
||||||
|
totalSize: 0
|
||||||
|
};
|
||||||
|
|
||||||
|
const assets = (state = initialState, action) => {
|
||||||
switch (action.type) {
|
switch (action.type) {
|
||||||
case ActionTypes.SET_ASSETS:
|
case ActionTypes.SET_ASSETS:
|
||||||
return action.assets;
|
return { list: action.assets, totalSize: action.totalSize };
|
||||||
default:
|
default:
|
||||||
return state;
|
return state;
|
||||||
}
|
}
|
||||||
|
|
|
@ -54,3 +54,7 @@
|
||||||
text-align: center;
|
text-align: center;
|
||||||
font-size: #{16 / $base-font-size}rem;
|
font-size: #{16 / $base-font-size}rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.asset-table__total {
|
||||||
|
padding: 0 #{20 / $base-font-size}rem;
|
||||||
|
}
|
||||||
|
|
|
@ -126,6 +126,7 @@ export function listObjectsInS3ForUser(req, res) {
|
||||||
.on('end', () => {
|
.on('end', () => {
|
||||||
const projectAssets = [];
|
const projectAssets = [];
|
||||||
getProjectsForUserId(userId).then((projects) => {
|
getProjectsForUserId(userId).then((projects) => {
|
||||||
|
let totalSize = 0;
|
||||||
assets.forEach((asset) => {
|
assets.forEach((asset) => {
|
||||||
const name = asset.key.split('/').pop();
|
const name = asset.key.split('/').pop();
|
||||||
const foundAsset = {
|
const foundAsset = {
|
||||||
|
@ -134,6 +135,7 @@ export function listObjectsInS3ForUser(req, res) {
|
||||||
size: asset.size,
|
size: asset.size,
|
||||||
url: `${process.env.S3_BUCKET_URL_BASE}${asset.key}`
|
url: `${process.env.S3_BUCKET_URL_BASE}${asset.key}`
|
||||||
};
|
};
|
||||||
|
totalSize += asset.size;
|
||||||
projects.some((project) => {
|
projects.some((project) => {
|
||||||
let found = false;
|
let found = false;
|
||||||
project.files.some((file) => {
|
project.files.some((file) => {
|
||||||
|
@ -152,7 +154,7 @@ export function listObjectsInS3ForUser(req, res) {
|
||||||
});
|
});
|
||||||
projectAssets.push(foundAsset);
|
projectAssets.push(foundAsset);
|
||||||
});
|
});
|
||||||
res.json({ assets: projectAssets });
|
res.json({ assets: projectAssets, totalSize });
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in a new issue