Skip to content

Commit

Permalink
Fix history list to load last in the stack
Browse files Browse the repository at this point in the history
Fix moved loading overlay to the Gallery only, rather than the entire screen
  • Loading branch information
Christopher Joe committed Jul 31, 2017
1 parent 9ba9ff0 commit cb7d157
Show file tree
Hide file tree
Showing 5 changed files with 70 additions and 74 deletions.
2 changes: 1 addition & 1 deletion client/dist/js/bundle.js

Large diffs are not rendered by default.

4 changes: 0 additions & 4 deletions client/src/containers/AssetAdmin/AssetAdmin.js
Expand Up @@ -596,10 +596,6 @@ class AssetAdmin extends SilverStripeComponent {
{this.renderGallery()}
{this.renderEditor()}
</div>
{this.props.loading &&
[<div key="overlay" className="cms-content-loading-overlay ui-widget-overlay-light"></div>,
<div key="spinner" className="cms-content-loading-spinner"></div>]
}
</div>
);
}
Expand Down
33 changes: 10 additions & 23 deletions client/src/containers/Gallery/Gallery.js
Expand Up @@ -100,8 +100,6 @@ class Gallery extends Component {
if (!this.compareFiles(this.props.files, nextProps.files)) {
nextProps.actions.queuedFiles.purgeUploadQueue();
}

this.checkLoadingIndicator(nextProps);
}

componentDidUpdate() {
Expand Down Expand Up @@ -190,26 +188,6 @@ class Gallery extends Component {
);
}

/**
* Required anti-pattern, because `.cms-content` is the container for the React component.
*
* Adds or removes the load class from `.cms-content` if it is for the AssetAdmin
*
* @param {Object} props
*/
checkLoadingIndicator(props) {
const $sectionWrapper = $('.cms-content.AssetAdmin');
if (!$sectionWrapper.length) {
return;
}

if (props.loading) {
$sectionWrapper.addClass('loading');
} else {
$sectionWrapper.removeClass('loading');
}
}

/**
* Compare two lists to see if equal
*
Expand Down Expand Up @@ -844,7 +822,12 @@ class Gallery extends Component {
);
}
if (this.props.loading) {
return <div className="flexbox-area-grow"></div>;
return (
<div className="flexbox-area-grow">
<div key="overlay" className="cms-content-loading-overlay ui-widget-overlay-light"></div>
<div key="spinner" className="cms-content-loading-spinner"></div>
</div>
);
}
return (
<div className="flexbox-area-grow">
Expand Down Expand Up @@ -918,6 +901,10 @@ class Gallery extends Component {
{this.renderGalleryView()}
</GalleryDND>
</AssetDropzone>
{ this.props.loading && [
<div key="overlay" className="cms-content-loading-overlay ui-widget-overlay-light"></div>,
<div key="spinner" className="cms-content-loading-spinner"></div>,
]}
</div>
);
}
Expand Down
101 changes: 57 additions & 44 deletions client/src/containers/HistoryList/HistoryList.js
Expand Up @@ -7,6 +7,23 @@ import FormBuilderLoader from 'containers/FormBuilderLoader/FormBuilderLoader';

const sectionConfigKey = 'SilverStripe\\AssetAdmin\\Controller\\AssetAdmin';

/**
* Create a new endpoint
*
* @todo duplication with assetadmin.
*
* @param {Object} endpointConfig
* @param {Boolean} includeToken
* @returns {Function}
*/
const createEndpoint = (endpointConfig, includeToken = true) => (
backend.createEndpointFetcher(Object.assign(
{},
endpointConfig,
includeToken ? { defaultData: { SecurityID: Config.get('SecurityID') } } : {}
))
);

