Handle plugin model in Content Manager

This commit is contained in:
Aurelsicoko 2017-11-27 17:27:16 +01:00
parent 1c2f625a2b
commit eceede450b
19 changed files with 240 additions and 111 deletions

View File

@ -20,7 +20,13 @@ class LeftMenuLink extends React.Component { // eslint-disable-line react/prefer
return (
<li className={styles.item}>
<Link className={`${styles.link} ${isLinkActive ? styles.linkActive : ''}`} to={this.props.destination}>
<Link
className={`${styles.link} ${isLinkActive ? styles.linkActive : ''}`}
to={{
pathname: this.props.destination,
search: `?source=${this.props.source}`,
}}
>
<i className={`${styles.linkIcon} fa-${this.props.icon} fa`}></i>
<FormattedMessage
id={this.props.label}
@ -40,6 +46,11 @@ LeftMenuLink.propTypes = {
destination: PropTypes.string.isRequired,
icon: PropTypes.string.isRequired,
label: PropTypes.string.isRequired,
source: PropTypes.string,
};
LeftMenuLink.defaultProps = {
source: '',
};
export default LeftMenuLink;

View File

@ -23,7 +23,8 @@ function LeftMenuLinkContainer({ plugins }) {
acc[snakeCase(section.name)] = {
name: section.name,
links: (get(acc[snakeCase(section.name)], 'links') || []).concat(section.links.map(link => {
link.plugin = !isEmpty(pluginsObject[link.plugin] ? link.plugin : pluginsObject[current].id);
link.source = current;
link.plugin = !isEmpty(pluginsObject[link.plugin]) ? link.plugin : pluginsObject[current].id;
return link;
})),
@ -38,7 +39,7 @@ function LeftMenuLinkContainer({ plugins }) {
<p className={styles.title}>{pluginsSections[current].name}</p>
<ul className={styles.list}>
{sortBy(pluginsSections[current].links, 'label').map(link =>
<LeftMenuLink key={link.label} icon={link.icon || 'link'} label={link.label} destination={`/plugins/${link.plugin}/${link.destination}`} />
<LeftMenuLink key={link.label} icon={link.icon || 'link'} label={link.label} destination={`/plugins/${link.plugin}/${link.destination}`} source={link.source} />
)}
</ul>
</div>

View File

@ -0,0 +1,4 @@
export default (location, n) => {
const half = location.split(n + '=')[1];
return half !== undefined ? decodeURIComponent(half.split('&')[0]) : null;
};

View File

@ -12,6 +12,9 @@ import { findIndex, get, omit, isFunction, merge } from 'lodash';
// Components.
import Input from 'components/Input';
// Utils.
import getQueryParameters from 'utils/getQueryParameters';
// Styles.
import styles from './styles.scss';
@ -42,8 +45,12 @@ class EditForm extends React.Component {
}
render() {
const source = getQueryParameters(this.props.location.search, 'source');
const currentSchema = get(this.props.schema, [this.props.currentModelName]) || get(this.props.schema, ['plugins', source, this.props.currentModelName]);
const currentLayout = source === undefined || source === 'content-manager' ? get(this.props.layout, [this.props.currentModelName]) : get(this.props.layout, ['plugins', source, this.props.currentModelName]);
// Remove `id` field
const displayedFields = merge(this.props.layout[this.props.currentModelName], omit(this.props.schema[this.props.currentModelName].fields, 'id'));
const displayedFields = merge(currentLayout, omit(currentSchema.fields, 'id'));
// List fields inputs
const fields = Object.keys(displayedFields).map(attr => {
@ -53,14 +60,14 @@ class EditForm extends React.Component {
const validationsIndex = findIndex(this.props.formValidations, ['name', attr]);
const validations = get(this.props.formValidations[validationsIndex], 'validations') || {};
const layout = Object.keys(get(this.props.layout[this.props.currentModelName], attr, {})).reduce((acc, current) => {
acc[current] = isFunction(this.props.layout[this.props.currentModelName][attr][current]) ?
this.props.layout[this.props.currentModelName][attr][current](this) :
this.props.layout[this.props.currentModelName][attr][current];
const layout = Object.keys(get(currentLayout, attr, {})).reduce((acc, current) => {
acc[current] = isFunction(currentLayout[attr][current]) ?
currentLayout[attr][current](this) :
currentLayout[attr][current];
return acc;
}, {});
return (
<Input
key={attr}
@ -95,6 +102,9 @@ EditForm.propTypes = {
formErrors: PropTypes.array.isRequired,
formValidations: PropTypes.array.isRequired,
layout: PropTypes.object.isRequired,
location: PropTypes.shape({
search: PropTypes.string,
}).isRequired,
onChange: PropTypes.func.isRequired,
onSubmit: PropTypes.func.isRequired,
record: PropTypes.oneOfType([

View File

@ -8,8 +8,14 @@ import React from 'react';
import PropTypes from 'prop-types';
import { get, map, size } from 'lodash';
// Components.
import SelectOne from 'components/SelectOne';
import SelectMany from 'components/SelectMany';
// Utils.
import getQueryParameters from 'utils/getQueryParameters';
// Style.
import styles from './styles.scss';
class EditFormRelations extends React.Component { // eslint-disable-line react/prefer-stateless-function
@ -20,7 +26,10 @@ class EditFormRelations extends React.Component { // eslint-disable-line react/p
}
render() {
const relations = map(this.props.schema[this.props.currentModelName].relations, (relation, i) => {
const source = getQueryParameters(this.props.location.search, 'source');
const currentSchema = get(this.props.schema, [this.props.currentModelName]) || get(this.props.schema, ['plugins', source, this.props.currentModelName]);
const relations = map(currentSchema.relations, (relation, i) => {
switch (relation.nature) {
case 'oneToOne':
@ -75,6 +84,9 @@ EditFormRelations.propTypes = {
PropTypes.string,
]).isRequired,
isNull: PropTypes.bool.isRequired,
location: PropTypes.shape({
search: PropTypes.string,
}).isRequired,
record: PropTypes.oneOfType([
PropTypes.object,
PropTypes.bool,

View File

@ -19,10 +19,11 @@ export function emptyStore() {
};
}
export function getModelEntries(modelName) {
export function getModelEntries(modelName, source) {
return {
type: GET_MODEL_ENTRIES,
modelName,
source,
};
}

View File

@ -14,39 +14,26 @@ import { isEmpty, get } from 'lodash';
import { Switch, Route } from 'react-router-dom';
import injectSaga from 'utils/injectSaga';
import getQueryParameters from 'utils/getQueryParameters';
import Home from 'containers/Home';
import Edit from 'containers/Edit';
import List from 'containers/List';
import EmptyAttributesView from 'components/EmptyAttributesView';
import { emptyStore, getModelEntries, loadModels, updateSchema } from './actions';
import { emptyStore, getModelEntries, loadModels } from './actions';
import { makeSelectLoading, makeSelectModels, makeSelectModelEntries } from './selectors';
import saga from './sagas';
const tryRequire = (path) => {
try {
return require(`containers/${path}.js`); // eslint-disable-line global-require
} catch (err) {
return null;
}
};
class App extends React.Component {
componentDidMount() {
const config = tryRequire('../../../../config/admin.json');
if (!isEmpty(get(config, 'admin.schema'))) {
this.props.updateSchema(config.admin.schema);
} else {
this.props.loadModels();
}
this.props.loadModels();
const modelName = this.props.location.pathname.split('/')[3];
if (modelName) {
this.props.getModelEntries(modelName);
this.props.getModelEntries(modelName, getQueryParameters(this.props.location.search, 'source'));
}
}
@ -54,7 +41,7 @@ class App extends React.Component {
const currentModelName = this.props.location.pathname.split('/')[3];
if (prevProps.location.pathname !== this.props.location.pathname && currentModelName) {
this.props.getModelEntries(currentModelName);
this.props.getModelEntries(currentModelName, getQueryParameters(this.props.location.search, 'source'));
}
}
@ -68,9 +55,12 @@ class App extends React.Component {
}
const currentModelName = this.props.location.pathname.split('/')[3];
const source = getQueryParameters(this.props.location.search, 'source');
if (currentModelName && isEmpty(get(this.props.models, [currentModelName, 'attributes']))) {
return <EmptyAttributesView currentModelName={currentModelName} history={this.props.history} modelEntries={this.props.modelEntries} />;
if (currentModelName && source && isEmpty(get(this.props.models.plugins, [source, 'models', currentModelName, 'attributes']))) {
if (currentModelName && isEmpty(get(this.props.models.models, [currentModelName, 'attributes']))) {
return <EmptyAttributesView currentModelName={currentModelName} history={this.props.history} modelEntries={this.props.modelEntries} />;
}
}
return (
@ -101,7 +91,6 @@ App.propTypes = {
PropTypes.bool,
PropTypes.object,
]).isRequired,
updateSchema: PropTypes.func.isRequired,
};
export function mapDispatchToProps(dispatch) {
@ -110,7 +99,6 @@ export function mapDispatchToProps(dispatch) {
emptyStore,
getModelEntries,
loadModels,
updateSchema,
},
dispatch,
);

View File

@ -1,4 +1,4 @@
import { map } from 'lodash';
import { map, omit } from 'lodash';
import { fork, put, select, call, takeLatest } from 'redux-saga/effects';
import request from 'utils/request';
@ -10,7 +10,8 @@ import { makeSelectModels } from './selectors';
export function* modelEntriesGet(action) {
try {
const requestUrl = `${strapi.backendURL}/content-manager/explorer/${action.modelName}/count`;
const requestUrl = `${strapi.backendURL}/content-manager/explorer/${action.modelName}/count${action.source !== undefined ? `?source=${action.source}`: ''}`;
const response = yield call(request, requestUrl, { method: 'GET' });
yield put(getModelEntriesSucceeded(response.count));
@ -27,7 +28,7 @@ export const generateMenu = function () {
.then(displayedModels => {
return [{
name: 'Content Types',
links: map(displayedModels, (model, key) => ({
links: map(omit(displayedModels, 'plugins'), (model, key) => ({
label: model.labelPlural || model.label || key,
destination: key,
})),

View File

@ -33,24 +33,27 @@ export function cancelChanges() {
};
}
export function deleteRecord(id, modelName) {
export function deleteRecord(id, modelName, source) {
return {
type: DELETE_RECORD,
id,
modelName,
source,
};
}
export function editRecord() {
export function editRecord(source) {
return {
type: EDIT_RECORD,
source,
};
}
export function loadRecord(id) {
export function loadRecord(id, source) {
return {
type: LOAD_RECORD,
id,
source,
};
}

View File

@ -24,6 +24,7 @@ import PluginHeader from 'components/PluginHeader';
import { makeSelectModels, makeSelectSchema } from 'containers/App/selectors';
// Utils.
import getQueryParameters from 'utils/getQueryParameters';
import injectReducer from 'utils/injectReducer';
import injectSaga from 'utils/injectSaga';
import templateObject from 'utils/templateObject';
@ -97,15 +98,20 @@ export class Edit extends React.Component {
}
componentDidMount() {
const source = getQueryParameters(this.props.location.search, 'source');
const attributes =
get(this.props.models, ['models', this.props.match.params.slug.toLowerCase(), 'attributes']) ||
get(this.props.models, ['plugins', source, 'models', this.props.match.params.slug.toLowerCase(), 'attributes']);
this.props.setInitialState();
this.props.setCurrentModelName(this.props.match.params.slug.toLowerCase());
this.props.setFormValidations(this.props.models[this.props.match.params.slug.toLowerCase()].attributes);
this.props.setForm(this.props.models[this.props.match.params.slug.toLowerCase()].attributes);
this.props.setFormValidations(attributes);
this.props.setForm(attributes);
// Detect that the current route is the `create` route or not
if (this.props.match.params.id === 'create') {
this.props.setIsCreating();
} else {
this.props.loadRecord(this.props.match.params.id);
this.props.loadRecord(this.props.match.params.id, source);
}
}
@ -127,11 +133,14 @@ export class Edit extends React.Component {
}
handleChange = (e) => {
const source = getQueryParameters(this.props.location.search, 'source');
const currentSchema = get(this.props.schema, [this.props.currentModelName]) || get(this.props.schema, ['plugins', source, this.props.currentModelName]);
let formattedValue = e.target.value;
if (isObject(e.target.value) && e.target.value._isAMomentObject === true) {
formattedValue = moment(e.target.value, 'YYYY-MM-DD HH:mm:ss').format();
} else if (['float', 'integer', 'bigint'].indexOf(this.props.schema[this.props.currentModelName].fields[e.target.name].type) !== -1) {
} else if (['float', 'integer', 'bigint'].indexOf(currentSchema.fields[e.target.name].type) !== -1) {
formattedValue = toNumber(e.target.value);
}
@ -140,12 +149,15 @@ export class Edit extends React.Component {
handleSubmit = (e) => {
e.preventDefault();
const form = this.props.form.toJS();
map(this.props.record.toJS(), (value, key) => form[key] = value);
const formErrors = checkFormValidity(form, this.props.formValidations.toJS());
const source = getQueryParameters(this.props.location.search, 'source');
if (isEmpty(formErrors)) {
this.props.editRecord();
this.props.editRecord(source);
} else {
this.props.setFormErrors(formErrors);
}
@ -156,9 +168,12 @@ export class Edit extends React.Component {
return <p>Loading...</p>;
}
const source = getQueryParameters(this.props.location.search, 'source');
const currentModel = get(this.props.models, ['models', this.props.currentModelName]) || get(this.props.models, ['plugins', source, 'models', this.props.currentModelName]);
// Plugin header config
const primaryKey = this.props.models[this.props.currentModelName].primaryKey;
const mainField = get(this.props.models, `${this.props.currentModelName}.info.mainField`) || primaryKey;
const primaryKey = currentModel.primaryKey;
const mainField = get(currentModel, 'info.mainField') || primaryKey;
const pluginHeaderTitle = this.props.isCreating ? 'New entry' : templateObject({ mainField }, this.props.record.toJS()).mainField;
const pluginHeaderDescription = this.props.isCreating ? 'New entry' : `#${this.props.record && this.props.record.get(primaryKey)}`;
@ -192,6 +207,7 @@ export class Edit extends React.Component {
didCheckErrors={this.props.didCheckErrors}
formValidations={this.props.formValidations.toJS()}
layout={this.layout}
location={this.props.location}
/>
</div>
</div>
@ -204,6 +220,7 @@ export class Edit extends React.Component {
setRecordAttribute={this.props.setRecordAttribute}
isNull={this.props.isRelationComponentNull}
toggleNull={this.props.toggleNull}
location={this.props.location}
/>
</div>
</div>

View File

@ -19,15 +19,21 @@ import {
makeSelectIsCreating,
} from './selectors';
export function* getRecord(params) {
export function* getRecord(action) {
const currentModelName = yield select(makeSelectCurrentModelName());
const params = {};
if (action.source !== undefined) {
params.source = action.source;
}
try {
const requestUrl = `${strapi.backendURL}/content-manager/explorer/${currentModelName}/${params.id}`;
const requestUrl = `${strapi.backendURL}/content-manager/explorer/${currentModelName}/${action.id}`;
// Call our request helper (see 'utils/request')
const response = yield request(requestUrl, {
method: 'GET',
params,
});
yield put(recordLoaded(response));
@ -36,7 +42,7 @@ export function* getRecord(params) {
}
}
export function* editRecord() {
export function* editRecord(action) {
const currentModelName = yield select(makeSelectCurrentModelName());
const record = yield select(makeSelectRecord());
const recordJSON = record.toJSON();
@ -49,6 +55,11 @@ export function* editRecord() {
const isCreating = yield select(makeSelectIsCreating());
const id = isCreating ? '' : recordCleaned.id;
const params = {};
if (action.source !== undefined) {
params.source = action.source;
}
try {
const requestUrl = `${strapi.backendURL}/content-manager/explorer/${currentModelName}/${id}`;
@ -57,6 +68,7 @@ export function* editRecord() {
yield call(request, requestUrl, {
method: isCreating ? 'POST' : 'PUT',
body: recordCleaned,
params,
});
yield put(recordEdited());
@ -67,21 +79,31 @@ export function* editRecord() {
}
}
export function* deleteRecord({ id, modelName }) {
export function* deleteRecord({ id, modelName, source }) {
function* httpCall(id, modelName) {
try {
const requestUrl = `${strapi.backendURL}/content-manager/explorer/${modelName}/${id}`;
const params = {};
if (action.source !== undefined) {
params.source = action.source;
}
// Call our request helper (see 'utils/request')
yield call(request, requestUrl, {
method: 'DELETE',
params,
});
yield put(recordDeleted(id));
strapi.notification.success('content-manager.success.record.delete');
// Redirect to the list page.
router.push(`/plugins/content-manager/${modelName}`);
router.push({
pathname: `/plugins/content-manager/${modelName}`,
state: {
source,
},
});
} catch (err) {
yield put(recordDeleteError());
strapi.notification.error('content-manager.error.record.delete');

View File

@ -42,15 +42,17 @@ export function changeSort(sort) {
};
}
export function loadCount() {
export function loadCount(source) {
return {
type: LOAD_COUNT,
source,
};
}
export function loadRecords() {
export function loadRecords(source) {
return {
type: LOAD_RECORDS,
source,
};
}

View File

@ -9,7 +9,7 @@ import { connect } from 'react-redux';
import { bindActionCreators, compose } from 'redux';
import { createStructuredSelector } from 'reselect';
import PropTypes from 'prop-types';
import { isEmpty, isUndefined, map, replace, split } from 'lodash';
import { isEmpty, isUndefined, map, get, toInteger } from 'lodash';
import { router } from 'app';
// Selectors.
@ -24,6 +24,9 @@ import PopUpWarning from 'components/PopUpWarning';
import injectReducer from 'utils/injectReducer';
import injectSaga from 'utils/injectSaga';
// Utils
import getQueryParameters from 'utils/getQueryParameters';
// Actions.
import {
deleteRecord,
@ -88,24 +91,24 @@ export class List extends React.Component {
// Set current model name
this.props.setCurrentModelName(slug.toLowerCase());
const searchParams = split(replace(props.location.search, '?', ''), '&');
const source = getQueryParameters(props.location.search, 'source');
const sort = isEmpty(props.location.search) ?
this.props.models[slug.toLowerCase()].primaryKey || 'id' :
replace(searchParams[2], 'sort=', '');
const sort = (isEmpty(props.location.search) ?
get(this.props.models, ['models', slug.toLowerCase(), 'primaryKey']) || get(this.props.models.plugins, [source, 'models', slug.toLowerCase(), 'primaryKey']) :
getQueryParameters('sort')) || 'id';
if (!isEmpty(props.location.search)) {
this.props.changePage(parseInt(replace(searchParams[0], 'page=', ''), 10));
this.props.changeLimit(parseInt(replace(searchParams[1], 'limit=', ''), 10));
this.props.changePage(toInteger(getQueryParameters('page')));
this.props.changeLimit(toInteger(getQueryParameters('limit')));
}
this.props.changeSort(sort);
// Load records
this.props.loadRecords();
this.props.loadRecords(source);
// Get the records count
this.props.loadCount();
this.props.loadCount(source);
// Define the `create` route url
this.addRoute = `${this.props.match.path.replace(':slug', slug)}/create`;
@ -139,7 +142,9 @@ export class List extends React.Component {
e.preventDefault();
e.stopPropagation();
this.props.deleteRecord(this.state.target, this.props.currentModelName);
const source = getQueryParameters(this.props.location.search, 'source');
this.props.deleteRecord(this.state.target, this.props.currentModelName, source);
this.setState({ showWarning: false });
}
@ -156,18 +161,20 @@ export class List extends React.Component {
}
render() {
if (!this.props.currentModelName || !this.props.schema) {
// Detect current model structure from models list
const source = getQueryParameters(this.props.location.search, 'source');
const currentModel = get(this.props.models, ['models', this.props.currentModelName]) || get(this.props.models, ['plugins', source, 'models', this.props.currentModelName]);
const currentSchema = get(this.props.schema, [this.props.currentModelName]) || get(this.props.schema, ['plugins', source, this.props.currentModelName]);
if (!this.props.currentModelName || !currentSchema) {
return <div />;
}
// Detect current model structure from models list
const currentModel = this.props.models[this.props.currentModelName];
// Define table headers
const tableHeaders = map(this.props.schema[this.props.currentModelName].list, (value) => ({
const tableHeaders = map(currentSchema.list, (value) => ({
name: value,
label: this.props.schema[this.props.currentModelName].fields[value].label,
type: this.props.schema[this.props.currentModelName].fields[value].type,
label: currentSchema.fields[value].label,
type: currentSchema.fields[value].type,
}));
tableHeaders.splice(0, 0, { name: currentModel.primaryKey || 'id', label: 'Id', type: 'string' });
@ -183,12 +190,12 @@ export class List extends React.Component {
history={this.props.history}
primaryKey={currentModel.primaryKey || 'id'}
handleDelete={this.toggleModalWarning}
redirectUrl={`?redirectUrl=/plugins/content-manager/${this.props.currentModelName.toLowerCase()}/?page=${this.props.currentPage}&limit=${this.props.limit}&sort=${this.props.sort}`}
redirectUrl={`?redirectUrl=/plugins/content-manager/${this.props.currentModelName.toLowerCase()}/?page=${this.props.currentPage}&limit=${this.props.limit}&sort=${this.props.sort}&source=${source}`}
/>
);
// Plugin header config
const pluginHeaderTitle = this.props.schema[this.props.currentModelName].label || 'Content Manager';
const pluginHeaderTitle = currentSchema.label || 'Content Manager';
// Define plugin header actions
const pluginHeaderActions = [

View File

@ -25,7 +25,7 @@ import {
makeSelectSort,
} from './selectors';
export function* getRecords() {
export function* getRecords(action) {
const currentModel = yield select(makeSelectCurrentModelName());
const limit = yield select(makeSelectLimit());
const currentPage = yield select(makeSelectCurrentPage());
@ -40,6 +40,10 @@ export function* getRecords() {
sort,
};
if (action.source !== undefined) {
params.source = action.source;
}
try {
const requestUrl = `${strapi.backendURL}/content-manager/explorer/${currentModel}`;
// Call our request helper (see 'utils/request')
@ -54,14 +58,19 @@ export function* getRecords() {
}
}
export function* getCount() {
export function* getCount(action) {
const currentModel = yield select(makeSelectCurrentModelName());
const params = {};
if (action.source !== undefined) {
params.source = action.source;
}
try {
const response = yield call(
request,
`${strapi.backendURL}/content-manager/explorer/${currentModel}/count`,
);
const response = yield call(request,`${strapi.backendURL}/content-manager/explorer/${currentModel}/count`, {
method: 'GET',
params,
});
yield put(loadedCount(response.count));
} catch (err) {

View File

@ -1,4 +1,4 @@
import { forEach, upperFirst, mapValues, pickBy, slice, findKey, keys, get } from 'lodash';
import { forEach, upperFirst, mapValues, pickBy, slice, findKey, keys, get, set } from 'lodash';
import pluralize from 'pluralize';
/**
@ -7,11 +7,13 @@ import pluralize from 'pluralize';
*
* @param models
*/
const generateSchema = (models) => {
const generateSchema = (responses) => {
// Init `schema` object
const schema = {};
const schema = {
plugins: {},
};
forEach(models, (model, name) => {
const buildSchema = (model, name, plugin = false) => {
// Model data
const schemaModel = {
label: upperFirst(name),
@ -46,8 +48,24 @@ const generateSchema = (models) => {
}, {});
}
if (plugin) {
return set(schema.plugins, `${plugin}.${name}`, schemaModel);
}
// Set the formatted model to the schema
schema[name] = schemaModel;
};
// Generate schema for plugins.
forEach(responses.plugins, (plugin, pluginName) => {
forEach(plugin.models, (model, name) => {
buildSchema(model, name, pluginName);
});
});
// Generate schema for models.
forEach(responses.models, (model, name) => {
buildSchema(model, name);
});
return schema;

View File

@ -8,28 +8,37 @@ const _ = require('lodash');
module.exports = {
models: async ctx => {
ctx.body = _.mapValues(strapi.models, model =>
_.pick(model, [
'info',
'connection',
'collectionName',
'attributes',
'identity',
'globalId',
'globalName',
'orm',
'loadedModel',
'primaryKey',
'associations'
])
);
const pickData = (model) => _.pick(model, [
'info',
'connection',
'collectionName',
'attributes',
'identity',
'globalId',
'globalName',
'orm',
'loadedModel',
'primaryKey',
'associations'
]);
ctx.body = {
models: _.mapValues(strapi.models, pickData),
plugins: Object.keys(strapi.plugins).reduce((acc, current) => {
acc[current] = {
models: _.mapValues(strapi.plugins[current].models, pickData)
};
return acc;
}, {})
};
},
find: async ctx => {
const { limit, skip = 0, sort, query, queryAttribute } = ctx.request.query;
const { limit, skip = 0, sort, query, queryAttribute, source } = ctx.request.query;
// Find entries using `queries` system
const entries = await strapi.query(ctx.params.model).find({
const entries = await strapi.query(ctx.params.model, source).find({
limit,
skip,
sort,
@ -41,8 +50,10 @@ module.exports = {
},
count: async ctx => {
const { source } = ctx.request.query;
// Count using `queries` system
const count = await strapi.query(ctx.params.model).count();
const count = await strapi.query(ctx.params.model, source).count();
ctx.body = {
count: _.isNumber(count) ? count : _.toNumber(count)
@ -50,8 +61,10 @@ module.exports = {
},
findOne: async ctx => {
const { source } = ctx.request.query;
// Find an entry using `queries` system
const entry = await strapi.query(ctx.params.model).findOne({
const entry = await strapi.query(ctx.params.model, source).findOne({
id: ctx.params.id
});
@ -64,8 +77,10 @@ module.exports = {
},
create: async ctx => {
const { source } = ctx.request.query;
// Create an entry using `queries` system
const entryCreated = await strapi.query(ctx.params.model).create({
const entryCreated = await strapi.query(ctx.params.model, source).create({
values: ctx.request.body
});
@ -73,8 +88,10 @@ module.exports = {
},
update: async ctx => {
const { source } = ctx.request.query;
// Add current model to the flow of updates.
const entry = strapi.query(ctx.params.model).update({
const entry = strapi.query(ctx.params.model, source).update({
id: ctx.params.id,
values: ctx.request.body
});
@ -84,7 +101,9 @@ module.exports = {
},
delete: async ctx => {
const { source } = ctx.request.query;
const params = ctx.params;
const response = await strapi.query(params.model).findOne({
id: params.id
});
@ -102,11 +121,11 @@ module.exports = {
if (!_.isEmpty(params.values)) {
// Run update to remove all relationships.
await strapi.query(params.model).update(params);
await strapi.query(params.model, source).update(params);
}
// Delete an entry using `queries` system
const entryDeleted = await strapi.query(params.model).delete({
const entryDeleted = await strapi.query(params.model, source).delete({
id: params.id
});

View File

@ -11,9 +11,9 @@ const bootstrap = (plugin) => new Promise((resolve, reject) => {
links: [{
label: 'Users',
destination: 'user',
plugin: 'content-manager'
plugin: 'content-manager',
}],
name: 'Content Types'
name: 'Content Types',
});
return resolve(plugin);

View File

@ -6,6 +6,10 @@
"content-manager": {
"controllers": {
"contentmanager": {
"identity": {
"enabled": false,
"policy": ""
},
"models": {
"enabled": false,
"policy": ""
@ -33,10 +37,6 @@
"delete": {
"enabled": false,
"policy": ""
},
"identity": {
"enabled": false,
"policy": ""
}
}
}

View File

@ -22,3 +22,7 @@ npm run test
# Test `strapi-plugin-content-type-builder`
cd ../strapi-plugin-content-type-builder
npm run test
# Test `strapi-plugin-content-type-builder`
cd ../strapi-plugin-users-permissions
npm run test