/*
*
* Home
*
*/
import React from 'react';
import { connect } from 'react-redux';
import { bindActionCreators } from 'redux';
import { createStructuredSelector } from 'reselect';
import {
find,
findIndex,
findKey,
forEach,
get,
has,
isEmpty,
includes,
isObject,
join,
map,
replace,
split,
toNumber,
toLower,
upperCase,
} 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 RowDatabase from 'components/RowDatabase';
import { makeSelectSections, makeSelectEnvironments } from 'containers/App/selectors';
import selectHome from './selectors';
import {
cancelChanges,
changeDefaultLanguage,
changeInput,
configFetch,
databaseEdit,
databasesFetch,
databaseDelete,
editSettings,
languageDelete,
languagesFetch,
newLanguagePost,
newDatabasePost,
specificDatabaseFetch,
} 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,
toggleDefaultConnection: 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();
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;
}
});
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);
// format the default locale
const defaultLanguageArray = this.formatLanguageLocale(target.id);
// Edit the new config
this.props.editSettings({ 'language.defaultLocale': join(defaultLanguageArray, '_') }, 'i18n');
}
formatLanguageLocale = (data) => {
const array = [];
forEach(split(data, '_'), (value, key) => {
if (key === 0){
array.push(toLower(value));
} else {
array.push(upperCase(value));
}
});
return array;
}
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 }) => {
let value = target.type === 'number' ? toNumber(target.value) : target.value;
let name = target.name;
if (this.props.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;
}
}
this.props.changeInput(name, value);
}
handleCancel = () => {
this.props.cancelChanges();
}
handleSubmit = (e) => {
e.preventDefault();
const apiUrl = this.props.params.env ? `${this.props.params.slug}/${this.props.params.env}` : this.props.params.slug;
// send only updated settings
const body = this.sendUpdatedParams();
if (!isEmpty(body)) {
this.props.editSettings(body, apiUrl);
} else {
window.Strapi.notification.error('Settings are equals');
}
}
handleSubmitEditDatabase = (databaseName) => {
const body = this.sendUpdatedParams();
const apiUrl = `${databaseName}/${this.props.params.env}`;
if (!isEmpty(body)) {
this.props.databaseEdit(body, apiUrl);
} else {
window.Strapi.notification.error('Settings are equals');
}
}
sendUpdatedParams = () => {
const prevSettings = this.props.home.initialData;
const body = {};
forEach(this.props.home.modifiedData, (value, key) => {
if (value !== prevSettings[key] && key !== 'security.xframe.value.nested') {
body[key] = value;
}
});
if (has(this.props.home.modifiedData, 'security.xframe.value.nested') && this.props.home.modifiedData['security.xframe.value'] === 'ALLOW-FROM') {
const value = includes(this.props.home.modifiedData['security.xframe.value.nested'], 'ALLOW-FROM') ?
`ALLOW-FROM ${this.props.home.modifiedData['security.xframe.value.nested']}`
: `ALLOW-FROM.ALLOW-FROM ${this.props.home.modifiedData['security.xframe.value.nested']}`;
body['security.xframe.value'] = value;
}
return body;
}
handleLanguageDelete = ({ target }) => {
// retrieve the language to delete using the target id
this.props.languageDelete(target.id);
}
handleDatabaseDelete = (dbName) => {
window.Strapi.notification.info('Deleting database');
this.props.databaseDelete(dbName, this.props.params.env);
}
// 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
// format the locale to
const defaultLanguageArray = this.formatLanguageLocale(props.name);
// retrieve language name from i18n translation
const languageObject = find(get(this.props.home.listLanguages, ['sections', '0', 'items', '0', 'items']), ['value', join(defaultLanguageArray, '_')]);
// apply i18n
const languageDisplay = isObject(languageObject) ?