Merge branch 'develop' of github.com:strapi/strapi into ctm/repeatable-edit-view

This commit is contained in:
soupette 2019-07-25 12:07:01 +02:00
commit a2dc4b22d1
6 changed files with 92 additions and 75 deletions

View File

@ -106,9 +106,14 @@ module.exports = {
return ctx.notFound('contentType.notFound'); return ctx.notFound('contentType.notFound');
} }
const schema = service.formatContentTypeSchema(contentType);
let input; let input;
try { try {
input = await createModelConfigurationSchema(contentType).validate(body, { input = await createModelConfigurationSchema(
contentType,
schema
).validate(body, {
abortEarly: false, abortEarly: false,
stripUnknown: true, stripUnknown: true,
strict: true, strict: true,
@ -130,7 +135,7 @@ module.exports = {
const data = { const data = {
uid, uid,
source, source,
schema: service.formatContentTypeSchema(contentType), schema,
...contentTypeConfigurations, ...contentTypeConfigurations,
}; };

View File

@ -56,17 +56,23 @@ module.exports = {
const group = strapi.groups[uid]; const group = strapi.groups[uid];
const ctService = strapi.plugins['content-manager'].services.contenttypes;
if (!group) { if (!group) {
return ctx.notFound('group.notFound'); return ctx.notFound('group.notFound');
} }
const schema = ctService.formatContentTypeSchema(group);
let input; let input;
try { try {
input = await createModelConfigurationSchema(group).validate(body, { input = await createModelConfigurationSchema(group, schema).validate(
body,
{
abortEarly: false, abortEarly: false,
stripUnknown: true, stripUnknown: true,
strict: true, strict: true,
}); }
);
} catch (error) { } catch (error) {
return ctx.badRequest(null, { return ctx.badRequest(null, {
name: 'validationError', name: 'validationError',
@ -77,12 +83,11 @@ module.exports = {
const groupService = strapi.plugins['content-manager'].services.groups; const groupService = strapi.plugins['content-manager'].services.groups;
await groupService.setConfiguration(uid, input); await groupService.setConfiguration(uid, input);
const ctService = strapi.plugins['content-manager'].services.contenttypes;
const configurations = await groupService.getConfiguration(uid); const configurations = await groupService.getConfiguration(uid);
const data = { const data = {
uid, uid,
schema: ctService.formatContentTypeSchema(group), schema,
...configurations, ...configurations,
}; };

View File

@ -1,30 +1,28 @@
'use strict'; 'use strict';
const yup = require('yup'); const yup = require('yup');
const {
isListable,
hasRelationAttribute,
hasEditableAttribute,
} = require('../../services/utils/configuration/attributes');
/** /**
* Creates the validation schema for content-type configurations * Creates the validation schema for content-type configurations
*/ */
module.exports = model => module.exports = (model, schema) =>
yup yup
.object() .object()
.shape({ .shape({
settings: createSettingsSchema(model), settings: createSettingsSchema(model, schema),
metadatas: createMetadasSchema(model), metadatas: createMetadasSchema(model, schema),
layouts: createLayoutsSchema(model), layouts: createLayoutsSchema(model, schema),
}) })
.noUnknown(); .noUnknown();
// TODO: do sth to clean the keys configurable, private etc const createSettingsSchema = (model, schema) => {
const validAttributes = Object.keys(schema.attributes).filter(key =>
const createSettingsSchema = model => { isListable(schema, key)
const validAttributes = Object.keys(model.allAttributes).filter(key => {
return (
model.allAttributes[key].type &&
!['json', 'password', 'group'].includes(model.allAttributes[key].type)
); );
});
const attrs = ['id'].concat(validAttributes);
return yup return yup
.object() .object()
@ -41,12 +39,12 @@ const createSettingsSchema = model => {
// should be reset when the type changes // should be reset when the type changes
mainField: yup mainField: yup
.string() .string()
.oneOf(attrs) .oneOf(validAttributes)
.default('id'), .default('id'),
// should be reset when the type changes // should be reset when the type changes
defaultSortBy: yup defaultSortBy: yup
.string() .string()
.oneOf(attrs) .oneOf(validAttributes)
.default('id'), .default('id'),
defaultSortOrder: yup defaultSortOrder: yup
.string() .string()
@ -56,9 +54,9 @@ const createSettingsSchema = model => {
.noUnknown(); .noUnknown();
}; };
const createMetadasSchema = model => { const createMetadasSchema = (model, schema) => {
return yup.object().shape( return yup.object().shape(
['id'].concat(Object.keys(model.allAttributes)).reduce((acc, key) => { Object.keys(schema.attributes).reduce((acc, key) => {
acc[key] = yup acc[key] = yup
.object() .object()
.shape({ .shape({
@ -97,18 +95,18 @@ const ARRAY_TEST = {
test: val => Array.isArray(val), test: val => Array.isArray(val),
}; };
const createLayoutsSchema = model => { const createLayoutsSchema = (model, schema) => {
const validAttributes = Object.keys(model.allAttributes).filter(key => { const validAttributes = Object.keys(schema.attributes).filter(key =>
return ( isListable(schema, key)
model.allAttributes[key].type &&
!['json', 'password', 'group'].includes(model.allAttributes[key].type)
); );
});
const attrs = ['id'].concat(validAttributes); const editAttributes = Object.keys(schema.attributes).filter(key =>
const relationAttributes = Array.isArray(model.associations) hasEditableAttribute(schema, key)
? model.associations.map(assoc => assoc.alias) );
: [];
const relationAttributes = Object.keys(schema.attributes).filter(key =>
hasRelationAttribute(schema, key)
);
return yup.object().shape({ return yup.object().shape({
edit: yup edit: yup
@ -120,11 +118,7 @@ const createLayoutsSchema = model => {
.shape({ .shape({
name: yup name: yup
.string() .string()
.oneOf( .oneOf(editAttributes)
Object.keys(model.allAttributes).filter(
key => model.allAttributes[key].type
)
)
.required(), .required(),
size: yup size: yup
.number() .number()
@ -138,7 +132,7 @@ const createLayoutsSchema = model => {
.test(ARRAY_TEST), .test(ARRAY_TEST),
list: yup list: yup
.array() .array()
.of(yup.string().oneOf(attrs)) .of(yup.string().oneOf(validAttributes))
.test(ARRAY_TEST), .test(ARRAY_TEST),
editRelations: yup editRelations: yup
.array() .array()

View File

@ -3,6 +3,10 @@
const _ = require('lodash'); const _ = require('lodash');
const NON_SORTABLES = ['group', 'json', 'relation']; const NON_SORTABLES = ['group', 'json', 'relation'];
const isListable = (schema, name) =>
isSortable(schema, name) && schema.attributes[name].type != 'password';
const isSortable = (schema, name) => { const isSortable = (schema, name) => {
if (!_.has(schema.attributes, name)) { if (!_.has(schema.attributes, name)) {
return false; return false;
@ -49,9 +53,37 @@ const isTimestamp = (schema, name) => {
const isRelation = attribute => attribute.type === 'relation'; const isRelation = attribute => attribute.type === 'relation';
const hasRelationAttribute = (schema, name) => {
if (!_.has(schema.attributes, name)) {
return false;
}
return isRelation(schema.attributes[name]);
};
const hasEditableAttribute = (schema, name) => {
if (!_.has(schema.attributes, name)) {
return false;
}
if (!isVisible(schema, name)) {
return false;
}
if (isRelation(schema.attributes[name])) {
if (schema.modelType === 'group') return true;
return false;
}
return true;
};
module.exports = { module.exports = {
isSortable, isSortable,
isVisible, isVisible,
isSearchable, isSearchable,
isRelation, isRelation,
isListable,
hasEditableAttribute,
hasRelationAttribute,
}; };

View File

@ -1,7 +1,12 @@
'use strict'; 'use strict';
const _ = require('lodash'); const _ = require('lodash');
const { isSortable, isVisible, isRelation } = require('./attributes'); const {
isListable,
isVisible,
hasEditableAttribute,
hasRelationAttribute,
} = require('./attributes');
const DEFAULT_LIST_LENGTH = 4; const DEFAULT_LIST_LENGTH = 4;
const MAX_ROW_SIZE = 12; const MAX_ROW_SIZE = 12;
@ -37,7 +42,7 @@ async function createDefaultLayouts(schema) {
function createDefaultListLayout(schema) { function createDefaultListLayout(schema) {
return Object.keys(schema.attributes) return Object.keys(schema.attributes)
.filter(name => isSortable(schema, name)) .filter(name => isListable(schema, name))
.slice(0, DEFAULT_LIST_LENGTH); .slice(0, DEFAULT_LIST_LENGTH);
} }
@ -67,7 +72,7 @@ function syncLayouts(configuration, schema) {
const { list = [], editRelations = [], edit = [] } = const { list = [], editRelations = [], edit = [] } =
configuration.layouts || {}; configuration.layouts || {};
const cleanList = list.filter(attr => isSortable(schema, attr)); const cleanList = list.filter(attr => isListable(schema, attr));
const cleanEditRelations = editRelations.filter(attr => const cleanEditRelations = editRelations.filter(attr =>
hasRelationAttribute(schema, attr) hasRelationAttribute(schema, attr)
@ -120,13 +125,13 @@ function syncLayouts(configuration, schema) {
// only add valid listable attributes // only add valid listable attributes
layout.list = _.uniq( layout.list = _.uniq(
layout.list layout.list
.concat(newAttributes.filter(key => isSortable(schema, key))) .concat(newAttributes.filter(key => isListable(schema, key)))
.slice(0, DEFAULT_LIST_LENGTH) .slice(0, DEFAULT_LIST_LENGTH)
); );
} }
// add new relations to layout // add new relations to layout
if (schema.type !== 'group') { if (schema.modelType !== 'group') {
const newRelations = newAttributes.filter(key => const newRelations = newAttributes.filter(key =>
hasRelationAttribute(schema, key) hasRelationAttribute(schema, key)
); );
@ -171,31 +176,6 @@ const appendToEditLayout = (layout = [], keysToAppend, schema) => {
return layout; return layout;
}; };
const hasRelationAttribute = (schema, name) => {
if (!_.has(schema.attributes, name)) {
return false;
}
return isRelation(schema.attributes[name]);
};
const hasEditableAttribute = (schema, name) => {
if (!_.has(schema.attributes, name)) {
return false;
}
if (!isVisible(schema, name)) {
return false;
}
if (isRelation(schema.attributes[name])) {
if (schema.modelType === 'group') return true;
return false;
}
return true;
};
module.exports = { module.exports = {
createDefaultLayouts, createDefaultLayouts,
syncLayouts, syncLayouts,

View File

@ -4,6 +4,7 @@ const _ = require('lodash');
const pickSchemaFields = model => const pickSchemaFields = model =>
_.pick(model, [ _.pick(model, [
'modelType',
'connection', 'connection',
'collectionName', 'collectionName',
'info', 'info',