mirror of
https://github.com/strapi/strapi.git
synced 2025-08-18 13:45:25 +00:00
Merge branch 'master' into language-ko_kr
This commit is contained in:
commit
236d2a62ed
10
.travis.yml
10
.travis.yml
@ -13,12 +13,16 @@ before_install:
|
|||||||
- export CHROME_BIN=chromium-browser
|
- export CHROME_BIN=chromium-browser
|
||||||
- export DISPLAY=:99.0
|
- export DISPLAY=:99.0
|
||||||
- sh -e /etc/init.d/xvfb start
|
- sh -e /etc/init.d/xvfb start
|
||||||
- sudo chown -R $(whoami) $(npm config get prefix)/{lib/node_modules,bin,share}
|
# - sudo chown -R $(whoami) $(npm config get prefix)/{lib/node_modules,bin,share}
|
||||||
- npm cache clean --force
|
# - npm cache clean --force
|
||||||
- rm -rf node_modules/
|
# - rm -rf node_modules/
|
||||||
|
|
||||||
install:
|
install:
|
||||||
- npm run setup --debug
|
- npm run setup --debug
|
||||||
|
|
||||||
script:
|
script:
|
||||||
- npm run doc
|
- npm run doc
|
||||||
|
|
||||||
|
cache:
|
||||||
|
directories:
|
||||||
|
- "node_modules"
|
||||||
|
@ -179,6 +179,10 @@ Most of the application's configurations are defined by environment. It means th
|
|||||||
- `password` (string): Password used to establish the connection.
|
- `password` (string): Password used to establish the connection.
|
||||||
- `options` (object): List of additional options used by the connector.
|
- `options` (object): List of additional options used by the connector.
|
||||||
- `timezone` (string): Set the default behavior for local time (used only for a SQL database). Default value: `utc`.
|
- `timezone` (string): Set the default behavior for local time (used only for a SQL database). Default value: `utc`.
|
||||||
|
- `options` Options used for database connection.
|
||||||
|
- `ssl` (boolean): For ssl database connection.
|
||||||
|
- `debug` (boolean): Show database exchanges and errors.
|
||||||
|
- `autoMigration` (boolean): To disable auto tables/columns creation for SQL database.
|
||||||
|
|
||||||
#### Example
|
#### Example
|
||||||
|
|
||||||
|
@ -501,6 +501,25 @@ module.exports = function(strapi) {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const storeTable = async (table, attributes) => {
|
||||||
|
const existTable = await StrapiConfigs.forge({key: `db_model_${table}`}).fetch();
|
||||||
|
|
||||||
|
if (existTable) {
|
||||||
|
await StrapiConfigs.forge({id: existTable.id}).save({
|
||||||
|
value: JSON.stringify(attributes)
|
||||||
|
}, {
|
||||||
|
path: true
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
await StrapiConfigs.forge({
|
||||||
|
key: `db_model_${table}`,
|
||||||
|
type: 'object',
|
||||||
|
value: JSON.stringify(attributes)
|
||||||
|
}).save();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
if (!tableExist) {
|
if (!tableExist) {
|
||||||
const columns = generateColumns(attributes, [`id ${definition.client === 'pg' ? 'SERIAL' : 'INT AUTO_INCREMENT'} NOT NULL PRIMARY KEY`]).join(',\n\r');
|
const columns = generateColumns(attributes, [`id ${definition.client === 'pg' ? 'SERIAL' : 'INT AUTO_INCREMENT'} NOT NULL PRIMARY KEY`]).join(',\n\r');
|
||||||
|
|
||||||
@ -513,7 +532,10 @@ module.exports = function(strapi) {
|
|||||||
|
|
||||||
// Generate indexes.
|
// Generate indexes.
|
||||||
await generateIndexes(table, attributes);
|
await generateIndexes(table, attributes);
|
||||||
|
|
||||||
|
await storeTable(table, attributes);
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
const columns = Object.keys(attributes);
|
const columns = Object.keys(attributes);
|
||||||
|
|
||||||
// Fetch existing column
|
// Fetch existing column
|
||||||
@ -546,9 +568,21 @@ module.exports = function(strapi) {
|
|||||||
await Promise.all(queries.map(query => ORM.knex.raw(query)));
|
await Promise.all(queries.map(query => ORM.knex.raw(query)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let previousAttributes;
|
||||||
|
try {
|
||||||
|
previousAttributes = JSON.parse((await StrapiConfigs.forge({key: `db_model_${table}`}).fetch()).toJSON().value);
|
||||||
|
} catch (err) {
|
||||||
|
await storeTable(table, attributes);
|
||||||
|
previousAttributes = JSON.parse((await StrapiConfigs.forge({key: `db_model_${table}`}).fetch()).toJSON().value);
|
||||||
|
}
|
||||||
|
|
||||||
// Execute query to update column type
|
// Execute query to update column type
|
||||||
await Promise.all(columns.map(attribute =>
|
await Promise.all(columns.map(attribute =>
|
||||||
new Promise(async (resolve) => {
|
new Promise(async (resolve) => {
|
||||||
|
if (JSON.stringify(previousAttributes[attribute]) === JSON.stringify(attributes[attribute])) {
|
||||||
|
return resolve();
|
||||||
|
}
|
||||||
|
|
||||||
const type = getType(attributes[attribute], attribute);
|
const type = getType(attributes[attribute], attribute);
|
||||||
|
|
||||||
if (type) {
|
if (type) {
|
||||||
@ -567,6 +601,8 @@ module.exports = function(strapi) {
|
|||||||
resolve();
|
resolve();
|
||||||
})
|
})
|
||||||
));
|
));
|
||||||
|
|
||||||
|
await storeTable(table, attributes);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -583,7 +619,9 @@ module.exports = function(strapi) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Equilize tables
|
// Equilize tables
|
||||||
|
if (connection.options && connection.options.autoMigration !== false) {
|
||||||
await handler(loadedModel.tableName, definition.attributes);
|
await handler(loadedModel.tableName, definition.attributes);
|
||||||
|
}
|
||||||
|
|
||||||
// Equilize polymorphic releations
|
// Equilize polymorphic releations
|
||||||
const morphRelations = definition.associations.find((association) => {
|
const morphRelations = definition.associations.find((association) => {
|
||||||
@ -606,8 +644,10 @@ module.exports = function(strapi) {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if (connection.options && connection.options.autoMigration !== false) {
|
||||||
await handler(`${loadedModel.tableName}_morph`, attributes);
|
await handler(`${loadedModel.tableName}_morph`, attributes);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Equilize many to many releations
|
// Equilize many to many releations
|
||||||
const manyRelations = definition.associations.find((association) => {
|
const manyRelations = definition.associations.find((association) => {
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
/* eslint-disable no-console */
|
/* eslint-disable no-console */
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import { get, has, isArray, isEmpty, size } from 'lodash';
|
import { get, has, isArray, isEmpty, startsWith, size } from 'lodash';
|
||||||
import cn from 'classnames';
|
import cn from 'classnames';
|
||||||
|
|
||||||
import BkgImg from 'assets/icons/icon_upload.svg';
|
import BkgImg from 'assets/icons/icon_upload.svg';
|
||||||
@ -31,9 +31,10 @@ class ImgPreview extends React.Component {
|
|||||||
componentDidMount() {
|
componentDidMount() {
|
||||||
// We don't need the generateImgURL function here since the compo will
|
// We don't need the generateImgURL function here since the compo will
|
||||||
// always have an init value here
|
// always have an init value here
|
||||||
|
const file = this.props.multiple ? get(this.props.files, ['0', 'name'], '') : get(this.props.files, 'name');
|
||||||
this.setState({
|
this.setState({
|
||||||
imgURL: get(this.props.files, ['0', 'url'], '') || get(this.props.files, 'url', ''),
|
imgURL: get(this.props.files, ['0', 'url'], '') || get(this.props.files, 'url', ''),
|
||||||
isImg: this.isPictureType(get(this.props.files, ['0', 'name'], '')),
|
isImg: this.isPictureType(file),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -144,8 +145,10 @@ class ImgPreview extends React.Component {
|
|||||||
const fileType = this.getFileType(this.state.imgURL);
|
const fileType = this.getFileType(this.state.imgURL);
|
||||||
|
|
||||||
if (this.state.isImg) {
|
if (this.state.isImg) {
|
||||||
|
const imgURL = startsWith(this.state.imgURL, '/') ? `${strapi.backendURL}${this.state.imgURL}` : this.state.imgURL;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<img src={this.state.imgURL} alt="" />
|
<img src={imgURL} alt="" />
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -159,6 +162,7 @@ class ImgPreview extends React.Component {
|
|||||||
render() {
|
render() {
|
||||||
const { files, onBrowseClick } = this.props;
|
const { files, onBrowseClick } = this.props;
|
||||||
const { imgURL } = this.state;
|
const { imgURL } = this.state;
|
||||||
|
|
||||||
const containerStyle = isEmpty(imgURL) ?
|
const containerStyle = isEmpty(imgURL) ?
|
||||||
{
|
{
|
||||||
backgroundImage: `url(${BkgImg})`,
|
backgroundImage: `url(${BkgImg})`,
|
||||||
|
@ -14,6 +14,7 @@ import GlobalPagination from 'components/GlobalPagination';
|
|||||||
|
|
||||||
import styles from './styles.scss';
|
import styles from './styles.scss';
|
||||||
|
|
||||||
|
/* eslint-disable jsx-a11y/label-has-for */
|
||||||
function PageFooter(props) {
|
function PageFooter(props) {
|
||||||
return (
|
return (
|
||||||
<div className={cn('row', styles.pageFooter)} style={props.style}>
|
<div className={cn('row', styles.pageFooter)} style={props.style}>
|
||||||
|
@ -123,8 +123,9 @@ class PopUpRelations extends React.Component {
|
|||||||
value[0],
|
value[0],
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
|
const keyValue = get(this.props.values, 'params.nature') === 'oneWay' ? '-' : '';
|
||||||
this.props.onChange({ target: { name: 'name', value: '' } });
|
this.props.onChange({ target: { name: 'name', value: '' } });
|
||||||
this.props.onChange({ target: { name: 'params.key', value: '' } });
|
this.props.onChange({ target: { name: 'params.key', value: keyValue } });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -237,6 +238,8 @@ class PopUpRelations extends React.Component {
|
|||||||
|
|
||||||
const errs = findIndex(this.props.formErrors, ['name',get(this.props.form, ['items', '0', 'name'])]) !== -1 ? this.props.formErrors[findIndex(this.props.formErrors, ['name', get(this.props.form, ['items', '0', 'name'])])].errors: [];
|
const errs = findIndex(this.props.formErrors, ['name',get(this.props.form, ['items', '0', 'name'])]) !== -1 ? this.props.formErrors[findIndex(this.props.formErrors, ['name', get(this.props.form, ['items', '0', 'name'])])].errors: [];
|
||||||
const errors = findIndex(this.props.formErrors, ['name', get(this.props.form, ['items', '1', 'name'])]) !== -1 ? this.props.formErrors[findIndex(this.props.formErrors, ['name', get(this.props.form, ['items', '1', 'name'])])].errors : [];
|
const errors = findIndex(this.props.formErrors, ['name', get(this.props.form, ['items', '1', 'name'])]) !== -1 ? this.props.formErrors[findIndex(this.props.formErrors, ['name', get(this.props.form, ['items', '1', 'name'])])].errors : [];
|
||||||
|
const contentTypeTargetPlaceholder = get(this.props.values, 'params.nature', '') === 'oneWay' ? '-' : get(this.props.contentType, 'name');
|
||||||
|
const contentTypeTargetValue = get(this.props.values, 'params.nature') === 'oneWay' ? '-' : get(this.props.values, ['params', 'key']);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ModalBody className={`${styles.modalBody} ${styles.flex}`}>
|
<ModalBody className={`${styles.modalBody} ${styles.flex}`}>
|
||||||
@ -262,12 +265,12 @@ class PopUpRelations extends React.Component {
|
|||||||
/>
|
/>
|
||||||
<RelationBox
|
<RelationBox
|
||||||
tabIndex="2"
|
tabIndex="2"
|
||||||
contentTypeTargetPlaceholder={get(this.props.contentType, 'name')}
|
contentTypeTargetPlaceholder={contentTypeTargetPlaceholder}
|
||||||
relationType={get(this.props.values, ['params', 'nature'])}
|
relationType={get(this.props.values, ['params', 'nature'])}
|
||||||
onSubmit={this.props.onSubmit}
|
onSubmit={this.props.onSubmit}
|
||||||
header={header}
|
header={header}
|
||||||
input={get(this.props.form, ['items', '1'])}
|
input={get(this.props.form, ['items', '1'])}
|
||||||
value={get(this.props.values, ['params', 'key'])}
|
value={contentTypeTargetValue}
|
||||||
onChange={this.props.onChange}
|
onChange={this.props.onChange}
|
||||||
didCheckErrors={this.props.didCheckErrors}
|
didCheckErrors={this.props.didCheckErrors}
|
||||||
errors={errors}
|
errors={errors}
|
||||||
|
@ -143,7 +143,8 @@ export class Form extends React.Component { // eslint-disable-line react/prefer-
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Check if user is adding a relation with the same content type
|
// Check if user is adding a relation with the same content type
|
||||||
if (includes(this.props.hash, 'attributerelation') && this.props.modifiedDataAttribute.params.target === this.props.modelName) {
|
|
||||||
|
if (includes(this.props.hash, 'attributerelation') && this.props.modifiedDataAttribute.params.target === this.props.modelName && get(this.props.modifiedDataAttribute, ['params', 'nature'], '') !== 'oneWay') {
|
||||||
// Insert two attributes
|
// Insert two attributes
|
||||||
this.props.addAttributeRelationToContentType(this.props.modifiedDataAttribute);
|
this.props.addAttributeRelationToContentType(this.props.modifiedDataAttribute);
|
||||||
} else {
|
} else {
|
||||||
@ -168,7 +169,8 @@ export class Form extends React.Component { // eslint-disable-line react/prefer-
|
|||||||
const contentType = this.props.modifiedDataEdit;
|
const contentType = this.props.modifiedDataEdit;
|
||||||
// Add the new attribute to the content type attribute list
|
// Add the new attribute to the content type attribute list
|
||||||
const newAttribute = this.setTempAttribute();
|
const newAttribute = this.setTempAttribute();
|
||||||
contentType.attributes = compact(concat(contentType.attributes, newAttribute, this.setParallelAttribute(newAttribute)));
|
const parallelAttribute = this.props.modelName === get(newAttribute, ['params', 'target']) && get(newAttribute, ['params', 'nature'], '') === 'oneWay' ? null : this.setParallelAttribute(newAttribute);
|
||||||
|
contentType.attributes = compact(concat(contentType.attributes, newAttribute, parallelAttribute));
|
||||||
// Reset the store and update the parent container
|
// Reset the store and update the parent container
|
||||||
this.props.contentTypeCreate(contentType);
|
this.props.contentTypeCreate(contentType);
|
||||||
// Get the displayed model from the localStorage
|
// Get the displayed model from the localStorage
|
||||||
|
Loading…
x
Reference in New Issue
Block a user