/* * * HomePage * */ import React from 'react'; import PropTypes from 'prop-types'; import { connect } from 'react-redux'; import { bindActionCreators, compose } from 'redux'; import { createStructuredSelector } from 'reselect'; import { findIndex, findKey, forEach, get, isEmpty, includes, join, map, replace, toNumber, } from 'lodash'; import { FormattedMessage } from 'react-intl'; import Helmet from 'react-helmet'; import Select from 'react-select'; import { router } from 'app'; // design import ContentHeader from 'components/ContentHeader'; import EditForm from 'components/EditForm'; import HeaderNav from 'components/HeaderNav'; import List from 'components/List'; import RowDatabase from 'components/RowDatabase'; import SelectOptionLanguage from 'components/SelectOptionLanguage'; import RowLanguage from 'components/RowLanguage'; import PluginLeftMenu from 'components/PluginLeftMenu'; // App selectors import { makeSelectSections, makeSelectEnvironments } from 'containers/App/selectors'; // utils import injectReducer from 'utils/injectReducer'; import injectSaga from 'utils/injectSaga'; import { checkFormValidity, getRequiredInputsDb } from '../../utils/inputValidations'; import getFlag, { formatLanguageLocale } from '../../utils/getFlag'; import sendUpdatedParams from '../../utils/sendUpdatedParams'; import selectHomePage from './selectors'; import { cancelChanges, changeDefaultLanguage, changeInput, configFetch, databaseEdit, databasesFetch, databaseDelete, editSettings, emptyDbModifiedData, languageDelete, languagesFetch, newLanguagePost, newDatabasePost, setErrors, specificDatabaseFetch, } from './actions'; import reducer from './reducer'; import saga from './sagas'; import styles from './styles.scss'; import config from './config.json'; export class HomePage extends React.Component { // eslint-disable-line react/prefer-stateless-function constructor(props) { super(props); this.customComponents = config.customComponents; this.components = { // editForm: EditForm, defaultComponent: EditForm, list: List, defaultComponentWithEnvironments: HeaderNav, }; // allowing state only for database modal purpose this.state = { modal: false, toggleDefaultConnection: false, }; this.sendUpdatedParams = sendUpdatedParams.bind(this); } componentDidMount() { if (this.props.match.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.match.params.slug !== nextProps.match.params.slug && nextProps.match.params.slug) { if (nextProps.match.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.match.params.env !== nextProps.match.params.env && nextProps.match.params.env && this.props.match.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(); 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') { newData[k] = data; } }); const formErrors = getRequiredInputsDb(this.props.home.modifiedData, this.props.home.formErrors); if (isEmpty(formErrors)) { // this.props.setErrors([]); this.props.newDatabasePost(this.props.match.params.env, newData); } else { this.props.setErrors(formErrors); } } 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); // format the default locale const defaultLanguageArray = formatLanguageLocale(target.id); // Edit the new config this.props.editSettings({ 'language.defaultLocale': join(defaultLanguageArray, '_') }, 'i18n'); } getDatabase = (databaseName) => { // allow state here just for modal purpose this.props.specificDatabaseFetch(databaseName, this.props.match.params.env); // this.setState({ modal: !this.state.modal }); } handleFetch(props) { const apiUrl = props.match.params.env ? `${props.match.params.slug}/${props.match.params.env}` : props.match.params.slug; switch(props.match.params.slug) { case 'languages': return this.props.languagesFetch(); case 'databases': return this.props.databasesFetch(props.match.params.env); default: return this.props.configFetch(apiUrl); } } handleChange = ({ target }) => { let value = target.type === 'number' && target.value !== '' ? toNumber(target.value) : target.value; let name = target.name; if (this.props.match.params.slug === 'security') { // the only case where the input doesn't have a name if (target.name === '') { name = 'security.xframe.value.nested'; value = target.value; } } if (this.props.match.params.slug === 'databases') { if (name === this.props.home.dbNameTarget) { const formErrors = value === this.props.home.addDatabaseSection.sections[1].items[0].value ? [{ target: name, errors: [{ id: 'settings-manager.request.error.database.exist' }] }] : []; this.props.setErrors(formErrors); } else { this.props.setErrors([]); } } this.props.changeInput(name, value); } handleChangeLanguage = (value) => this.props.changeInput('language.defaultLocale', value.value); handleCancel = () => this.props.cancelChanges(); handleSubmit = (e) => { // eslint-disable-line consistent-return e.preventDefault(); const apiUrl = this.props.match.params.env ? `${this.props.match.params.slug}/${this.props.match.params.env}` : this.props.match.params.slug; const isCreatingNewFields = this.props.match.params.slug === 'security'; // send only updated settings const body = this.sendUpdatedParams(isCreatingNewFields); const formErrors = checkFormValidity(body, this.props.home.formValidations); if (isEmpty(body)) return window.Strapi.notification.info('settings-manager.strapi.notification.info.settingsEqual'); if (isEmpty(formErrors)) { this.props.editSettings(body, apiUrl); } else { this.props.setErrors(formErrors); // window.Strapi.notification.info('Settings are equals'); } } handleSubmitEditDatabase = (databaseName) => { // eslint-disable-line consistent-return const body = this.sendUpdatedParams(); const apiUrl = `${databaseName}/${this.props.match.params.env}`; const formErrors = checkFormValidity(body, this.props.home.formValidations, this.props.home.formErrors); if (isEmpty(body)) return window.Strapi.notification.info('settings-manager.strapi.notification.info.settingsEqual'); if (isEmpty(formErrors)) { this.props.databaseEdit(body, apiUrl); } else { this.props.setErrors(formErrors); } } // retrieve the language to delete using the target id handleLanguageDelete = (languaToDelete) => this.props.languageDelete(languaToDelete); handleDatabaseDelete = (dbName) => { window.Strapi.notification.success('settings-manager.strapi.notification.success.databaseDelete'); this.props.databaseDelete(dbName, this.props.match.params.env); } // function used for react-select option optionComponent = (props) => ; // custom Row rendering for the component List with params slug === languages renderRowLanguage = (props, key, liStyles) => ( ) renderListTitle = () => { const availableContentNumber = this.props.home.configsDisplay.sections.length; const title = availableContentNumber > 1 ? `list.${this.props.match.params.slug}.title.plural` : `list.${this.props.match.params.slug}.title.singular`; const titleDisplay = title ? : ''; return {availableContentNumber} {titleDisplay} } renderListButtonLabel = () => `list.${this.props.match.params.slug}.button.label`; renderPopUpFormDatabase = (section, props, popUpStyles) => ( map(section.items, (item, key) => { const isActive = props.values[this.props.home.dbNameTarget] === this.props.home.modifiedData['database.defaultConnection'] ?
: ''; if (item.name === 'form.database.item.default') { return (
{isActive}
); } return ( props.renderInput(item, key) ); }) ) renderPopUpFormLanguage = (section) => ( map(section.items, (item) => { const value = this.props.home.modifiedData[item.target] || this.props.home.selectOptions.options[0].value; return (