mirror of
https://github.com/strapi/strapi.git
synced 2025-11-03 11:25:17 +00:00
Merge branch 'develop' of github.com:strapi/strapi into ctm/repeatable-edit-view
This commit is contained in:
commit
a2dc4b22d1
@ -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,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -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,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -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()
|
||||||
|
|||||||
@ -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,
|
||||||
};
|
};
|
||||||
|
|||||||
@ -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,
|
||||||
|
|||||||
@ -4,6 +4,7 @@ const _ = require('lodash');
|
|||||||
|
|
||||||
const pickSchemaFields = model =>
|
const pickSchemaFields = model =>
|
||||||
_.pick(model, [
|
_.pick(model, [
|
||||||
|
'modelType',
|
||||||
'connection',
|
'connection',
|
||||||
'collectionName',
|
'collectionName',
|
||||||
'info',
|
'info',
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user