class HistoryList extends Component {

constructor(props) {
Expand All @@ -15,14 +32,15 @@ class HistoryList extends Component {
this.state = {
detailView: null,
history: [],
/* TODO loading */
loadedDetails: true,
loadedDetails: false,
};

this.handleClick = this.handleClick.bind(this);
this.handleBack = this.handleBack.bind(this);

this.api = this.createEndpoint(props.sectionConfig.historyEndpoint);
this.timer = null;

this.api = createEndpoint(props.sectionConfig.historyEndpoint);
}

componentDidMount() {
Expand All @@ -34,13 +52,8 @@ class HistoryList extends Component {
this.refreshHistoryIfNeeded(nextProps);
}

/**
* @returns {string} class
*/
getContainerClassName() {
return (this.state.viewDetails && !this.state.loadedDetails)
? 'history-list history-container--loading'
: 'history-list';
componentWillUnmount() {
clearTimeout(this.timer);
}

/**
Expand All @@ -49,15 +62,28 @@ class HistoryList extends Component {
* @param {object} nextProps
*/
refreshHistoryIfNeeded(nextProps) {
if (!nextProps
if (
(!nextProps && !this.state.loadedDetails)
|| (nextProps.data.fileId !== this.props.data.fileId)
|| (nextProps.data.latestVersionId !== this.props.data.latestVersionId)
) {
this.api({
fileId: (nextProps) ? nextProps.data.fileId : this.props.data.fileId,
}).then((history) => {
this.setState({ history });
});
this.setState({ loadedDetails: false });
const fileId = (nextProps) ? nextProps.data.fileId : this.props.data.fileId;
clearTimeout(this.timer);

/*
* This needs a delay/throttle, so this api request tries to be made last in the stack.
* We also use this to stop an API call happening if the component is going to
* unmount soon.
* TODO: This could potentially be solved by using apollo-client's caching and graphql.
*/
this.timer = setTimeout(() => {
this.api({
fileId,
}).then((history) => {
this.setState({ history, loadedDetails: true });
});
}, 250);
}
}

Expand All @@ -83,57 +109,44 @@ class HistoryList extends Component {
});
}

/**
* Create a new endpoint
*
* @todo duplication with assetadmin.
*
* @param {Object} endpointConfig
* @param {Boolean} includeToken
* @returns {Function}
*/
createEndpoint(endpointConfig, includeToken = true) {
return backend.createEndpointFetcher(Object.assign(
{},
endpointConfig,
includeToken ? { defaultData: { SecurityID: Config.get('SecurityID') } } : {}
));
}

render() {
const containerClassName = this.getContainerClassName();
if (!this.state.history) {
if (!this.state.loadedDetails) {
return (
<div className={containerClassName} />
<div className="history-list history-list--loading">
Loading...
</div>
);
}

if (this.state.viewDetails) {
let schemaUrl = [
const schemaUrl = [
this.props.historySchemaUrl,
this.props.data.fileId,
this.state.viewDetails,
].join('/');

let className = [
'btn btn-secondary',
'btn--icon-xl btn--no-text',
const buttonClasses = [
'btn',
'btn-secondary',
'btn--icon-xl',
'btn--no-text',
'font-icon-left-open-big',
'history-list__back',
].join(' ');

return (
<div className={containerClassName}>
<a className={className} onClick={this.handleBack} />
<div className="history-list">
<a className={buttonClasses} onClick={this.handleBack} />
<FormBuilderLoader identifier="AssetAdmin.HistoryList" schemaUrl={schemaUrl} />
</div>
);
}

const historyList = this.state.history || [];
return (
<div className={containerClassName}>
<div className="history-list">
<ul className="list-group list-group-flush history-list__list">
{this.state.history.map((history) => (
{historyList.map((history) => (
<HistoryItem
key={history.versionid}
{...history}
Expand Down
4 changes: 2 additions & 2 deletions code/Controller/AssetAdmin.php
Expand Up @@ -509,8 +509,8 @@ public function apiHistory(HTTPRequest $request)
}
}

return
(new HTTPResponse(json_encode($output)))->addHeader('Content-Type', 'application/json');
$response = new HTTPResponse(json_encode($output));
return $response->addHeader('Content-Type', 'application/json');
}

/**
Expand Down

0 comments on commit cb7d157

Please sign in to comment.