mirror of
https://github.com/strapi/strapi.git
synced 2025-08-22 15:48:59 +00:00
Auto generate admin fields
This commit is contained in:
parent
feaaf3a4eb
commit
1fb39080c3
@ -40,7 +40,7 @@ class EditFormRelation extends React.Component { // eslint-disable-line react/pr
|
||||
}
|
||||
|
||||
// Request URL
|
||||
const requestUrlSuffix = query ? '' : this.props.record.get(this.props.relation.attribute);
|
||||
const requestUrlSuffix = query && this.props.record.get(this.props.relation.attribute) ? this.props.record.get(this.props.relation.attribute) : '';
|
||||
const requestUrl = `/content-manager/explorer/${this.props.relation.model}/${requestUrlSuffix}`;
|
||||
|
||||
// Call our request helper (see 'utils/request')
|
||||
@ -51,11 +51,11 @@ class EditFormRelation extends React.Component { // eslint-disable-line react/pr
|
||||
.then(response => {
|
||||
const options = _.isArray(response)
|
||||
? _.map(response, item => ({
|
||||
value: Number(item.id),
|
||||
value: item.id,
|
||||
label: item[this.props.relation.displayedAttribute],
|
||||
}))
|
||||
: [{
|
||||
value: Number(response.id),
|
||||
value: response.id,
|
||||
label: response[this.props.relation.displayedAttribute],
|
||||
}];
|
||||
|
||||
|
@ -8,21 +8,33 @@
|
||||
import React from 'react';
|
||||
import { connect } from 'react-redux';
|
||||
import { createStructuredSelector } from 'reselect';
|
||||
import _ from 'lodash';
|
||||
|
||||
import config from '../../../../config/admin.json';
|
||||
import { loadModels, updateSchema } from './actions';
|
||||
import { makeSelectModels, makeSelectLoading } from './selectors';
|
||||
import { makeSelectLoading } from './selectors';
|
||||
|
||||
const tryRequire = (path) => {
|
||||
try {
|
||||
return require(`containers/${path}.js`); // eslint-disable-line global-require
|
||||
} catch (err) {
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
class App extends React.Component {
|
||||
componentWillMount() {
|
||||
this.props.loadModels();
|
||||
this.props.updateSchema(config.admin.schema);
|
||||
const config = tryRequire('../../../../config/admin.json');
|
||||
if (!_.isEmpty(_.get(config, 'admin.schema'))) {
|
||||
this.props.updateSchema(config.admin.schema);
|
||||
} else {
|
||||
this.props.loadModels();
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
let content = <div />;
|
||||
|
||||
if (this.props.models) {
|
||||
if (!this.props.loading) {
|
||||
// Assign plugin component to children
|
||||
content = React.Children.map(this.props.children, child =>
|
||||
React.cloneElement(child, {
|
||||
@ -46,11 +58,8 @@ App.contextTypes = {
|
||||
App.propTypes = {
|
||||
children: React.PropTypes.node.isRequired,
|
||||
exposedComponents: React.PropTypes.object.isRequired,
|
||||
loading: React.PropTypes.bool,
|
||||
loadModels: React.PropTypes.func.isRequired,
|
||||
models: React.PropTypes.oneOfType([
|
||||
React.PropTypes.object,
|
||||
React.PropTypes.bool,
|
||||
]),
|
||||
updateSchema: React.PropTypes.func.isRequired,
|
||||
};
|
||||
|
||||
@ -63,7 +72,6 @@ export function mapDispatchToProps(dispatch) {
|
||||
}
|
||||
|
||||
const mapStateToProps = createStructuredSelector({
|
||||
models: makeSelectModels(),
|
||||
loading: makeSelectLoading(),
|
||||
});
|
||||
|
||||
|
@ -9,7 +9,7 @@ import { fromJS } from 'immutable';
|
||||
import { LOAD_MODELS, LOADED_MODELS, UPDATE_SCHEMA } from './constants';
|
||||
|
||||
const initialState = fromJS({
|
||||
loading: false,
|
||||
loading: true,
|
||||
models: false,
|
||||
schema: false,
|
||||
});
|
||||
@ -17,11 +17,14 @@ const initialState = fromJS({
|
||||
function appReducer(state = initialState, action) {
|
||||
switch (action.type) {
|
||||
case LOAD_MODELS:
|
||||
return state.set('loading', true);
|
||||
return state;
|
||||
case LOADED_MODELS:
|
||||
return state.set('loading', false).set('models', action.models);
|
||||
return state
|
||||
.set('models', action.models);
|
||||
case UPDATE_SCHEMA:
|
||||
return state.set('schema', action.schema);
|
||||
return state
|
||||
.set('loading', false)
|
||||
.set('schema', action.schema);
|
||||
default:
|
||||
return state;
|
||||
}
|
||||
|
@ -1,9 +1,13 @@
|
||||
import _ from 'lodash';
|
||||
import {takeLatest} from 'redux-saga';
|
||||
import {fork, put} from 'redux-saga/effects';
|
||||
import { takeLatest } from 'redux-saga';
|
||||
import { fork, put, select } from 'redux-saga/effects';
|
||||
|
||||
import { generateSchema } from 'utils/schema';
|
||||
|
||||
import { loadedModels, updateSchema } from './actions';
|
||||
import { LOAD_MODELS, LOADED_MODELS, UPDATE_SCHEMA } from './constants';
|
||||
import { makeSelectModels } from './selectors';
|
||||
|
||||
import {loadedModels} from './actions';
|
||||
import {LOAD_MODELS, UPDATE_SCHEMA} from './constants';
|
||||
|
||||
export function* getModels() {
|
||||
try {
|
||||
@ -26,6 +30,22 @@ export function* getModels() {
|
||||
}
|
||||
}
|
||||
|
||||
export function* modelsLoaded() {
|
||||
const models = yield select(makeSelectModels());
|
||||
let schema;
|
||||
|
||||
try {
|
||||
schema = generateSchema(models);
|
||||
} catch (err) {
|
||||
window.Strapi.notification.error(
|
||||
'An error occurred during schema generation.'
|
||||
);
|
||||
throw new Error(err);
|
||||
}
|
||||
|
||||
yield put(updateSchema(schema));
|
||||
}
|
||||
|
||||
export function* schemaUpdated(action) {
|
||||
// Display the links only if the `displayed` attribute is not set to false
|
||||
const displayedModels = _.pickBy(action.schema, model => (model.displayed !== false));
|
||||
@ -44,6 +64,7 @@ export function* schemaUpdated(action) {
|
||||
export function* defaultSaga() {
|
||||
yield fork(takeLatest, LOAD_MODELS, getModels);
|
||||
yield fork(takeLatest, UPDATE_SCHEMA, schemaUpdated);
|
||||
yield fork(takeLatest, LOADED_MODELS, modelsLoaded);
|
||||
}
|
||||
|
||||
// All sagas to be loaded
|
||||
|
@ -0,0 +1,56 @@
|
||||
import _ from 'lodash';
|
||||
import pluralize from 'pluralize';
|
||||
|
||||
/**
|
||||
* Generate a schema according to the models
|
||||
* of the Strapi application.
|
||||
*
|
||||
* @param models
|
||||
*/
|
||||
const generateSchema = (models) => {
|
||||
// Init `schema` object
|
||||
const schema = {};
|
||||
|
||||
_.forEach(models, (model, name) => {
|
||||
// Model data
|
||||
const schemaModel = {
|
||||
label: _.upperFirst(name),
|
||||
labelPlural: _.upperFirst(pluralize(name)),
|
||||
orm: model.orm || 'mongoose',
|
||||
};
|
||||
|
||||
// Fields (non relation)
|
||||
schemaModel.fields = _.mapValues(_.pickBy(model.attributes, attribute =>
|
||||
!attribute.model && !attribute.collection
|
||||
), (value, attribute) => ({
|
||||
label: _.upperFirst(attribute),
|
||||
description: '',
|
||||
type: value.type || 'string',
|
||||
}));
|
||||
|
||||
// Select fields displayed in list view
|
||||
schemaModel.list = _.slice(_.keys(schemaModel.fields), 0, 4);
|
||||
|
||||
// Model relations
|
||||
schemaModel.relations = _.mapValues(_.pickBy(model.attributes, attribute =>
|
||||
attribute.model
|
||||
), (value, attribute) => ({
|
||||
columnName: attribute,
|
||||
model: value.model,
|
||||
attribute,
|
||||
label: _.upperFirst(attribute),
|
||||
description: '',
|
||||
displayedAttribute: _.findKey(models[value.model].attributes, { type: 'string' }) || 'id',
|
||||
})
|
||||
);
|
||||
|
||||
// Set the formatted model to the schema
|
||||
schema[name] = schemaModel;
|
||||
});
|
||||
|
||||
return schema;
|
||||
};
|
||||
|
||||
export {
|
||||
generateSchema,
|
||||
};
|
@ -23,7 +23,7 @@ module.exports = {
|
||||
|
||||
find: async ctx => {
|
||||
const model = strapi.models[ctx.params.model];
|
||||
const orm = _.get(strapi.plugins, ['content-manager', 'config', 'admin', 'schema', ctx.params.model, 'orm']);
|
||||
const orm = _.get(strapi.plugins, ['content-manager', 'config', 'admin', 'schema', ctx.params.model, 'orm']) || model.orm;
|
||||
const queries = _.get(strapi.plugins, ['content-manager', 'config', 'queries', orm]);
|
||||
const primaryKey = model.primaryKey;
|
||||
const {limit, skip = 0, sort = primaryKey, query, queryAttribute} = ctx.request.query;
|
||||
@ -44,7 +44,7 @@ module.exports = {
|
||||
|
||||
count: async ctx => {
|
||||
const model = strapi.models[ctx.params.model];
|
||||
const orm = _.get(strapi.plugins, ['content-manager', 'config', 'admin', 'schema', ctx.params.model, 'orm']);
|
||||
const orm = _.get(strapi.plugins, ['content-manager', 'config', 'admin', 'schema', ctx.params.model, 'orm']) || model.orm;
|
||||
const queries = _.get(strapi.plugins, ['content-manager', 'config', 'queries', orm]);
|
||||
|
||||
// Count using `queries` system
|
||||
@ -57,7 +57,7 @@ module.exports = {
|
||||
|
||||
findOne: async ctx => {
|
||||
const model = strapi.models[ctx.params.model];
|
||||
const orm = _.get(strapi.plugins, ['content-manager', 'config', 'admin', 'schema', ctx.params.model, 'orm']);
|
||||
const orm = _.get(strapi.plugins, ['content-manager', 'config', 'admin', 'schema', ctx.params.model, 'orm']) || model.orm;
|
||||
const queries = _.get(strapi.plugins, ['content-manager', 'config', 'queries', orm]);
|
||||
const primaryKey = model.primaryKey;
|
||||
const id = ctx.params.id;
|
||||
@ -79,7 +79,7 @@ module.exports = {
|
||||
|
||||
create: async ctx => {
|
||||
const model = strapi.models[ctx.params.model];
|
||||
const orm = _.get(strapi.plugins, ['content-manager', 'config', 'admin', 'schema', ctx.params.model, 'orm']);
|
||||
const orm = _.get(strapi.plugins, ['content-manager', 'config', 'admin', 'schema', ctx.params.model, 'orm']) || model.orm;
|
||||
const queries = _.get(strapi.plugins, ['content-manager', 'config', 'queries', orm]);
|
||||
const values = ctx.request.body;
|
||||
|
||||
@ -94,7 +94,7 @@ module.exports = {
|
||||
|
||||
update: async ctx => {
|
||||
const model = strapi.models[ctx.params.model];
|
||||
const orm = _.get(strapi.plugins, ['content-manager', 'config', 'admin', 'schema', ctx.params.model, 'orm']);
|
||||
const orm = _.get(strapi.plugins, ['content-manager', 'config', 'admin', 'schema', ctx.params.model, 'orm']) || model.orm;
|
||||
const queries = _.get(strapi.plugins, ['content-manager', 'config', 'queries', orm]);
|
||||
const primaryKey = model.primaryKey;
|
||||
const id = ctx.params.id;
|
||||
@ -113,7 +113,7 @@ module.exports = {
|
||||
|
||||
delete: async ctx => {
|
||||
const model = strapi.models[ctx.params.model];
|
||||
const orm = _.get(strapi.plugins, ['content-manager', 'config', 'admin', 'schema', ctx.params.model, 'orm']);
|
||||
const orm = _.get(strapi.plugins, ['content-manager', 'config', 'admin', 'schema', ctx.params.model, 'orm']) || model.orm;
|
||||
const queries = _.get(strapi.plugins, ['content-manager', 'config', 'queries', orm]);
|
||||
const primaryKey = model.primaryKey;
|
||||
const id = ctx.params.id;
|
||||
|
Loading…
x
Reference in New Issue
Block a user