add options 'editable' and 'restrictRelationsTo' in CTB (#7768)

* add options 'editable' and 'restrictRelationsTo' in CTB

Signed-off-by: Pierre Noël <petersg83@gmail.com>
This commit is contained in:
Pierre Noël 2020-09-10 09:40:26 +02:00 committed by Pierre Noël
parent e10452c245
commit f7bd0886bb
12 changed files with 86 additions and 20 deletions

View File

@ -21,16 +21,7 @@ module.exports = {
const contentTypeService = strapi.plugins['content-type-builder'].services.contenttypes;
const contentTypes = Object.keys(strapi.contentTypes)
.filter(uid => {
if (uid.startsWith('strapi::')) return false;
if (uid === 'plugins::upload.file') return false; // TODO: add a flag in the content type instead
if (kind && _.get(strapi.contentTypes[uid], 'kind', 'collectionType') !== kind) {
return false;
}
return true;
})
.filter(uid => !kind || _.get(strapi.contentTypes[uid], 'kind', 'collectionType') === kind)
.map(uid => contentTypeService.formatContentType(strapi.contentTypes[uid]));
ctx.send({

View File

@ -7,7 +7,7 @@ const { formatYupErrors } = require('strapi-utils');
const { isValidCategoryName, isValidIcon } = require('./common');
const createSchema = require('./model-schema');
const { removeEmptyDefaults } = require('./data-transform');
const { modelTypes, DEFAULT_TYPES } = require('./constants');
const { modelTypes, DEFAULT_TYPES } = require('../../services/constants');
const VALID_RELATIONS = ['oneWay', 'manyWay'];
const VALID_TYPES = [...DEFAULT_TYPES, 'component'];

View File

@ -8,7 +8,7 @@ const pluralize = require('pluralize');
const createSchema = require('./model-schema');
const { removeEmptyDefaults, removeDeletedUIDTargetFields } = require('./data-transform');
const { nestedComponentSchema } = require('./component');
const { modelTypes, DEFAULT_TYPES, typeKinds } = require('./constants');
const { modelTypes, DEFAULT_TYPES, typeKinds } = require('../../services/constants');
/**
* Allowed relation per type kind

View File

@ -3,7 +3,7 @@
const _ = require('lodash');
const yup = require('yup');
const { modelTypes, FORBIDDEN_ATTRIBUTE_NAMES, typeKinds } = require('./constants');
const { modelTypes, FORBIDDEN_ATTRIBUTE_NAMES, typeKinds } = require('../../services/constants');
const { isValidCollectionName, isValidKey } = require('./common');
const getTypeValidator = require('./types');
const getRelationValidator = require('./relations');

View File

@ -2,13 +2,28 @@
const yup = require('yup');
const { validators, isValidName } = require('./common');
const { typeKinds } = require('./constants');
const { typeKinds, coreUids } = require('../../services/constants');
const REVERSE_RELATIONS = ['oneToOne', 'oneToMany', 'manyToOne', 'manyToMany'];
const STRAPI_USER_RELATIONS = ['oneWay', 'manyWay'];
const isValidNature = validNatures =>
function(value) {
const allowedRelations =
this.parent.target === coreUids.STRAPI_USER ? STRAPI_USER_RELATIONS : validNatures;
return allowedRelations.includes(value)
? true
: this.createError({
path: this.path,
message: `must be one of the following values: ${allowedRelations.join(', ')}`,
});
};
module.exports = (obj, validNatures) => {
const contentTypesUIDs = Object.keys(strapi.contentTypes)
.filter(key => strapi.contentTypes[key].kind === typeKinds.COLLECTION_TYPE)
.filter(key => !key.startsWith(coreUids.PREFIX) || key === coreUids.STRAPI_USER)
.concat(['__self__', '__contentType__']);
return {
@ -18,7 +33,7 @@ module.exports = (obj, validNatures) => {
.required(),
nature: yup
.string()
.oneOf(validNatures)
.test('isValidNature', isValidNature(validNatures))
.required(),
unique: validators.unique.nullable(),
configurable: yup.boolean().nullable(),

View File

@ -13,7 +13,7 @@ const {
isValidRegExpPattern,
} = require('./common');
const { hasComponent } = require('../../utils/attributes');
const { modelTypes, VALID_UID_TARGETS } = require('./constants');
const { modelTypes, VALID_UID_TARGETS } = require('../../services/constants');
const maxLengthIsGreaterThanOrEqualToMinLength = {
name: 'isGreaterThanMin',

View File

@ -8,6 +8,41 @@ const createBuilder = require('./schema-builder');
const apiHandler = require('./api-handler');
const { formatAttributes, replaceTemporaryUIDs } = require('../utils/attributes');
const { nameToSlug, contentTypes: contentTypesUtils } = require('strapi-utils');
const { coreUids, pluginsUids } = require('./constants');
const isContentTypeEditable = (contentType = {}) => {
const { uid } = contentType;
return !uid.startsWith(coreUids.PREFIX) && uid !== pluginsUids.UPLOAD_FILE;
};
const getRestrictRelationsTo = (contentType = {}) => {
const { uid } = contentType;
if (uid === coreUids.STRAPI_USER) {
return ['oneWay', 'manyWay'];
}
if (uid.startsWith(coreUids.PREFIX) || uid === pluginsUids.UPLOAD_FILE) {
return [];
}
return null;
};
const getformattedName = (contentType = {}) => {
const { uid, info, plugin } = contentType;
const name = _.get(info, 'name') || _.upperFirst(pluralize(uid));
const isUser = name.toLowerCase() === 'user';
if (isUser && plugin === 'admin') {
return 'User (Admin panel)';
}
if (isUser && plugin === 'users-permissions') {
return 'User (Permissions plugin)';
}
return name;
};
/**
* Format a contentType info to be used by the front-end
@ -21,13 +56,15 @@ const formatContentType = contentType => {
plugin,
apiID: modelName,
schema: {
name: _.get(info, 'name') || _.upperFirst(pluralize(uid)),
name: getformattedName(contentType),
description: _.get(info, 'description', ''),
draftAndPublish: contentTypesUtils.hasDraftAndPublish({ options }),
connection,
kind: kind || 'collectionType',
collectionName,
attributes: formatAttributes(contentType),
editable: isContentTypeEditable(contentType),
restrictRelationsTo: getRestrictRelationsTo(contentType),
},
};
};

View File

@ -14,8 +14,10 @@ Object {
"connection": "default",
"description": "My description",
"draftAndPublish": false,
"editable": true,
"kind": "singleType",
"name": "My name",
"restrictRelationsTo": null,
},
"uid": "test-uid",
}

View File

@ -33,6 +33,10 @@ const VALID_UID_TARGETS = ['string', 'text'];
const FORBIDDEN_ATTRIBUTE_NAMES = ['__component', '__contentType'];
const PREFIX = 'strapi::';
const STRAPI_USER = 'strapi::user';
const UPLOAD_FILE = 'plugins::upload.file';
module.exports = {
DEFAULT_TYPES,
typeKinds: {
@ -45,4 +49,11 @@ module.exports = {
},
FORBIDDEN_ATTRIBUTE_NAMES,
VALID_UID_TARGETS,
coreUids: {
STRAPI_USER,
PREFIX,
},
pluginsUids: {
UPLOAD_FILE,
},
};

View File

@ -6,7 +6,7 @@ const pluralize = require('pluralize');
const { isRelation, toUID, isConfigurable } = require('../../utils/attributes');
const { nameToSlug, nameToCollectionName } = require('strapi-utils');
const { typeKinds } = require('../../controllers/validation/constants');
const { typeKinds } = require('../constants');
const createSchemaHandler = require('./schema-handler');
module.exports = function createComponentBuilder() {

View File

@ -14,8 +14,10 @@ Object {
"connection": "default",
"description": "",
"draftAndPublish": false,
"editable": true,
"kind": "collectionType",
"name": "Test Collection Type",
"restrictRelationsTo": null,
},
"uid": "application::test-collection-type.test-collection-type",
},
@ -36,8 +38,10 @@ Object {
"connection": "default",
"description": "",
"draftAndPublish": true,
"editable": true,
"kind": "collectionType",
"name": "CT with DP",
"restrictRelationsTo": null,
},
"uid": "application::ct-with-dp.ct-with-dp",
},
@ -58,8 +62,10 @@ Object {
"connection": "default",
"description": "",
"draftAndPublish": false,
"editable": true,
"kind": "singleType",
"name": "Test Single Type",
"restrictRelationsTo": null,
},
"uid": "application::test-single-type.test-single-type",
},

View File

@ -62,13 +62,17 @@ module.exports = ({ rq }) => {
}
async function modifyContentType(data) {
const sanitizedData = { ...data };
delete sanitizedData.editable;
delete sanitizedData.restrictRelationsTo;
await rq({
url: `/content-type-builder/content-types/application::${data.name}.${data.name}`,
url: `/content-type-builder/content-types/application::${sanitizedData.name}.${sanitizedData.name}`,
method: 'PUT',
body: {
contentType: {
connection: 'default',
...data,
...sanitizedData,
},
},
});