mirror of
https://github.com/wassname/talk.git
synced 2026-09-12 13:01:11 +08:00
Merge branch 'master' into performance-enhancements
This commit is contained in:
@@ -87,7 +87,7 @@ const CoralHeader = ({
|
||||
</a>
|
||||
</MenuItem>
|
||||
<MenuItem>
|
||||
<a href="https://coralproject.net/contribute.html#other-ideas-and-bug-reports" target="_blank" rel="noopener noreferrer">
|
||||
<a href="https://support.coralproject.net" target="_blank" rel="noopener noreferrer">
|
||||
Report a bug or give feedback
|
||||
</a>
|
||||
</MenuItem>
|
||||
|
||||
@@ -1,15 +1,5 @@
|
||||
import update from 'immutability-helper';
|
||||
import mapValues from 'lodash/mapValues';
|
||||
|
||||
// Map nested object leaves. Array objects are considered leaves.
|
||||
function mapLeaves(o, mapper) {
|
||||
return mapValues(o, (val) => {
|
||||
if (typeof val === 'object' && !Array.isArray(val)) {
|
||||
return mapLeaves(val, mapper);
|
||||
}
|
||||
return mapper(val);
|
||||
});
|
||||
}
|
||||
import {mapLeaves} from 'coral-framework/utils';
|
||||
|
||||
export default {
|
||||
mutations: {
|
||||
|
||||
@@ -39,7 +39,7 @@ class ModerationSettings extends React.Component {
|
||||
};
|
||||
|
||||
render() {
|
||||
const {settings, data, root} = this.props;
|
||||
const {settings, data, root, updatePending, errors} = this.props;
|
||||
|
||||
return (
|
||||
<ConfigurePage
|
||||
@@ -74,6 +74,8 @@ class ModerationSettings extends React.Component {
|
||||
fill="adminModerationSettings"
|
||||
data={data}
|
||||
queryData={{root, settings}}
|
||||
updatePending={updatePending}
|
||||
errors={errors}
|
||||
/>
|
||||
</ConfigurePage>
|
||||
);
|
||||
@@ -82,6 +84,7 @@ class ModerationSettings extends React.Component {
|
||||
|
||||
ModerationSettings.propTypes = {
|
||||
updatePending: PropTypes.func.isRequired,
|
||||
errors: PropTypes.object.isRequired,
|
||||
data: PropTypes.object.isRequired,
|
||||
root: PropTypes.object.isRequired,
|
||||
settings: PropTypes.object.isRequired,
|
||||
|
||||
@@ -53,3 +53,6 @@
|
||||
|
||||
|
||||
|
||||
.autoCloseWrapper {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
@@ -100,7 +100,7 @@ class StreamSettings extends React.Component {
|
||||
};
|
||||
|
||||
render() {
|
||||
const {settings, data, root, errors} = this.props;
|
||||
const {settings, data, root, errors, updatePending} = this.props;
|
||||
|
||||
return (
|
||||
<ConfigurePage
|
||||
@@ -180,22 +180,24 @@ class StreamSettings extends React.Component {
|
||||
onCheckbox={this.updateAutoClose}
|
||||
title={t('configure.close_after')}
|
||||
>
|
||||
<Textfield
|
||||
type='number'
|
||||
pattern='[0-9]+'
|
||||
style={{width: 50}}
|
||||
onChange={this.updateClosedTimeout}
|
||||
value={getTimeoutAmount(settings.closedTimeout)}
|
||||
label={t('configure.closed_comments_label')} />
|
||||
<div className={styles.configTimeoutSelect}>
|
||||
<SelectField
|
||||
label="comments closed time window"
|
||||
value={getTimeoutMeasure(settings.closedTimeout)}
|
||||
onChange={this.updateClosedTimeoutMeasure}>
|
||||
<Option value={'hours'}>{t('configure.hours')}</Option>
|
||||
<Option value={'days'}>{t('configure.days')}</Option>
|
||||
<Option value={'weeks'}>{t('configure.weeks')}</Option>
|
||||
</SelectField>
|
||||
<div className={styles.autoCloseWrapper}>
|
||||
<Textfield
|
||||
type='number'
|
||||
pattern='[0-9]+'
|
||||
style={{width: 50}}
|
||||
onChange={this.updateClosedTimeout}
|
||||
value={getTimeoutAmount(settings.closedTimeout)}
|
||||
label={t('configure.closed_comments_label')} />
|
||||
<div className={styles.configTimeoutSelect}>
|
||||
<SelectField
|
||||
label="comments closed time window"
|
||||
value={getTimeoutMeasure(settings.closedTimeout)}
|
||||
onChange={this.updateClosedTimeoutMeasure}>
|
||||
<Option value={'hours'}>{t('configure.hours')}</Option>
|
||||
<Option value={'days'}>{t('configure.days')}</Option>
|
||||
<Option value={'weeks'}>{t('configure.weeks')}</Option>
|
||||
</SelectField>
|
||||
</div>
|
||||
</div>
|
||||
</ConfigureCard>
|
||||
{/* the above card should be the last one if at all possible because of z-index issues with the selects */}
|
||||
@@ -203,6 +205,8 @@ class StreamSettings extends React.Component {
|
||||
fill="adminStreamSettings"
|
||||
data={data}
|
||||
queryData={{root, settings}}
|
||||
updatePending={updatePending}
|
||||
errors={errors}
|
||||
/>
|
||||
</ConfigurePage>
|
||||
);
|
||||
|
||||
@@ -31,7 +31,7 @@ class TechSettings extends React.Component {
|
||||
};
|
||||
|
||||
render() {
|
||||
const {settings, data, root} = this.props;
|
||||
const {settings, data, root, errors, updatePending} = this.props;
|
||||
return (
|
||||
<ConfigurePage
|
||||
title={t('configure.tech_settings')}
|
||||
@@ -51,6 +51,8 @@ class TechSettings extends React.Component {
|
||||
fill="adminTechSettings"
|
||||
data={data}
|
||||
queryData={{root, settings}}
|
||||
updatePending={updatePending}
|
||||
errors={errors}
|
||||
/>
|
||||
</ConfigurePage>
|
||||
);
|
||||
@@ -59,6 +61,7 @@ class TechSettings extends React.Component {
|
||||
|
||||
TechSettings.propTypes = {
|
||||
updatePending: PropTypes.func.isRequired,
|
||||
errors: PropTypes.object.isRequired,
|
||||
data: PropTypes.object.isRequired,
|
||||
root: PropTypes.object.isRequired,
|
||||
settings: PropTypes.object.isRequired,
|
||||
|
||||
@@ -2,38 +2,20 @@ import React, {Component} from 'react';
|
||||
import {connect} from 'react-redux';
|
||||
import {bindActionCreators} from 'redux';
|
||||
import {compose, gql} from 'react-apollo';
|
||||
import withQuery from 'coral-framework/hocs/withQuery';
|
||||
import {withQuery, withMergedSettings} from 'coral-framework/hocs';
|
||||
import {Spinner} from 'coral-ui';
|
||||
import {notify} from 'coral-framework/actions/notification';
|
||||
import PropTypes from 'prop-types';
|
||||
import assignWith from 'lodash/assignWith';
|
||||
import {withUpdateSettings} from 'coral-framework/graphql/mutations';
|
||||
import {getErrorMessages, getDefinitionName} from 'coral-framework/utils';
|
||||
import StreamSettings from './StreamSettings';
|
||||
import TechSettings from './TechSettings';
|
||||
import ModerationSettings from './ModerationSettings';
|
||||
import {clearPending, setActiveSection} from '../../../actions/configure';
|
||||
|
||||
import Configure from '../components/Configure';
|
||||
|
||||
// Like lodash merge but does not recurse into arrays.
|
||||
const mergeExcludingArrays = (objValue, srcValue) => {
|
||||
if (typeof srcValue === 'object' && !Array.isArray(srcValue)) {
|
||||
return assignWith({}, objValue, srcValue, mergeExcludingArrays);
|
||||
}
|
||||
return srcValue;
|
||||
};
|
||||
|
||||
class ConfigureContainer extends Component {
|
||||
|
||||
// Merge current settings with pending settings.
|
||||
getMergedSettings = (props = this.props) => {
|
||||
return assignWith({}, props.root.settings, props.pending, mergeExcludingArrays);
|
||||
}
|
||||
|
||||
// Cached merged settings.
|
||||
mergedSettings = this.getMergedSettings();
|
||||
|
||||
savePending = async () => {
|
||||
try {
|
||||
await this.props.updateSettings(this.props.pending);
|
||||
@@ -44,14 +26,6 @@ class ConfigureContainer extends Component {
|
||||
}
|
||||
};
|
||||
|
||||
componentWillReceiveProps(nextProps) {
|
||||
|
||||
// Recalculate merged settings when necessary.
|
||||
if (this.props.root.settings !== nextProps.root.settings || this.props.pending !== nextProps.pending) {
|
||||
this.mergedSettings = this.getMergedSettings(nextProps);
|
||||
}
|
||||
}
|
||||
|
||||
render () {
|
||||
if(this.props.data.loading) {
|
||||
return <Spinner/>;
|
||||
@@ -62,7 +36,7 @@ class ConfigureContainer extends Component {
|
||||
auth={this.props.auth}
|
||||
data={this.props.data}
|
||||
root={this.props.root}
|
||||
settings={this.mergedSettings}
|
||||
settings={this.props.mergedSettings}
|
||||
canSave={this.props.canSave}
|
||||
savePending={this.savePending}
|
||||
setActiveSection={this.props.setActiveSection}
|
||||
@@ -112,6 +86,7 @@ export default compose(
|
||||
withUpdateSettings,
|
||||
withConfigureQuery,
|
||||
connect(mapStateToProps, mapDispatchToProps),
|
||||
withMergedSettings('root.settings', 'pending', 'mergedSettings'),
|
||||
)(ConfigureContainer);
|
||||
|
||||
ConfigureContainer.propTypes = {
|
||||
@@ -124,5 +99,6 @@ ConfigureContainer.propTypes = {
|
||||
root: PropTypes.object.isRequired,
|
||||
canSave: PropTypes.bool.isRequired,
|
||||
pending: PropTypes.object.isRequired,
|
||||
mergedSettings: PropTypes.object.isRequired,
|
||||
activeSection: PropTypes.string.isRequired,
|
||||
};
|
||||
|
||||
@@ -10,6 +10,10 @@ const slots = [
|
||||
'adminModerationSettings',
|
||||
];
|
||||
|
||||
const mapStateToProps = (state) => ({
|
||||
errors: state.configure.errors,
|
||||
});
|
||||
|
||||
const mapDispatchToProps = (dispatch) =>
|
||||
bindActionCreators({
|
||||
updatePending,
|
||||
@@ -36,5 +40,5 @@ export default compose(
|
||||
}
|
||||
`
|
||||
}),
|
||||
connect(null, mapDispatchToProps),
|
||||
connect(mapStateToProps, mapDispatchToProps),
|
||||
)(ModerationSettings);
|
||||
|
||||
@@ -10,6 +10,10 @@ const slots = [
|
||||
'adminTechSettings',
|
||||
];
|
||||
|
||||
const mapStateToProps = (state) => ({
|
||||
errors: state.configure.errors,
|
||||
});
|
||||
|
||||
const mapDispatchToProps = (dispatch) =>
|
||||
bindActionCreators({
|
||||
updatePending,
|
||||
@@ -33,5 +37,5 @@ export default compose(
|
||||
}
|
||||
`
|
||||
}),
|
||||
connect(null, mapDispatchToProps),
|
||||
connect(mapStateToProps, mapDispatchToProps),
|
||||
)(TechSettings);
|
||||
|
||||
@@ -48,7 +48,7 @@ class Stories extends Component {
|
||||
<div className={styles.optionHeader}>{t('streams.filter_streams')}</div>
|
||||
<div className={styles.optionDetail}>{t('streams.stream_status')}</div>
|
||||
<RadioGroup
|
||||
name='status filter'
|
||||
name='statusFilter'
|
||||
value={filter}
|
||||
childContainer='div'
|
||||
onChange={onSettingChange('filter')}
|
||||
@@ -60,7 +60,7 @@ class Stories extends Component {
|
||||
</RadioGroup>
|
||||
<div className={styles.optionHeader}>{t('streams.sort_by')}</div>
|
||||
<RadioGroup
|
||||
name='sort by'
|
||||
name='sortBy'
|
||||
value={asc}
|
||||
childContainer='div'
|
||||
onChange={onSettingChange('asc')}
|
||||
|
||||
Reference in New Issue
Block a user