/* * * Home * */ import React from 'react'; import { connect } from 'react-redux'; import { bindActionCreators } from 'redux'; import { createStructuredSelector } from 'reselect'; // modal import { Button, Modal, ModalHeader, ModalBody, ModalFooter } from 'reactstrap'; import { find, findIndex, findKey, forEach, get, isEmpty, includes, isObject, map, replace, toNumber, } from 'lodash'; import { FormattedMessage } from 'react-intl'; import Helmet from 'react-helmet'; import { router } from 'app'; // design import ContentHeader from 'components/ContentHeader'; import Debug from 'components/Debug'; import EditForm from 'components/EditForm'; import HeaderNav from 'components/HeaderNav'; import List from 'components/List'; import { makeSelectSections, makeSelectEnvironments } from 'containers/App/selectors'; import selectHome from './selectors'; import { cancelChanges, changeDefaultLanguage, changeInput, configFetch, databasesFetch, databaseDelete, editSettings, languageDelete, languagesFetch, newLanguagePost, newDatabasePost, } from './actions' import styles from './styles.scss'; import config from './config.json'; export class Home extends React.Component { // eslint-disable-line react/prefer-stateless-function constructor(props) { super(props); this.customComponents = config.customComponents; this.components = { editForm: EditForm, list: List, defaultComponent: HeaderNav, debug: Debug, }; // allowing state only for database modal purpose this.state = { modal: false, }; } componentDidMount() { if (this.props.params.slug) { this.handleFetch(this.props); } else { router.push(`/plugins/settings-manager/${get(this.props.menuSections, ['0', 'items', '0', 'slug'])}`); } } componentWillReceiveProps(nextProps) { // check if params slug updated if (this.props.params.slug !== nextProps.params.slug && nextProps.params.slug) { if (nextProps.params.slug) { // get data from api if params slug updated this.handleFetch(nextProps); } else { // redirect user if no params slug provided router.push(`/plugins/settings-manager/${get(this.props.menuSections, ['0', 'items', '0', 'slug'])}`); } } else if (this.props.params.env !== nextProps.params.env && nextProps.params.env && this.props.params.env) { // get data if params env updated this.handleFetch(nextProps); } } componentDidUpdate(prevProps) { if (prevProps.home.didCreatedNewLanguage !== this.props.home.didCreatedNewLanguage) { this.handleFetch(this.props); } if (prevProps.home.didCreatedNewDb !== this.props.home.didCreatedNewDb) { this.handleFetch(this.props); } } /* eslint-disable react/sort-comp */ /* eslint-disable jsx-a11y/no-static-element-interactions */ addConnection = (e) => { e.preventDefault(); // TODO add connection const newData = {}; /* eslint-disable no-template-curly-in-string */ const dbName = get(this.props.home.modifiedData, 'database.connections.${name}.name'); map(this.props.home.modifiedData, (data, key) => { const k = replace(key, '${name}', dbName); if (key !== 'database.connections.${name}.name' && key !== 'database.defaultConnection') { newData[k] = data; } }); /* eslint-enable no-template-curly-in-string */ if (this.props.home.modifiedData['database.defaultConnection']) { newData['database.defaultConnection'] = dbName; } this.props.newDatabasePost(this.props.params.env, newData); } changeDefaultLanguage = ({ target }) => { // create new object configsDisplay based on store property configsDisplay const configsDisplay = { name: this.props.home.configsDisplay.name, description: this.props.home.configsDisplay.description, sections: [], }; // Find the index of the new setted language const activeLanguageIndex = findIndex(this.props.home.configsDisplay.sections, ['name', target.id]); forEach(this.props.home.configsDisplay.sections, (section, key) => { // set all Language active state to false if (key !== activeLanguageIndex) { configsDisplay.sections.push({ name: section.name, active: false }); } else { // set the new language active state to true configsDisplay.sections.push({ name: section.name, active: true }); } }); // reset all the configs to ensure component is updated this.props.changeDefaultLanguage(configsDisplay, target.id); // Edit the new config this.props.editSettings({ 'i18n.i18n.defaultLocale': target.id }, 'i18n'); } handleFetch(props) { const apiUrl = props.params.env ? `${props.params.slug}/${props.params.env}` : props.params.slug; switch(props.params.slug) { case 'languages': return this.props.languagesFetch(); case 'databases': return this.props.databasesFetch(props.params.env); default: return this.props.configFetch(apiUrl); } } handleChange = ({ target }) => { const value = target.type === 'number' ? toNumber(target.value) : target.value; this.props.changeInput(target.name, value); } handleCancel = () => { this.props.cancelChanges(); } handleSubmit = (e) => { e.preventDefault(); const prevSettings = this.props.home.initialData; const body = {}; const apiUrl = this.props.params.env ? `${this.props.params.slug}/${this.props.params.env}` : this.props.params.slug; // send only updated settings forEach(this.props.home.modifiedData, (value, key) => { if (value !== prevSettings[key]) { body[key] = value; } }); if (!isEmpty(body)) { this.props.editSettings(body, apiUrl); } else { window.Strapi.notification.error('Settings are equals'); } } handleLanguageDelete = ({ target }) => { // Display notification window.Strapi.notification.success('Deleting language...'); // retrieve the language to delete using the target id this.props.languageDelete(target.id); } handleDatabaseDelete = ({ target }) => { console.log(target); this.props.databaseDelete(target.id, this.props.params.env); console.log('will detele'); } // custom Row rendering for the component List with params slug === languages renderRowLanguage = (props, key, liStyles) => { // assign the target id the language name to prepare for delete const deleteIcon = props.active ? '' : ; // eslint-disable-line jsx-a11y/no-static-element-interactions // retrieve language name from i18n translation const languageObject = find(get(this.props.home.listLanguages, ['sections', '0', 'items', '0', 'items']), ['value', props.name]); // apply i18n const languageDisplay = isObject(languageObject) ? : ''; const languageLabel = props.active ? : // set the span's id with the language name to retrieve it {(message) => ( )} ; return (
  • {key}
    {languageDisplay}
    {props.name}
    {languageLabel}
    {deleteIcon}
  • ) } renderListTitle = () => { const availableContentNumber = this.props.home.configsDisplay.sections.length; const title = availableContentNumber > 1 ? `list.${this.props.params.slug}.title.plural` : `list.${this.props.params.slug}.title.singular`; const titleDisplay = title ? : ''; return {availableContentNumber} {titleDisplay} } renderListButtonLabel = () => `list.${this.props.params.slug}.button.label`; renderPopUpFormDatabase = (section, props, popUpStyles) => ( map(section.items, (item, key) => { const isActive = props.values[item.target] ?
    : ''; if (item.name === 'form.database.item.default') { return (
    {item.name}{isActive}
    ); } return ( props.renderInput(item, key) ); }) ) renderPopUpFormLanguage = (section, props) => ( map(section.items, (item, key) => (
    {props.renderInput(item, key)}
    )) ) renderRowDatabase = (props, key, listStyles) => (
  • {props.letter}
    {props.name}
    {props.database}
    {props.host}
    Databases
    {' '}
  • ) renderComponent = () => { // check if settingName (params.slug) has a custom view display const specificComponent = findKey(this.customComponents, (value) => includes(value, this.props.params.slug)) || 'defaultComponent'; // if custom view display render specificComponent const Component = this.components[specificComponent]; const listTitle = this.props.params.slug === 'languages' || 'databases' ? this.renderListTitle() : ''; const listButtonLabel = this.props.params.slug === 'languages' || 'databases' ? this.renderListButtonLabel() : ''; // check if HeaderNav component needs to render a form or a list const renderListComponent = this.props.params.slug === 'databases'; let handleListPopUpSubmit; // sections is the props used by EditForm in case of list of table rendering we need to change its value let sections; let renderPopUpForm = false; let renderRow = false; switch (this.props.params.slug) { case 'languages': sections = this.props.home.listLanguages.sections; // custom rendering for PopUpForm renderPopUpForm = this.renderPopUpFormLanguage; renderRow = this.renderRowLanguage; handleListPopUpSubmit = this.props.newLanguagePost; break; case 'databases': sections = this.props.home.addDatabaseSection.sections; renderPopUpForm = this.renderPopUpFormDatabase; handleListPopUpSubmit = this.addConnection; renderRow = this.renderRowDatabase; break; default: sections = this.props.home.configsDisplay.sections; } // custom selectOptions for languages const selectOptions = this.props.params.slug === 'languages' ? this.props.home.listLanguages : []; return ( ); } showDatabaseModal = () => { // allow state here just for modal purpose this.setState({ modal: !this.state.modal }); } setDefaultConnectionDb = (e) => { const target = { name: e.target.id, value: !this.props.home.modifiedData[e.target.id] } this.handleChange({target}); } // Hide database modal toggle = () => { this.setState({ modal: !this.state.modal }); } render() { if (this.props.home.loading) { return
    ; } return (
    {this.renderComponent()}
    ); } } const mapStateToProps = createStructuredSelector({ environments: makeSelectEnvironments(), home: selectHome(), menuSections: makeSelectSections(), }) function mapDispatchToProps(dispatch) { return bindActionCreators( { cancelChanges, changeDefaultLanguage, changeInput, configFetch, databaseDelete, databasesFetch, editSettings, languageDelete, languagesFetch, newDatabasePost, newLanguagePost, }, dispatch ) } Home.propTypes = { cancelChanges: React.PropTypes.func, changeDefaultLanguage: React.PropTypes.func, changeInput: React.PropTypes.func, configFetch: React.PropTypes.func.isRequired, databaseDelete: React.PropTypes.func, databasesFetch: React.PropTypes.func, editSettings: React.PropTypes.func, environments: React.PropTypes.array, home: React.PropTypes.object, languageDelete: React.PropTypes.func, languagesFetch: React.PropTypes.func, location: React.PropTypes.object, menuSections: React.PropTypes.array, newDatabasePost: React.PropTypes.func, newLanguagePost: React.PropTypes.func, params: React.PropTypes.object.isRequired, }; export default connect(mapStateToProps, mapDispatchToProps)(Home);