Merge branch 'features/custom-fields' of github.com:strapi/strapi into custom-fields/rm-plugin

This commit is contained in:
Mark Kaylor 2022-09-13 08:20:49 -04:00
commit a67ff09585
18 changed files with 107 additions and 98 deletions

View File

@ -28,7 +28,7 @@ class CustomFields {
register(customFields) {
if (Array.isArray(customFields)) {
// If several custom fields are passed, register them one by one
customFields.forEach(customField => {
customFields.forEach((customField) => {
this.register(customField);
});
} else {

View File

@ -306,6 +306,7 @@ exports[`<AttributeOptions /> renders and matches the snapshot 1`] = `
class="c20"
>
<svg
aria-hidden="true"
class="c21"
fill="none"
height="1em"
@ -373,6 +374,7 @@ exports[`<AttributeOptions /> renders and matches the snapshot 1`] = `
class="c20"
>
<svg
aria-hidden="true"
class="c21"
fill="none"
height="1em"
@ -440,6 +442,7 @@ exports[`<AttributeOptions /> renders and matches the snapshot 1`] = `
class="c20"
>
<svg
aria-hidden="true"
class="c21"
fill="none"
height="1em"
@ -509,6 +512,7 @@ exports[`<AttributeOptions /> renders and matches the snapshot 1`] = `
class="c20"
>
<svg
aria-hidden="true"
class="c21"
fill="none"
height="1em"
@ -572,6 +576,7 @@ exports[`<AttributeOptions /> renders and matches the snapshot 1`] = `
class="c20"
>
<svg
aria-hidden="true"
class="c21"
fill="none"
height="1em"
@ -639,6 +644,7 @@ exports[`<AttributeOptions /> renders and matches the snapshot 1`] = `
class="c20"
>
<svg
aria-hidden="true"
class="c21"
fill="none"
height="1em"
@ -708,6 +714,7 @@ exports[`<AttributeOptions /> renders and matches the snapshot 1`] = `
class="c20"
>
<svg
aria-hidden="true"
class="c21"
fill="none"
height="1em"
@ -773,6 +780,7 @@ exports[`<AttributeOptions /> renders and matches the snapshot 1`] = `
class="c20"
>
<svg
aria-hidden="true"
class="c21"
fill="none"
height="1em"
@ -842,6 +850,7 @@ exports[`<AttributeOptions /> renders and matches the snapshot 1`] = `
class="c20"
>
<svg
aria-hidden="true"
class="c21"
fill="none"
height="1em"
@ -909,6 +918,7 @@ exports[`<AttributeOptions /> renders and matches the snapshot 1`] = `
class="c20"
>
<svg
aria-hidden="true"
class="c21"
fill="none"
height="1em"
@ -978,6 +988,7 @@ exports[`<AttributeOptions /> renders and matches the snapshot 1`] = `
class="c20"
>
<svg
aria-hidden="true"
class="c21"
fill="none"
height="1em"
@ -1043,6 +1054,7 @@ exports[`<AttributeOptions /> renders and matches the snapshot 1`] = `
class="c20"
>
<svg
aria-hidden="true"
class="c21"
fill="none"
height="1em"
@ -1110,6 +1122,7 @@ exports[`<AttributeOptions /> renders and matches the snapshot 1`] = `
class="c20"
>
<svg
aria-hidden="true"
class="c21"
fill="none"
height="1em"
@ -1183,6 +1196,7 @@ exports[`<AttributeOptions /> renders and matches the snapshot 1`] = `
class="c20"
>
<svg
aria-hidden="true"
class="c21"
fill="none"
height="1em"

View File

@ -1,4 +1,4 @@
const getPadding = index => {
const getPadding = (index) => {
const isOdd = index % 2 === 1;
const paddingLeft = isOdd ? 2 : 0;
const paddingRight = isOdd ? 0 : 2;

View File

@ -94,6 +94,11 @@ const formatAttributes = (attributes, mainDataUID) => {
acc[name] = removeNullKeys(formattedRelationAttribute);
}
if (currentAttribute.customField) {
const customFieldAttribute = { ...currentAttribute, type: 'customField' };
acc[name] = removeNullKeys(customFieldAttribute);
}
return acc;
}, {});
};

View File

@ -6,7 +6,7 @@ import has from 'lodash/has';
* @param {array} sections The sections to mutate
*/
const addItemsToFormSection = (formTypeOptions, sections) => {
formTypeOptions.forEach(item => {
formTypeOptions.forEach((item) => {
if (!has(item, 'sectionTitle')) {
// When there is no sectionTitle key,
// add the item to the default section

View File

@ -1412,6 +1412,7 @@ exports[`<ListView /> renders and matches the snapshot 1`] = `
spacing="4"
>
<svg
aria-hidden="true"
class="c34"
fill="none"
height="1em"
@ -1520,6 +1521,7 @@ exports[`<ListView /> renders and matches the snapshot 1`] = `
spacing="4"
>
<svg
aria-hidden="true"
class="c34"
fill="none"
height="1em"
@ -1632,6 +1634,7 @@ exports[`<ListView /> renders and matches the snapshot 1`] = `
spacing="4"
>
<svg
aria-hidden="true"
class="c34"
fill="none"
height="1em"
@ -1742,6 +1745,7 @@ exports[`<ListView /> renders and matches the snapshot 1`] = `
spacing="4"
>
<svg
aria-hidden="true"
class="c34"
fill="none"
height="1em"
@ -1852,6 +1856,7 @@ exports[`<ListView /> renders and matches the snapshot 1`] = `
spacing="4"
>
<svg
aria-hidden="true"
class="c34"
fill="none"
height="1em"
@ -1960,6 +1965,7 @@ exports[`<ListView /> renders and matches the snapshot 1`] = `
spacing="4"
>
<svg
aria-hidden="true"
class="c34"
fill="none"
height="1em"
@ -2070,6 +2076,7 @@ exports[`<ListView /> renders and matches the snapshot 1`] = `
spacing="4"
>
<svg
aria-hidden="true"
class="c34"
fill="none"
height="1em"
@ -2174,6 +2181,7 @@ exports[`<ListView /> renders and matches the snapshot 1`] = `
spacing="4"
>
<svg
aria-hidden="true"
class="c34"
fill="none"
height="1em"
@ -2321,6 +2329,7 @@ exports[`<ListView /> renders and matches the snapshot 1`] = `
spacing="4"
>
<svg
aria-hidden="true"
class="c34"
fill="none"
height="1em"
@ -2448,6 +2457,7 @@ exports[`<ListView /> renders and matches the snapshot 1`] = `
spacing="4"
>
<svg
aria-hidden="true"
class="c34"
fill="none"
height="1em"
@ -2575,6 +2585,7 @@ exports[`<ListView /> renders and matches the snapshot 1`] = `
spacing="4"
>
<svg
aria-hidden="true"
class="c34"
fill="none"
height="1em"
@ -2724,6 +2735,7 @@ exports[`<ListView /> renders and matches the snapshot 1`] = `
spacing="4"
>
<svg
aria-hidden="true"
class="c34"
fill="none"
height="1em"
@ -2871,6 +2883,7 @@ exports[`<ListView /> renders and matches the snapshot 1`] = `
spacing="4"
>
<svg
aria-hidden="true"
class="c34"
fill="none"
height="1em"
@ -2998,6 +3011,7 @@ exports[`<ListView /> renders and matches the snapshot 1`] = `
spacing="4"
>
<svg
aria-hidden="true"
class="c34"
fill="none"
height="1em"
@ -3125,6 +3139,7 @@ exports[`<ListView /> renders and matches the snapshot 1`] = `
spacing="4"
>
<svg
aria-hidden="true"
class="c34"
fill="none"
height="1em"
@ -3274,6 +3289,7 @@ exports[`<ListView /> renders and matches the snapshot 1`] = `
spacing="4"
>
<svg
aria-hidden="true"
class="c34"
fill="none"
height="1em"
@ -3678,6 +3694,7 @@ exports[`<ListView /> renders and matches the snapshot 1`] = `
spacing="4"
>
<svg
aria-hidden="true"
class="c34"
fill="none"
height="1em"
@ -3805,6 +3822,7 @@ exports[`<ListView /> renders and matches the snapshot 1`] = `
spacing="4"
>
<svg
aria-hidden="true"
class="c34"
fill="none"
height="1em"
@ -3932,6 +3950,7 @@ exports[`<ListView /> renders and matches the snapshot 1`] = `
spacing="4"
>
<svg
aria-hidden="true"
class="c34"
fill="none"
height="1em"
@ -4123,6 +4142,7 @@ exports[`<ListView /> renders and matches the snapshot 1`] = `
spacing="4"
>
<svg
aria-hidden="true"
class="c34"
fill="none"
height="1em"
@ -4250,6 +4270,7 @@ exports[`<ListView /> renders and matches the snapshot 1`] = `
spacing="4"
>
<svg
aria-hidden="true"
class="c34"
fill="none"
height="1em"
@ -4377,6 +4398,7 @@ exports[`<ListView /> renders and matches the snapshot 1`] = `
spacing="4"
>
<svg
aria-hidden="true"
class="c34"
fill="none"
height="1em"
@ -4504,6 +4526,7 @@ exports[`<ListView /> renders and matches the snapshot 1`] = `
spacing="4"
>
<svg
aria-hidden="true"
class="c34"
fill="none"
height="1em"
@ -4633,6 +4656,7 @@ exports[`<ListView /> renders and matches the snapshot 1`] = `
spacing="4"
>
<svg
aria-hidden="true"
class="c34"
fill="none"
height="1em"
@ -4762,6 +4786,7 @@ exports[`<ListView /> renders and matches the snapshot 1`] = `
spacing="4"
>
<svg
aria-hidden="true"
class="c34"
fill="none"
height="1em"
@ -4957,6 +4982,7 @@ exports[`<ListView /> renders and matches the snapshot 1`] = `
spacing="4"
>
<svg
aria-hidden="true"
class="c34"
fill="none"
height="1em"
@ -5084,6 +5110,7 @@ exports[`<ListView /> renders and matches the snapshot 1`] = `
spacing="4"
>
<svg
aria-hidden="true"
class="c34"
fill="none"
height="1em"
@ -5211,6 +5238,7 @@ exports[`<ListView /> renders and matches the snapshot 1`] = `
spacing="4"
>
<svg
aria-hidden="true"
class="c34"
fill="none"
height="1em"
@ -5359,6 +5387,7 @@ exports[`<ListView /> renders and matches the snapshot 1`] = `
spacing="4"
>
<svg
aria-hidden="true"
class="c34"
fill="none"
height="1em"
@ -5486,6 +5515,7 @@ exports[`<ListView /> renders and matches the snapshot 1`] = `
spacing="4"
>
<svg
aria-hidden="true"
class="c34"
fill="none"
height="1em"
@ -5613,6 +5643,7 @@ exports[`<ListView /> renders and matches the snapshot 1`] = `
spacing="4"
>
<svg
aria-hidden="true"
class="c34"
fill="none"
height="1em"
@ -5740,6 +5771,7 @@ exports[`<ListView /> renders and matches the snapshot 1`] = `
spacing="4"
>
<svg
aria-hidden="true"
class="c34"
fill="none"
height="1em"
@ -5869,6 +5901,7 @@ exports[`<ListView /> renders and matches the snapshot 1`] = `
spacing="4"
>
<svg
aria-hidden="true"
class="c34"
fill="none"
height="1em"
@ -5998,6 +6031,7 @@ exports[`<ListView /> renders and matches the snapshot 1`] = `
spacing="4"
>
<svg
aria-hidden="true"
class="c34"
fill="none"
height="1em"
@ -6234,6 +6268,7 @@ exports[`<ListView /> renders and matches the snapshot 1`] = `
spacing="4"
>
<svg
aria-hidden="true"
class="c34"
fill="none"
height="1em"
@ -6361,6 +6396,7 @@ exports[`<ListView /> renders and matches the snapshot 1`] = `
spacing="4"
>
<svg
aria-hidden="true"
class="c34"
fill="none"
height="1em"
@ -6490,6 +6526,7 @@ exports[`<ListView /> renders and matches the snapshot 1`] = `
spacing="4"
>
<svg
aria-hidden="true"
class="c34"
fill="none"
height="1em"

View File

@ -9,7 +9,7 @@ const createSchema = require('./model-schema');
const { removeEmptyDefaults } = require('./data-transform');
const VALID_RELATIONS = ['oneToOne', 'oneToMany'];
const VALID_TYPES = [...DEFAULT_TYPES, 'component'];
const VALID_TYPES = [...DEFAULT_TYPES, 'component', 'customField'];
const componentSchema = createSchema(VALID_TYPES, VALID_RELATIONS, {
modelType: modelTypes.COMPONENT,

View File

@ -36,7 +36,7 @@ const VALID_RELATIONS = {
/**
* Allowed types
*/
const VALID_TYPES = [...DEFAULT_TYPES, 'uid', 'component', 'dynamiczone'];
const VALID_TYPES = [...DEFAULT_TYPES, 'uid', 'component', 'dynamiczone', 'customField'];
/**
* Returns a yup schema to validate a content type payload

View File

@ -8,7 +8,6 @@ const { nameToSlug, nameToCollectionName } = require('@strapi/utils');
const { ApplicationError } = require('@strapi/utils').errors;
const { isConfigurable } = require('../../utils/attributes');
const createSchemaHandler = require('./schema-handler');
const convertCustomFieldType = require('./utils/convert-custom-field-type');
module.exports = function createComponentBuilder() {
return {
@ -33,15 +32,12 @@ module.exports = function createComponentBuilder() {
* create a component in the tmpComponent map
*/
createComponent(infos) {
const { attributes } = infos;
const uid = this.createComponentUID(infos);
if (this.components.has(uid)) {
throw new ApplicationError('component.alreadyExists');
}
convertCustomFieldType(attributes);
const handler = createSchemaHandler({
dir: path.join(strapi.dirs.app.components, nameToSlug(infos.category)),
filename: `${nameToSlug(infos.displayName)}.json`,
@ -76,13 +72,12 @@ module.exports = function createComponentBuilder() {
* create a component in the tmpComponent map
*/
editComponent(infos) {
const { uid, attributes } = infos;
const { uid } = infos;
if (!this.components.has(uid)) {
throw new ApplicationError('component.notFound');
}
convertCustomFieldType(attributes);
const component = this.components.get(uid);
const [, nameUID] = uid.split('.');

View File

@ -8,7 +8,6 @@ const { ApplicationError } = require('@strapi/utils').errors;
const { isRelation, isConfigurable } = require('../../utils/attributes');
const { typeKinds } = require('../constants');
const createSchemaHandler = require('./schema-handler');
const convertCustomFieldType = require('./utils/convert-custom-field-type');
const reuseUnsetPreviousProperties = (newAttribute, oldAttribute) => {
_.defaults(
@ -72,15 +71,12 @@ module.exports = function createComponentBuilder() {
* @returns {object} new content type
*/
createContentType(infos) {
const { attributes } = infos;
const uid = createContentTypeUID(infos);
if (this.contentTypes.has(uid)) {
throw new ApplicationError('contentType.alreadyExists');
}
convertCustomFieldType(attributes);
const contentType = createSchemaHandler({
modelName: infos.singularName,
dir: path.join(
@ -133,14 +129,12 @@ module.exports = function createComponentBuilder() {
},
editContentType(infos) {
const { uid, attributes } = infos;
const { uid } = infos;
if (!this.contentTypes.has(uid)) {
throw new ApplicationError('contentType.notFound');
}
convertCustomFieldType(attributes);
const contentType = this.contentTypes.get(uid);
const oldAttributes = contentType.schema.attributes;

View File

@ -1,27 +0,0 @@
'use strict';
/**
* @description
* Sets attribute.type to customField
* @param {object} attributes Attributes found on content-type or component
*/
const convertCustomFieldType = attributes => {
Object.values(attributes).forEach(attribute => {
if (attribute.customField) {
// Use the custom field uid sent from the admin to get its equivalent on the server
// The getter will throw an error if the custom field is not found
const customField = strapi.container.get('custom-fields').get(attribute.customField);
if (customField.type !== attribute.type) {
// When there is a type mismatch between admin and server
throw new Error(
`Custom field: "${attribute.customField}" sent type: "${attribute.type}" from the admin but the server expected type: "${customField.type}"`
);
}
attribute.type = 'customField';
}
});
};
module.exports = convertCustomFieldType;

View File

@ -4,7 +4,7 @@ const customFieldsRegistry = require('../custom-fields');
const strapi = {
plugins: { plugintest: 'foo' },
plugin: jest.fn(plugin => strapi.plugins[plugin]),
plugin: jest.fn((plugin) => strapi.plugins[plugin]),
};
describe('Custom fields registry', () => {

View File

@ -3,7 +3,7 @@
const { has } = require('lodash/fp');
const validators = require('../../services/entity-validator/validators');
const customFieldsRegistry = strapi => {
const customFieldsRegistry = (strapi) => {
const customFields = {};
return {

View File

@ -1,6 +1,6 @@
'use strict';
const createCustomFields = strapi => {
const createCustomFields = (strapi) => {
return {
register(customField) {
strapi.container.get('custom-fields').add(customField);

View File

@ -1,11 +1,11 @@
'use strict';
const convertCustomFieldType = strapi => {
const convertCustomFieldType = (strapi) => {
const allContentTypeSchemaAttributes = Object.values(strapi.contentTypes).map(
schema => schema.attributes
(schema) => schema.attributes
);
const allComponentSchemaAttributes = Object.values(strapi.components).map(
schema => schema.attributes
(schema) => schema.attributes
);
const allSchemasAttributes = [...allContentTypeSchemaAttributes, ...allComponentSchemaAttributes];

View File

@ -5,13 +5,13 @@ import { Flex } from '@strapi/design-system/Flex';
import Paint from '@strapi/icons/Paint';
const IconBox = styled(Flex)`
// Hard code color values
// to stay consistent between themes
background-color: #f0f0ff; // primary100
border: 1px solid #d9d8ff; // primary200
/* Hard code color values */
/* to stay consistent between themes */
background-color: #f0f0ff; /* primary100 */
border: 1px solid #d9d8ff; /* primary200 */
svg > path {
fill: #4945ff; // primary600
fill: #4945ff; /* primary600 */
}
`;

View File

@ -1,7 +1,7 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`<ColorPickerInput /> renders and matches the snapshot 1`] = `
.c10 {
.c9 {
border: 0;
-webkit-clip: rect(0 0 0 0);
clip: rect(0 0 0 0);
@ -37,12 +37,12 @@ exports[`<ColorPickerInput /> renders and matches the snapshot 1`] = `
}
.c8 {
color: #32324d;
color: #666687;
font-size: 0.875rem;
line-height: 1.43;
}
.c2 {
.c6 {
-webkit-align-items: center;
-webkit-box-align: center;
-ms-flex-align: center;
@ -56,7 +56,7 @@ exports[`<ColorPickerInput /> renders and matches the snapshot 1`] = `
flex-direction: row;
}
.c5 {
.c4 {
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
@ -70,21 +70,21 @@ exports[`<ColorPickerInput /> renders and matches the snapshot 1`] = `
outline: none;
}
.c5 svg {
.c4 svg {
height: 12px;
width: 12px;
}
.c5 svg > g,
.c5 svg path {
.c4 svg > g,
.c4 svg path {
fill: #ffffff;
}
.c5[aria-disabled='true'] {
.c4[aria-disabled='true'] {
pointer-events: none;
}
.c5:after {
.c4:after {
-webkit-transition-property: all;
transition-property: all;
-webkit-transition-duration: 0.2s;
@ -99,11 +99,11 @@ exports[`<ColorPickerInput /> renders and matches the snapshot 1`] = `
border: 2px solid transparent;
}
.c5:focus-visible {
.c4:focus-visible {
outline: none;
}
.c5:focus-visible:after {
.c4:focus-visible:after {
border-radius: 8px;
content: '';
position: absolute;
@ -114,7 +114,7 @@ exports[`<ColorPickerInput /> renders and matches the snapshot 1`] = `
border: 2px solid #4945ff;
}
.c4 {
.c3 {
-webkit-align-items: center;
-webkit-box-align: center;
-ms-flex-align: center;
@ -128,7 +128,7 @@ exports[`<ColorPickerInput /> renders and matches the snapshot 1`] = `
flex-direction: row;
}
.c3 {
.c2 {
font-weight: 600;
color: #32324d;
font-size: 0.75rem;
@ -140,11 +140,11 @@ exports[`<ColorPickerInput /> renders and matches the snapshot 1`] = `
width: 20px;
height: 20px;
margin-right: 10px;
background-color: #ffffff;
background-color: #000000;
border: 1px solid rgba(0,0,0,0.1);
}
.c6 {
.c5 {
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
@ -159,62 +159,53 @@ exports[`<ColorPickerInput /> renders and matches the snapshot 1`] = `
align-items: center;
}
.c6 svg {
.c5 svg {
width: 8px;
height: 8px;
}
.c6 svg > path {
.c5 svg > path {
fill: #8e8ea9;
justify-self: flex-end;
}
.c9 {
text-transform: uppercase;
color: #808080;
}
<div>
<div>
<div
class="c0 c1"
spacing="1"
>
<div
<label
class="c2"
for="color"
>
<label
<div
class="c3"
for="color"
>
<div
class="c4"
>
color-picker
</div>
</label>
</div>
color-picker
</div>
</label>
<button
aria-controls="color-picker-value"
aria-disabled="false"
aria-expanded="false"
aria-haspopup="dialog"
aria-label="Color picker toggle"
class="c5 c6"
class="c4 c5"
type="button"
>
<div
class="c2"
class="c6"
>
<div
class="c7"
color="#ffffff"
color="#000000"
/>
<span
class="c8 c9"
color="#808080"
class="c8"
style="text-transform: uppercase;"
>
#ffffff
#000000
</span>
</div>
<svg
@ -236,7 +227,7 @@ exports[`<ColorPickerInput /> renders and matches the snapshot 1`] = `
</div>
</div>
<div
class="c10"
class="c9"
>
<p
aria-live="polite"

View File

@ -1,7 +1,7 @@
{
"name": "@strapi/plugin-color-picker",
"version": "4.3.6",
"description": "Color picker custom field",
"name": "@strapi/custom-fields",
"version": "4.3.4",
"description": "Strapi maintained Custom Fields",
"strapi": {
"name": "color-picker",
"description": "Color picker custom field",