From 41f09d410f941d06b61a7dbad171187102572d77 Mon Sep 17 00:00:00 2001 From: soupette Date: Mon, 18 Nov 2019 19:03:24 +0100 Subject: [PATCH] Init attribute form --- .../src/components/AttributeOption/Button.js | 17 +- .../src/components/AttributeOption/Card.js | 23 -- .../src/components/AttributeOption/index.js | 109 ++++--- .../admin/src/components/ModalHeader/index.js | 17 +- .../containers/DataManagerProvider/index.js | 2 - .../containers/DataManagerProvider/reducer.js | 31 +- .../admin/src/containers/FormModal/index.js | 289 ++++++++++++------ .../containers/FormModal/utils/attributes.js | 23 ++ .../src/containers/FormModal/utils/forms.js | 52 ++++ .../admin/src/containers/LeftMenu/index.js | 53 ++-- .../admin/src/translations/en.json | 87 +++--- .../admin/src/utils/getTrad.js | 5 + 12 files changed, 435 insertions(+), 273 deletions(-) create mode 100644 packages/strapi-plugin-content-type-builder/admin/src/containers/FormModal/utils/attributes.js create mode 100644 packages/strapi-plugin-content-type-builder/admin/src/utils/getTrad.js diff --git a/packages/strapi-plugin-content-type-builder/admin/src/components/AttributeOption/Button.js b/packages/strapi-plugin-content-type-builder/admin/src/components/AttributeOption/Button.js index ae1900a1de..13b6f30bc1 100644 --- a/packages/strapi-plugin-content-type-builder/admin/src/components/AttributeOption/Button.js +++ b/packages/strapi-plugin-content-type-builder/admin/src/components/AttributeOption/Button.js @@ -19,10 +19,19 @@ const Button = styled.button` &:hover, &:active, &:focus { - background: #f7f7f7; - outline: 0; - > div:after { - color: #0097f6; + background: #e6f0fb; + border-color: #aed4fb; + + .attributeIcon { + background-color: #007eff; + + > svg { + g { + path { + fill: #007eff; + } + } + } } } diff --git a/packages/strapi-plugin-content-type-builder/admin/src/components/AttributeOption/Card.js b/packages/strapi-plugin-content-type-builder/admin/src/components/AttributeOption/Card.js index 1b89f7a035..d0a71ba4c3 100644 --- a/packages/strapi-plugin-content-type-builder/admin/src/components/AttributeOption/Card.js +++ b/packages/strapi-plugin-content-type-builder/admin/src/components/AttributeOption/Card.js @@ -6,33 +6,10 @@ const Card = styled.div` align-items: center; max-width: calc(100% - 18px); - &:after { - content: '\f05d'; - position: absolute; - top: 7px; - right: 26px; - color: #e3e9f3; - font-size: 1.4rem; - font-family: 'FontAwesome'; - -webkit-font-smoothing: antialiased; - } - - &:hover { - background: none; - } - - > img { - display: inline-block; - height: 20px; - width: 35px; - margin-right: 10px; - } - > span { white-space: nowrap; color: #9ea7b8; font-size: 1.2rem; - font-style: italic; font-weight: 400; -webkit-font-smoothing: antialiased; margin-top: auto; diff --git a/packages/strapi-plugin-content-type-builder/admin/src/components/AttributeOption/index.js b/packages/strapi-plugin-content-type-builder/admin/src/components/AttributeOption/index.js index 02d2c8e705..2b56f66c8b 100644 --- a/packages/strapi-plugin-content-type-builder/admin/src/components/AttributeOption/index.js +++ b/packages/strapi-plugin-content-type-builder/admin/src/components/AttributeOption/index.js @@ -4,81 +4,76 @@ * */ -import React from 'react'; +import React, { + forwardRef, + useEffect, + useImperativeHandle, + useRef, +} from 'react'; +import { AttributeIcon } from '@buffetjs/core'; import PropTypes from 'prop-types'; import { FormattedMessage } from 'react-intl'; - -import attributeIcons from '../../utils/attributeIcons'; -import pluginId from '../../pluginId'; +import { useHistory } from 'react-router-dom'; +import getTrad from '../../utils/getTrad'; +import useQuery from '../../hooks/useQuery'; import Button from './Button'; import Card from './Card'; -class AttributeOption extends React.Component { - componentDidUpdate(prevProps) { - const { isDisplayed, nodeToFocus, tabIndex } = this.props; +const AttributeOption = forwardRef(({ tabIndex, type }, ref) => { + const buttonRef = useRef(); + const tabRef = useRef(); + const query = useQuery(); + const { push } = useHistory(); + tabRef.current = tabIndex; - if ( - prevProps.isDisplayed !== isDisplayed && - isDisplayed && - nodeToFocus === tabIndex - ) { - this.focusNode(); + useImperativeHandle(ref, () => ({ + focus: () => { + buttonRef.current.focus(); + }, + })); + + useEffect(() => { + if (tabRef.current === 0) { + buttonRef.current.focus(); } + }, []); - if (prevProps.nodeToFocus !== nodeToFocus && nodeToFocus === tabIndex) { - this.focusNode(); - } - } + const handleClick = () => { + const forTarget = query.get('for'); + const target = query.get('target'); - button = React.createRef(); - - focusNode = () => { - const { current } = this.button; - - current.focus(); + push({ + search: `modalType=attribute&actionType=create&settingType=base&for=${forTarget}&target=${target}&attributeType=${type}`, + }); }; - render() { - const { description, onClick, tabIndex, type } = this.props; + return ( +
+ +
+ ); +}); - return ( -
- -
- ); - } -} +AttributeOption.displayName = 'AttributeOption'; AttributeOption.defaultProps = { - description: 'app.utils.defaultMessage', - isDisplayed: false, - nodeToFocus: -1, - onClick: () => {}, tabIndex: 0, - type: 'string', + type: 'text', }; AttributeOption.propTypes = { - description: PropTypes.string, - isDisplayed: PropTypes.bool, - nodeToFocus: PropTypes.number, - onClick: PropTypes.func, tabIndex: PropTypes.number, type: PropTypes.string, }; diff --git a/packages/strapi-plugin-content-type-builder/admin/src/components/ModalHeader/index.js b/packages/strapi-plugin-content-type-builder/admin/src/components/ModalHeader/index.js index 9d9cfdfddd..8798261632 100644 --- a/packages/strapi-plugin-content-type-builder/admin/src/components/ModalHeader/index.js +++ b/packages/strapi-plugin-content-type-builder/admin/src/components/ModalHeader/index.js @@ -2,15 +2,20 @@ import React from 'react'; import PropTypes from 'prop-types'; import { HeaderModalTitle } from 'strapi-helper-plugin'; import { AttributeIcon } from '@buffetjs/core'; -import pluginId from '../../pluginId'; import { FormattedMessage } from 'react-intl'; +import { upperFirst } from 'lodash'; +import pluginId from '../../pluginId'; -const ModalHeader = ({ headerId, name, type }) => { +const ModalHeader = ({ headerId, iconType, name }) => { + console.log({ iconType }); return (
- - + + {headerId && ( + + )} + {!headerId && {upperFirst(name)}}
); @@ -18,14 +23,14 @@ const ModalHeader = ({ headerId, name, type }) => { ModalHeader.defaultProps = { headerId: '', + iconType: 'contentType', name: '', - type: 'contentType', }; ModalHeader.propTypes = { headerId: PropTypes.string, + iconType: PropTypes.string, name: PropTypes.string, - type: PropTypes.string, }; export default ModalHeader; diff --git a/packages/strapi-plugin-content-type-builder/admin/src/containers/DataManagerProvider/index.js b/packages/strapi-plugin-content-type-builder/admin/src/containers/DataManagerProvider/index.js index dd34c5d973..abdd52b6bb 100644 --- a/packages/strapi-plugin-content-type-builder/admin/src/containers/DataManagerProvider/index.js +++ b/packages/strapi-plugin-content-type-builder/admin/src/containers/DataManagerProvider/index.js @@ -18,7 +18,6 @@ const DataManagerProvider = ({ children }) => { isLoading, initialData, modifiedData, - newSchema, } = reducerState.toJS(); const contentTypeMatch = useRouteMatch( @@ -90,7 +89,6 @@ const DataManagerProvider = ({ children }) => { createSchema, initialData, modifiedData, - newSchema, setModifiedData, }} > diff --git a/packages/strapi-plugin-content-type-builder/admin/src/containers/DataManagerProvider/reducer.js b/packages/strapi-plugin-content-type-builder/admin/src/containers/DataManagerProvider/reducer.js index a7b295bb86..bf40801d53 100644 --- a/packages/strapi-plugin-content-type-builder/admin/src/containers/DataManagerProvider/reducer.js +++ b/packages/strapi-plugin-content-type-builder/admin/src/containers/DataManagerProvider/reducer.js @@ -6,16 +6,6 @@ const initialState = fromJS({ initialData: {}, modifiedData: {}, isLoading: true, - newSchema: { - schemaType: '', - schema: {}, - uid: '', - }, - newSchemaClone: { - schemaType: '', - schema: {}, - uid: '', - }, }); const reducer = (state, action) => { @@ -25,12 +15,21 @@ const reducer = (state, action) => { .update('components', () => fromJS(action.components)) .update('contentTypes', () => fromJS(action.contentTypes)) .update('isLoading', () => false); - case 'CREATE_SCHEMA': - console.log({ action }); - return state - .updateIn(['newSchema', 'schema'], () => fromJS(action.data)) - .updateIn(['newSchema', 'uid'], () => fromJS(action.uid)) - .updateIn(['newSchema', 'schemaType'], () => fromJS(action.schemaType)); + case 'CREATE_SCHEMA': { + const newSchema = { + uid: action.uid, + isTemporary: true, + schema: { + ...action.data, + attributes: {}, + }, + }; + const key = + action.schemaType === 'contentType' ? 'contentTypes' : 'components'; + + return state.updateIn([key, action.uid], () => fromJS(newSchema)); + } + case 'SET_MODIFIED_DATA': return state .update('initialData', () => OrderedMap(action.schemaToSet)) diff --git a/packages/strapi-plugin-content-type-builder/admin/src/containers/FormModal/index.js b/packages/strapi-plugin-content-type-builder/admin/src/containers/FormModal/index.js index 2df0eb8ae8..d7df58b66f 100644 --- a/packages/strapi-plugin-content-type-builder/admin/src/containers/FormModal/index.js +++ b/packages/strapi-plugin-content-type-builder/admin/src/containers/FormModal/index.js @@ -1,4 +1,4 @@ -import React, { useEffect, useReducer, useState } from 'react'; +import React, { useEffect, useReducer, useRef, useState } from 'react'; // import PropTypes from 'prop-types'; import { ButtonModal, @@ -18,15 +18,17 @@ import { get, isEmpty, upperFirst } from 'lodash'; import pluginId from '../../pluginId'; import useQuery from '../../hooks/useQuery'; import useDataManager from '../../hooks/useDataManager'; +import AttributeOption from '../../components/AttributeOption'; import ModalHeader from '../../components/ModalHeader'; import HeaderModalNavContainer from '../../components/HeaderModalNavContainer'; import HeaderNavLink from '../../components/HeaderNavLink'; +import getTrad from '../../utils/getTrad'; +import getAttributes from './utils/attributes'; import forms from './utils/forms'; import { createUid } from './utils/createUid'; import init from './init'; import reducer, { initialState } from './reducer'; -const getTrad = id => `${pluginId}.${id}`; const NAVLINKS = [{ id: 'base' }, { id: 'advanced' }]; const FormModal = () => { @@ -34,40 +36,77 @@ const FormModal = () => { actionType: null, modalType: null, settingType: null, - // uid: null, + for: null, + target: null, + attributeType: null, }; const [state, setState] = useState(initialStateData); const [reducerState, dispatch] = useReducer(reducer, initialState, init); const { push } = useHistory(); const { search } = useLocation(); const { formatMessage } = useGlobalContext(); - const isOpen = !isEmpty(search); const query = useQuery(); + const attributeOptionRef = useRef(); + const { contentTypes, createSchema, initialData } = useDataManager(); const { formErrors, modifiedData } = reducerState.toJS(); useEffect(() => { - if (isOpen) { + if (!isEmpty(search)) { setState({ actionType: query.get('actionType'), modalType: query.get('modalType'), settingType: query.get('settingType'), - // uid: query.get('uid'), + for: query.get('for'), + target: query.get('target'), + attributeType: query.get('attributeType'), }); } // eslint-disable-next-line react-hooks/exhaustive-deps - }, [isOpen]); + }, [search]); + + const displayedAttributes = getAttributes(state.for); + + const form = get(forms, [state.modalType, 'form', state.settingType], () => ({ + items: [], + })); + const iconType = ['components', 'contentType'].includes(state.modalType) + ? state.modalType + : state.for; + const isCreatingCT = state.modalType === 'contentType'; const isCreating = state.actionType === 'create'; - const headerId = isCreating + const isOpen = !isEmpty(search); + const isPickingAttribute = state.modalType === 'chooseAttribute'; + const name = get(initialData, ['schema', 'name'], ''); + const uid = createUid(modifiedData.name || ''); + + let headerId = isCreating ? `modalForm.${state.modalType}.header-create` : 'modalForm.header-edit'; - const name = get(initialData, ['schema', 'name'], ''); + + if (!['contentType', 'component'].includes(state.modalType)) { + headerId = null; + } + + const modalBodyStyle = isPickingAttribute + ? { paddingTop: '0.5rem', paddingBottom: '3rem' } + : {}; + + const getModalTitleSubHeader = () => { + switch (state.modalType) { + case 'chooseAttribute': + return getTrad(`modalForm.sub-header.chooseAttribute.${state.for}`); + default: + return getTrad('configurations'); + } + }; + const getNextSearch = nextTab => { - const newSearch = Object.keys(state).reduce((acc, current) => { + const newSearch = Object.keys(state).reduce((acc, current, index) => { if (current !== 'settingType') { - acc = `${acc}&${current}=${state[current]}`; + acc = `${acc}${index === 0 ? '' : '&'}${current}=${state[current]}`; } else { - acc = `${acc}&${current}=${nextTab}`; + acc = `${acc}${index === 0 ? '' : '&'}${current}=${nextTab}`; } return acc; @@ -87,16 +126,21 @@ const FormModal = () => { e.preventDefault(); try { - const schema = forms.contentType.schema(Object.keys(contentTypes)); + const schema = forms[state.modalType].schema(Object.keys(contentTypes)); await schema.validate(modifiedData, { abortEarly: false }); - createSchema(modifiedData, state.modalType, createUid(modifiedData.name)); - handleToggle(); - // push({ p}) + + createSchema(modifiedData, state.modalType, uid); + const nextSlug = isCreatingCT ? 'content-types' : 'component-categories'; + push({ + pathname: `/plugins/${pluginId}/${nextSlug}/${uid}`, + search: `modalType=chooseAttribute&for=${state.modalType}&target=${modifiedData.name}`, + }); + dispatch({ + type: 'RESET_PROPS', + }); } catch (err) { const errors = getYupInnerErrors(err); - // TODO - console.log({ errors }); dispatch({ type: 'SET_ERRORS', errors, @@ -112,104 +156,161 @@ const FormModal = () => { type: 'RESET_PROPS', }); }; - const form = get(forms, [state.modalType, 'form', state.settingType], () => ({ - items: [], - })); + + const onOpened = () => { + if (state.modalType === 'chooseAttribute') { + attributeOptionRef.current.focus(); + } + }; return ( - +
- + {msg => {upperFirst(msg)}} -
- - {NAVLINKS.map((link, index) => { - return ( - { - setState(prev => ({ ...prev, settingType: link.id })); - push({ search: getNextSearch(link.id) }); - }} - nextTab={index === NAVLINKS.length - 1 ? 0 : index + 1} - /> - ); - })} - -
-
+ {!isPickingAttribute && ( + <> +
+ + {NAVLINKS.map((link, index) => { + return ( + { + setState(prev => ({ + ...prev, + settingType: link.id, + })); + push({ search: getNextSearch(link.id) }); + }} + nextTab={ + index === NAVLINKS.length - 1 ? 0 : index + 1 + } + /> + ); + })} + +
+
+ + )}
- +
- {form(modifiedData).items.map((row, index) => { - return ( -
- {row.map(input => { - const errorId = get( - formErrors, - [...input.name.split('.'), 'id'], - null - ); - - return ( -
- {}} - description={ - get(input, 'description.id', null) - ? formatMessage(input.description) - : input.description - } - label={ - get(input, 'label.id', null) - ? formatMessage(input.label) - : input.label - } + {isPickingAttribute + ? displayedAttributes.map((row, i) => { + return ( +
+ {i === 1 && ( +
+ )} + {row.map((attr, index) => { + const tabIndex = + i === 0 + ? index + : displayedAttributes[0].length + index; + + return ( + {}} + ref={ + i === 0 && index === 0 + ? attributeOptionRef + : null + } + type={attr} + /> + ); + })} +
+ ); + }) + : form(modifiedData, state.attributeType).items.map( + (row, index) => { + return ( +
+ {row.map(input => { + const errorId = get( + formErrors, + [...input.name.split('.'), 'id'], + null + ); + + return ( +
+ {}} + description={ + get(input, 'description.id', null) + ? formatMessage(input.description) + : input.description + } + label={ + get(input, 'label.id', null) + ? formatMessage(input.label) + : input.label + } + /> +
+ ); + })}
); - })} -
- ); - })} + } + )}
- -
- - -
-
+ {!isPickingAttribute && ( + +
+ + +
+
+ )} ); diff --git a/packages/strapi-plugin-content-type-builder/admin/src/containers/FormModal/utils/attributes.js b/packages/strapi-plugin-content-type-builder/admin/src/containers/FormModal/utils/attributes.js new file mode 100644 index 0000000000..d2b2236236 --- /dev/null +++ b/packages/strapi-plugin-content-type-builder/admin/src/containers/FormModal/utils/attributes.js @@ -0,0 +1,23 @@ +const getAttributes = () => { + const defaultAttributes = [ + [ + 'text', + 'email', + 'richtext', + 'password', + 'number', + 'enumeration', + 'date', + 'media', + 'boolean', + 'json', + // 'uid', + 'relation', + ], + ['component', 'dynamiczone'], + ]; + + return defaultAttributes; +}; + +export default getAttributes; diff --git a/packages/strapi-plugin-content-type-builder/admin/src/containers/FormModal/utils/forms.js b/packages/strapi-plugin-content-type-builder/admin/src/containers/FormModal/utils/forms.js index a0b98ffa58..3a200a42fd 100644 --- a/packages/strapi-plugin-content-type-builder/admin/src/containers/FormModal/utils/forms.js +++ b/packages/strapi-plugin-content-type-builder/admin/src/containers/FormModal/utils/forms.js @@ -1,6 +1,7 @@ import * as yup from 'yup'; import { translatedErrors as errorsTrads } from 'strapi-helper-plugin'; import pluginId from '../../../pluginId'; +import getTrad from '../../../utils/getTrad'; import { createUid, nameToSlug } from './createUid'; yup.addMethod(yup.mixed, 'defined', function() { @@ -22,6 +23,57 @@ yup.addMethod(yup.string, 'unique', function(message, allReadyTakenValues) { }); const forms = { + attribute: { + schema() { + return yup.object(); + }, + form: { + advanced() { + return { + items: [[]], + }; + }, + base(data, type) { + const items = [ + [ + { + autoFocus: true, + name: 'name', + type: 'text', + label: { + id: getTrad('modalForm.attribute.form.base.name'), + }, + description: { + id: getTrad('modalForm.attribute.form.base.name.description'), + }, + validations: { + required: true, + }, + }, + ], + ]; + + if (type === 'text') { + items[0].push({ + label: { + id: 'content-type-builder.form.attribute.item.number.type', + }, + name: 'type', + type: 'select', + value: 'short text', + options: ['short text', 'long text'], + validations: { + required: true, + }, + }); + } + + return { + items, + }; + }, + }, + }, contentType: { schema(allReadyTakenValues) { return yup.object().shape({ diff --git a/packages/strapi-plugin-content-type-builder/admin/src/containers/LeftMenu/index.js b/packages/strapi-plugin-content-type-builder/admin/src/containers/LeftMenu/index.js index e2c7bf521c..c2e0e40c35 100644 --- a/packages/strapi-plugin-content-type-builder/admin/src/containers/LeftMenu/index.js +++ b/packages/strapi-plugin-content-type-builder/admin/src/containers/LeftMenu/index.js @@ -13,14 +13,19 @@ import CustomLink from '../../components/CustomLink'; import useDataManager from '../../hooks/useDataManager'; import Wrapper from './Wrapper'; -// const displayNotificationCTNotSaved = () => { -// strapi.notification.info( -// `${pluginId}.notification.info.contentType.creating.notSaved` -// ); -// }; +const displayNotificationCTNotSaved = () => { + strapi.notification.info( + `${pluginId}.notification.info.contentType.creating.notSaved` + ); +}; function LeftMenu() { - const { components, contentTypes, newSchema } = useDataManager(); + const { + components, + contentTypes, + // initialData, + // modifiedData, + } = useDataManager(); const { currentEnvironment } = useGlobalContext(); const { push } = useHistory(); const isProduction = currentEnvironment === 'production'; @@ -40,14 +45,24 @@ function LeftMenu() { })), obj => obj.title ); - const tempSchemaCT = - newSchema.schemaType === 'contentType' - ? { - name: newSchema.uid, - title: newSchema.schema.name, - to: `/plugins/${pluginId}/content-types/${newSchema.uid}`, - } - : null; + const canOpenModalCreateCTorComponent = () => { + return ( + !Object.keys(contentTypes).some( + ct => contentTypes[ct].isTemporary === true + ) && + !Object.keys(components).some( + component => components[component].isTemporary === true + ) + ); + }; + const handleClickOpenModal = type => { + if (canOpenModalCreateCTorComponent()) { + push({ search: `modalType=${type}&actionType=create&settingType=base` }); + } else { + displayNotificationCTNotSaved(); + } + }; + const data = [ { name: 'models', @@ -61,10 +76,7 @@ function LeftMenu() { disabled: isProduction, id: `${pluginId}.button.model.create`, onClick: () => { - push({ - search: - 'modalType=contentType&actionType=create&settingType=base', - }); + handleClickOpenModal('contentType'); }, }, }, @@ -75,7 +87,6 @@ function LeftMenu() { title: contentTypes[uid].schema.name, to: `/plugins/${pluginId}/content-types/${uid}`, })) - .concat(tempSchemaCT) .filter(obj => obj !== null), obj => obj.title ), @@ -92,9 +103,7 @@ function LeftMenu() { disabled: isProduction, id: `${pluginId}.button.component.create`, onClick: () => { - push({ - search: 'modalType=component&actionType=create&settingType=base', - }); + handleClickOpenModal('component'); }, }, }, diff --git a/packages/strapi-plugin-content-type-builder/admin/src/translations/en.json b/packages/strapi-plugin-content-type-builder/admin/src/translations/en.json index 12fa852971..fb13913fd7 100644 --- a/packages/strapi-plugin-content-type-builder/admin/src/translations/en.json +++ b/packages/strapi-plugin-content-type-builder/admin/src/translations/en.json @@ -2,23 +2,7 @@ "model": "Content Type", "group": "Group", "attribute.WYSIWYG": "Text (WYSIWYG)", - "attribute.boolean": "Boolean", - "attribute.date": "Date", - "attribute.decimal": "Decimal", - "attribute.email": "Email", - "attribute.enumeration": "Enumeration", - "attribute.float": "Float", - "attribute.group": "Group", - "attribute.integer": "Integer", - "attribute.biginteger": "Big Integer", - "attribute.json": "JSON", - "attribute.media": "Media", - "attribute.password": "Password", - "attribute.relation": "Relation", - "attribute.richtext": "Rich text", - "attribute.string": "String", - "attribute.text": "Text", - "attribute.uuid": "Uuid", + "button.attributes.add": "Add New Field", "button.attributes.add.another": "Add Another Field", "button.contentType.add": "Add a Content Type", @@ -146,34 +130,7 @@ "notification.success.message.contentType.edit": "Your Content Type has been updated", "plugin.description.long": "Modelize the data structure of your API. Create new fields and relations in just a minute. The files are automatically created and updated in your project.", "plugin.description.short": "Modelize the data structure of your API.", - "popUpForm.attributes.boolean.description": "Yes or no, 1 or 0, true or false", - "popUpForm.attributes.boolean.name": "Boolean", - "popUpForm.attributes.date.description": "Event date, opening hours", - "popUpForm.attributes.date.name": "Date", - "popUpForm.attributes.email.description": "User's email...", - "popUpForm.attributes.email.name": "Email", - "popUpForm.attributes.enumeration.description": "List of choices", - "popUpForm.attributes.enumeration.name": "Enumeration", - "popUpForm.attributes.group.description": "Refers to a Group", - "popUpForm.attributes.group.name": "Group", - "popUpForm.attributes.json.description": "Data in JSON format", - "popUpForm.attributes.json.name": "JSON", - "popUpForm.attributes.media.description": "Images, videos, PDFs and other files", - "popUpForm.attributes.media.name": "Media", - "popUpForm.attributes.number.description": "Everything that is number", - "popUpForm.attributes.number.name": "Number", - "popUpForm.attributes.password.description": "User password...", - "popUpForm.attributes.password.name": "Password", - "popUpForm.attributes.relation.description": "Refers to a Content Type", - "popUpForm.attributes.relation.name": "Relation", - "popUpForm.attributes.richtext.description": "Formatting and creating text", - "popUpForm.attributes.richtext.name": "Rich text", - "popUpForm.attributes.string.description": "Titles, names, paragraphs, list of names", - "popUpForm.attributes.string.name": "String", - "popUpForm.attributes.text.description": "Descriptions, text paragraphs, articles", - "popUpForm.attributes.text.name": "Text", - "popUpForm.attributes.uuid.description": "Unique identifier", - "popUpForm.attributes.uuid.name": "Uuid", + "popUpForm.choose.attributes.header.title": "Add New Field", "popUpForm.choose.attributes.header.subtitle.model": "Select a field for your content type", "popUpForm.choose.attributes.header.subtitle.group": "Select a field for your group", @@ -221,13 +178,45 @@ "table.relations.title.singular": "including {number} relationship", "prompt.content.unsaved": "Are you sure you want to leave this content type? All your modifications will be lost.", - "modalForm.contentType.header-create": "Create a content type", - "modalForm.header-edit": "Edit {name}", - "modalForm.component.header-create": "Create a component", + "attribute.boolean": "Boolean", + "attribute.boolean.description": "Yes or no, 1 or 0, true or false", + "attribute.component": "Component", + "attribute.component.description": "Set of fields that you can repeat or reuse", + "attribute.date": "Date", + "attribute.date.description": "Event date, opening hours", + "attribute.dynamiczone": "Dynamic zone", + "attribute.dynamiczone.description": "Dynamically pick component when editing content", + "attribute.email": "Email", + "attribute.email.description": "User's email...", + "attribute.enumeration": "Enumeration", + "attribute.enumeration.description": "List of choices", + "attribute.json": "JSON", + "attribute.json.description": "Data in JSON format", + "attribute.media": "Media", + "attribute.media.description": "Images, videos, PDFs and other files", + "attribute.number": "Number", + "attribute.number.description": "Everything that is number", + "attribute.password": "Password", + "attribute.password.description": "User password...", + "attribute.relation": "Relation", + "attribute.relation.description": "Refers to a Content Type", + "attribute.richtext": "Rich text", + "attribute.richtext.description": "Formatting and creating text", + "attribute.text": "Text", + "attribute.text.description": "Small or long text like title or description", + "attribute.uid": "Uuid", + "attribute.uid.description": "Unique identifier", "configurations": "configurations", "contentType.displayName.label": "Display name", "contentType.collectionName.description": "Useful when the name of your Content Type and your table name differ", "contentType.collectionName.label": "Collection name", - "contentType.UID.description": "The UID is used to generate the API routes and databases tables/collections" + "contentType.UID.description": "The UID is used to generate the API routes and databases tables/collections", + "modalForm.component.header-create": "Create a component", + "modalForm.contentType.header-create": "Create a content type", + "modalForm.attribute.form.base.name": "Name", + "modalForm.attribute.form.base.name.description": "No space is allowed for the name of the attribute", + "modalForm.header-edit": "Edit {name}", + "modalForm.sub-header.chooseAttribute.component": "Select a field for your component", + "modalForm.sub-header.chooseAttribute.contentType": "Select a field for your content type" } diff --git a/packages/strapi-plugin-content-type-builder/admin/src/utils/getTrad.js b/packages/strapi-plugin-content-type-builder/admin/src/utils/getTrad.js new file mode 100644 index 0000000000..a2b8632a8d --- /dev/null +++ b/packages/strapi-plugin-content-type-builder/admin/src/utils/getTrad.js @@ -0,0 +1,5 @@ +import pluginId from '../pluginId'; + +const getTrad = id => `${pluginId}.${id}`; + +export default getTrad;