From b5192d9b616a24b6ad828e414cc18aee47303826 Mon Sep 17 00:00:00 2001 From: cyril lopez Date: Fri, 23 Feb 2018 16:49:50 +0100 Subject: [PATCH 1/5] Add media type to ctb Prevent error if enumeration type is displayed Add tab navigation to popup choose attr --- .../src/components/AttributeCard/index.js | 20 ++++++-- .../src/components/AttributeCard/styles.scss | 49 +++++++++---------- .../src/components/AttributeRow/index.js | 4 +- .../admin/src/containers/Form/forms.json | 15 ++++++ .../admin/src/containers/Form/index.js | 2 + .../admin/src/containers/ModelPage/index.js | 4 ++ .../admin/src/translations/de.json | 44 +++++++++-------- .../admin/src/translations/en.json | 3 ++ .../admin/src/translations/fr.json | 3 ++ .../admin/src/translations/pl.json | 3 ++ .../admin/src/translations/tr.json | 3 ++ .../models/User.settings.json | 4 ++ 12 files changed, 104 insertions(+), 50 deletions(-) diff --git a/packages/strapi-plugin-content-type-builder/admin/src/components/AttributeCard/index.js b/packages/strapi-plugin-content-type-builder/admin/src/components/AttributeCard/index.js index c5358fc51b..66f0475bfc 100644 --- a/packages/strapi-plugin-content-type-builder/admin/src/components/AttributeCard/index.js +++ b/packages/strapi-plugin-content-type-builder/admin/src/components/AttributeCard/index.js @@ -22,6 +22,7 @@ import IcoText from '../../assets/images/icon_text.png'; import styles from './styles.scss'; /* eslint-disable jsx-a11y/no-static-element-interactions */ +/* eslint-disable jsx-a11y/no-autofocus */ const asset = { 'boolean': IcoBoolean, 'date': IcoDate, @@ -35,10 +36,16 @@ const asset = { 'text': IcoText, }; -function AttributeCard({ attribute, handleClick }) { +function AttributeCard({ attribute, autoFocus, handleClick, tabIndex }) { return (
-
handleClick(attribute.type)}> +
+
); } +AttributeCard.defaultProps = { + autoFocus: false, + tabIndex: 0, +}; + AttributeCard.propTypes = { attribute: PropTypes.object.isRequired, + autoFocus: PropTypes.bool, handleClick: PropTypes.func.isRequired, + tabIndex: PropTypes.number, }; export default AttributeCard; diff --git a/packages/strapi-plugin-content-type-builder/admin/src/components/AttributeCard/styles.scss b/packages/strapi-plugin-content-type-builder/admin/src/components/AttributeCard/styles.scss index 138505493e..1daff2b561 100644 --- a/packages/strapi-plugin-content-type-builder/admin/src/components/AttributeCard/styles.scss +++ b/packages/strapi-plugin-content-type-builder/admin/src/components/AttributeCard/styles.scss @@ -1,22 +1,22 @@ .attributeCardContainer { /* stylelint-disable */ - cursor: pointer; display: flex; - justify-content: space-between; - align-items: center; + width: 100% !important; height: 4rem; + padding: 0 1rem 0 1rem; margin-top: .6rem; margin-bottom: .8rem; - padding: 0 1rem 0 1rem; - border: 1px solid #E3E9F3; + align-items: center; + justify-content: space-between; border-radius: 0.25rem; - line-height: 4rem; + border: 1px solid #E3E9F3; background: #FFFFFF; + line-height: 4rem; box-shadow: 1px 1px 1px rgba(104, 118,145, 0.05); - - &:hover, &:active { + cursor: pointer; + &:hover, &:active, &:focus { background: #F7F7F7; - - > div:after{ + outline: 0; + > div:after { color: #0097F6; } } @@ -24,25 +24,24 @@ .attributeCard { font-size: 1.3rem; + &: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; } - - &:after{ - position: absolute; - top: 7px; right: 26px; - content: '\f05d'; - font-size: 1.4rem; - font-family: 'FontAwesome'; - color: #E3E9F3; - -webkit-font-smoothing: antialiased; - } - > img{ display: inline-block; - width: 35px; height: 20px; + width: 35px; margin-top: -3px; margin-right: 10px; } @@ -57,11 +56,11 @@ } .attributeType { - color: #323740 !important; margin-right: 1.2rem; - font-style: normal !important; + color: #323740 !important; + text-transform: capitalize; font-size: 1.3rem !important; font-weight: 500 !important; - text-transform: capitalize; + font-style: normal !important; -webkit-font-smoothing: subpixel-antialiased !important; } diff --git a/packages/strapi-plugin-content-type-builder/admin/src/components/AttributeRow/index.js b/packages/strapi-plugin-content-type-builder/admin/src/components/AttributeRow/index.js index 56862839cd..5e4a58ad12 100644 --- a/packages/strapi-plugin-content-type-builder/admin/src/components/AttributeRow/index.js +++ b/packages/strapi-plugin-content-type-builder/admin/src/components/AttributeRow/index.js @@ -42,6 +42,8 @@ class AttributeRow extends React.Component { // eslint-disable-line react/prefer 'decimal': IcoNumber, 'email': IcoEmail, 'password': IcoPassword, + // TODO add Enumeration icon + 'enumeration': IcoJson, }; this.state = { showWarning: false, @@ -90,7 +92,7 @@ class AttributeRow extends React.Component { // eslint-disable-line react/prefer const relationStyle = !this.props.row.params.type ? styles.relation : ''; const icons = isNotEditable ? [{ icoType: 'lock' }] : [{ icoType: 'pencil', onClick: this.handleEdit }, { icoType: 'trash', onClick: () => this.setState({ showWarning: !this.state.showWarning }) }]; const editableStyle = isNotEditable ? '' : styles.editable; - + return (
  • )) ) diff --git a/packages/strapi-plugin-content-type-builder/admin/src/containers/ModelPage/index.js b/packages/strapi-plugin-content-type-builder/admin/src/containers/ModelPage/index.js index ae493b014c..94bac49bd7 100644 --- a/packages/strapi-plugin-content-type-builder/admin/src/containers/ModelPage/index.js +++ b/packages/strapi-plugin-content-type-builder/admin/src/containers/ModelPage/index.js @@ -173,6 +173,10 @@ export class ModelPage extends React.Component { // eslint-disable-line react/pr handleEditAttribute = (attributeName) => { const index = findIndex(this.props.modelPage.model.attributes, ['name', attributeName]); const attribute = this.props.modelPage.model.attributes[index]; + + if (attribute.params.type === 'enumeration') { + return strapi.notification.info('content-type-builder.notification.info.enumeration'); + } const settingsType = attribute.params.type ? 'baseSettings' : 'defineRelation'; const parallelAttributeIndex = findIndex(this.props.modelPage.model.attributes, ['name', attribute.params.key]); const hasParallelAttribute = settingsType === 'defineRelation' && parallelAttributeIndex !== -1 ? `::${parallelAttributeIndex}` : ''; diff --git a/packages/strapi-plugin-content-type-builder/admin/src/translations/de.json b/packages/strapi-plugin-content-type-builder/admin/src/translations/de.json index f0eeeb2a0d..ffba9dbe35 100644 --- a/packages/strapi-plugin-content-type-builder/admin/src/translations/de.json +++ b/packages/strapi-plugin-content-type-builder/admin/src/translations/de.json @@ -13,21 +13,22 @@ "attribute.email": "E-Mail", "attribute.password": "Passwort", "attribute.relation": "Beziehung", - + "attribute.enumeration": "Enumeration", + "contentType.temporaryDisplay": "(Nicht gespeichert)", "from": "aus", "home.contentTypeBuilder.name": "Content-Typen", "home.contentTypeBuilder.description": "Verwalte deine Content-Typen.", "home.emptyContentType.title": "Es sind keine Content-Typen verfügbar", "home.emptyContentType.description": "Lege deinen ersten Content-Typ an, Daten deiner API abrufen zu können.", - + "home.emptyAttributes.title": "Es gibt noch keine Felder", "home.emptyAttributes.description": "Füge deinem Content-Typen das erste Feld hinzu", - + "button.contentType.create": "Lege einen Content-Typ an", "button.contentType.add": "Neuer Content-Typ", "button.attributes.add": "Neues Feld", - + "error.validation.required": "Dieser Wert ist erforderlich.", "error.validation.regex": "Dieser Wert entspricht nicht dem RegEx.", "error.validation.max": "Dieser Wert ist zu hoch.", @@ -39,11 +40,12 @@ "error.attribute.key.taken": "Dieser Wert existiert bereits", "error.attribute.sameKeyAndName": "Darf nicht gleich sein", "error.validation.minSupMax": "Darf nicht höher sein", - + "form.attribute.item.textarea.name": "Name", "form.attribute.item.number.name": "Name", "form.attribute.item.date.name": "Name", "form.attribute.item.media.name": "Name", + "form.attribute.item.media.multiple": "Allow multiple files", "form.attribute.item.json.name": "Name", "form.attribute.item.boolean.name": "Name", "form.attribute.item.string.name": "Name", @@ -63,11 +65,11 @@ "form.attribute.item.number.type.integer": "integer (ex: 10)", "form.attribute.item.number.type.float": "float (ex: 3.33333333)", "form.attribute.item.number.type.decimal": "decimal (ex: 2.22)", - + "form.button.cancel": "Abbrechen", "form.button.continue": "Weiter", "form.button.save": "Speichern", - + "form.contentType.item.connections": "Verbindung", "form.contentType.item.name": "Name", "form.contentType.item.name.description": "Der Name des Content-Typs sollte Singular sein. {link}", @@ -76,7 +78,7 @@ "form.contentType.item.description.placeholder": "Beschreibe deinen Content-Typ", "form.contentType.item.collectionName": "Name des Dokuments in der Datenbank", "form.contentType.item.collectionName.inputDescription": "Nützlich, wenn Content-Typ und Datenbankname unterschiedlich sind", - + "menu.section.contentTypeBuilder.name.plural": "Content-Typen", "menu.section.contentTypeBuilder.name.singular": "Content-Typ", "menu.section.documentation.name": "Dokumentation", @@ -84,7 +86,7 @@ "menu.section.documentation.guideLink": "Anleitung.", "menu.section.documentation.tutorial": "Schau dir unser", "menu.section.documentation.tutorialLink": "Tutorial an.", - + "modelPage.contentHeader.emptyDescription.description": "Dieser Content-Typ hat keine Beschreibung", "modelPage.contentType.list.title.plural": "Felder", "modelPage.contentType.list.title.singular": "Feld", @@ -92,17 +94,18 @@ "modelPage.contentType.list.relationShipTitle.plural": "Beziehungen", "modelPage.contentType.list.relationShipTitle.singular": "Beziehung", "modelPage.attribute.relationWith": "Beziehung mit", - + "noTableWarning.description": "Vergiss nicht, die Tabelle `{modelName}` in deiner Datenbank zu erstellen", "noTableWarning.infos": "Mehr Informationen", - + "notification.error.message": "Ein Fehler ist aufgetreten", "notification.info.contentType.creating.notSaved": "Bitte speichere zuerst diesen Content-Typ bevor du einen neuen anlegst", "notification.info.optimized": "Dieses Plugin ist auf deinen localStorage optimiert", "notification.success.message.contentType.edit": "Der Content-Typ wurde aktualisiert", "notification.success.message.contentType.create": "Der Content-Typ wurde angelegt", "notification.success.contentTypeDeleted": "Der Content-Typ wurde gelöscht", - + "notification.info.enumeration": "This field is not editable for the moment...😮", + "popUpForm.attributes.string.description": "Titel, Namen, Namenslisten", "popUpForm.attributes.text.description": "Beschreibungen, Paragraphen, Artikel", "popUpForm.attributes.boolean.description": "Ja/Nein, 1 oder 0, Wahr/Falsch", @@ -113,7 +116,7 @@ "popUpForm.attributes.relation.description": "Bezieht sich auf einen Content-Typ", "popUpForm.attributes.email.description": "E-Mail-Adressen von Benutzern", "popUpForm.attributes.password.description": "Passwörter von Benutzers", - + "popUpForm.attributes.string.name": "String", "popUpForm.attributes.text.name": "Text", "popUpForm.attributes.boolean.name": "Boolean", @@ -130,31 +133,30 @@ "popUpForm.create.contentType.header.title": "Neuer Content-Typ", "popUpForm.choose.attributes.header.title": "Neues Feld hinzufügen", "popUpForm.edit.contentType.header.title": "Content-Typen bearbeiten", - + "popUpForm.navContainer.relation": "Beziehung definieren", "popUpForm.navContainer.base": "Grundeinstellungen", "popUpForm.navContainer.advanced": "Fortgeschrittene Einstellungen", - + "popUpRelation.title": "Beziehung", - + "popUpWarning.button.cancel": "Abbrechen", "popUpWarning.button.confirm": "Bestätigen", "popUpWarning.title": "Bitte bestätigen", "popUpWarning.bodyMessage.contentType.delete": "Bist du sicher, dass du diesen Content-Typ löschen willst?", "popUpWarning.bodyMessage.attribute.delete": "Bist du sicher, dass du dieses Feld löschen willst?", - - + + "table.contentType.title.plural": "Content-Typen sind verfügbar", "table.contentType.title.singular": "Content-Typ ist verfügbar", "table.contentType.head.name": "Name", "table.contentType.head.description": "Beschreibung", "table.contentType.head.fields": "Felder", - + "relation.oneToOne": "hat ein(en)", "relation.oneToMany": "gehört zu vielen", "relation.manyToOne": "hat viele", "relation.manyToMany": "hat und gehört zu vielen", "relation.attributeName.placeholder": "z.B.: Autor, Kategorie" - + } - \ No newline at end of file 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 25dc625be5..730451e48e 100755 --- a/packages/strapi-plugin-content-type-builder/admin/src/translations/en.json +++ b/packages/strapi-plugin-content-type-builder/admin/src/translations/en.json @@ -13,6 +13,7 @@ "attribute.email": "Email", "attribute.password": "Password", "attribute.relation": "Relation", + "attribute.enumeration": "Enumeration", "contentType.temporaryDisplay": "(Not saved)", "from": "from", @@ -44,6 +45,7 @@ "form.attribute.item.number.name": "Name", "form.attribute.item.date.name": "Name", "form.attribute.item.media.name": "Name", + "form.attribute.item.media.multiple": "Allow multiple files", "form.attribute.item.json.name": "Name", "form.attribute.item.boolean.name": "Name", "form.attribute.item.string.name": "Name", @@ -102,6 +104,7 @@ "notification.success.message.contentType.edit": "Your Content Type has been updated", "notification.success.message.contentType.create": "Your Content Type has been created", "notification.success.contentTypeDeleted": "The Content Type has been deleted", + "notification.info.enumeration": "This field is not editable for the moment...😮", "popUpForm.attributes.string.description": "Titles, names, paragraphs, list of names", "popUpForm.attributes.text.description": "Descriptions, text paragraphs, articles ", diff --git a/packages/strapi-plugin-content-type-builder/admin/src/translations/fr.json b/packages/strapi-plugin-content-type-builder/admin/src/translations/fr.json index 24e7e9fa56..dc3a5f48eb 100755 --- a/packages/strapi-plugin-content-type-builder/admin/src/translations/fr.json +++ b/packages/strapi-plugin-content-type-builder/admin/src/translations/fr.json @@ -13,6 +13,7 @@ "attribute.password": "Mot de passe", "attribute.email": "Email", "attribute.relation": "Relation", + "attribute.enumeration": "Enumération", "contentType.temporaryDisplay": "(Non sauvegardé)", @@ -48,6 +49,7 @@ "form.attribute.item.number.name": "Nom", "form.attribute.item.json.name": "Nom", "form.attribute.item.media.name": "Nom", + "form.attribute.item.media.multiple": "Peut avoir plusierus fichiers", "form.attribute.item.string.name": "Nom", "form.attribute.item.settings.name": "Paramètres", "form.attribute.item.requiredField": "Champ obligatoire", @@ -105,6 +107,7 @@ "notification.success.message.contentType.edit": "Votre modèle a bien été modifié", "notification.success.message.contentType.create": "Votre modèle a bien été créée", "notification.success.contentTypeDeleted": "Le modèle a bien été supprimé.", + "notification.info.enumeration": "Ce champ n'est pas modifiable pour le moment...😮", "popUpForm.attributes.string.description": "Titres, noms,...", "popUpForm.attributes.text.description": "Descriptions, paragraphes texte, articles ", diff --git a/packages/strapi-plugin-content-type-builder/admin/src/translations/pl.json b/packages/strapi-plugin-content-type-builder/admin/src/translations/pl.json index fe367e9ca5..e01ae6636d 100644 --- a/packages/strapi-plugin-content-type-builder/admin/src/translations/pl.json +++ b/packages/strapi-plugin-content-type-builder/admin/src/translations/pl.json @@ -13,6 +13,7 @@ "attribute.email": "Email", "attribute.password": "Hasło", "attribute.relation": "Relacja", + "attribute.enumeration": "Enumeration", "contentType.temporaryDisplay": "(Nie zapisany)", "from": "z", @@ -44,6 +45,7 @@ "form.attribute.item.number.name": "Nazwa", "form.attribute.item.date.name": "Nazwa", "form.attribute.item.media.name": "Nazwa", + "form.attribute.item.media.multiple": "Allow multiple files", "form.attribute.item.json.name": "Nazwa", "form.attribute.item.boolean.name": "Nazwa", "form.attribute.item.string.name": "Nazwa", @@ -102,6 +104,7 @@ "notification.success.message.contentType.edit": "Model został zmieniony", "notification.success.message.contentType.create": "Model został utworzony", "notification.success.contentTypeDeleted": "Model został usunięty", + "notification.info.enumeration": "This field is not editable for the moment...😮", "popUpForm.attributes.string.description": "Tytuły, nazwy, paragrafy, lista nazwisk", "popUpForm.attributes.text.description": "Opisy, paragrafy, artykuły ", diff --git a/packages/strapi-plugin-content-type-builder/admin/src/translations/tr.json b/packages/strapi-plugin-content-type-builder/admin/src/translations/tr.json index a69ef06bb7..0a5e886c21 100755 --- a/packages/strapi-plugin-content-type-builder/admin/src/translations/tr.json +++ b/packages/strapi-plugin-content-type-builder/admin/src/translations/tr.json @@ -13,6 +13,7 @@ "attribute.email": "E-posta", "attribute.password": "Parola", "attribute.relation": "İlişki", + "attribute.enumeration": "Enumeration", "contentType.temporaryDisplay": "(Kaydedilmedi)", "from": "kimden", @@ -44,6 +45,7 @@ "form.attribute.item.number.name": "İsim", "form.attribute.item.date.name": "İsim", "form.attribute.item.media.name": "İsim", + "form.attribute.item.media.multiple": "Allow multiple files", "form.attribute.item.json.name": "İsim", "form.attribute.item.boolean.name": "İsim", "form.attribute.item.string.name": "İsim", @@ -102,6 +104,7 @@ "notification.success.message.contentType.edit": "İçerik Türünüz güncellendi", "notification.success.message.contentType.create": "İçerik Türünüz oluşturuldu", "notification.success.contentTypeDeleted": "İçerik Türü silindi", + "notification.info.enumeration": "This field is not editable for the moment...😮", "popUpForm.attributes.string.description": "Başlıklar, adlar, paragraflar, isim listesi", "popUpForm.attributes.text.description": "Tanımlar, metin paragrafları, makaleler ", diff --git a/packages/strapi-plugin-users-permissions/models/User.settings.json b/packages/strapi-plugin-users-permissions/models/User.settings.json index da72db76e3..873fbeee2c 100644 --- a/packages/strapi-plugin-users-permissions/models/User.settings.json +++ b/packages/strapi-plugin-users-permissions/models/User.settings.json @@ -38,6 +38,10 @@ "via": "users", "plugin": "users-permissions", "configurable": false + }, + "ttytte": { + "collection": "test", + "via": "tet" } } } \ No newline at end of file From 5972cf2d10440ca2b8d106860dc8787a134ab9d0 Mon Sep 17 00:00:00 2001 From: cyril lopez Date: Fri, 23 Feb 2018 16:58:00 +0100 Subject: [PATCH 2/5] Remove test relations --- .../models/User.settings.json | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/packages/strapi-plugin-users-permissions/models/User.settings.json b/packages/strapi-plugin-users-permissions/models/User.settings.json index 873fbeee2c..99479b1cba 100644 --- a/packages/strapi-plugin-users-permissions/models/User.settings.json +++ b/packages/strapi-plugin-users-permissions/models/User.settings.json @@ -38,10 +38,6 @@ "via": "users", "plugin": "users-permissions", "configurable": false - }, - "ttytte": { - "collection": "test", - "via": "tet" } } -} \ No newline at end of file +} From e63a1f19fc219e32cbe2feb428c606465716720f Mon Sep 17 00:00:00 2001 From: Aurelsicoko Date: Mon, 26 Feb 2018 11:12:49 +0100 Subject: [PATCH 3/5] Handle empty relationships on morph side --- packages/strapi-bookshelf/lib/index.js | 3 ++- packages/strapi-mongoose/lib/index.js | 2 ++ .../strapi-plugin-upload/models/File.settings.json | 4 ++++ .../models/User.settings.json | 10 +--------- packages/strapi-utils/lib/models.js | 5 +++-- 5 files changed, 12 insertions(+), 12 deletions(-) diff --git a/packages/strapi-bookshelf/lib/index.js b/packages/strapi-bookshelf/lib/index.js index 4731715b9f..b231d4a197 100755 --- a/packages/strapi-bookshelf/lib/index.js +++ b/packages/strapi-bookshelf/lib/index.js @@ -88,7 +88,8 @@ module.exports = function(strapi) { const loadedModel = _.assign({ tableName: definition.collectionName, hasTimestamps: _.get(definition, 'options.timestamps') === true, - idAttribute: _.get(definition, 'options.idAttribute', 'id') + idAttribute: _.get(definition, 'options.idAttribute', 'id'), + associations: [] }, definition.options); if (_.isString(_.get(connection, 'options.pivot_prefix'))) { diff --git a/packages/strapi-mongoose/lib/index.js b/packages/strapi-mongoose/lib/index.js index 4b7ccf1bf1..a95146d81d 100755 --- a/packages/strapi-mongoose/lib/index.js +++ b/packages/strapi-mongoose/lib/index.js @@ -95,6 +95,7 @@ module.exports = function (strapi) { It allows us to make Upload.find().populate('related') instead of Upload.find().populate('related.item') */ + const morphAssociations = definition.associations.filter(association => association.nature.toLowerCase().indexOf('morph') !== -1); if (morphAssociations.length > 0) { @@ -220,6 +221,7 @@ module.exports = function (strapi) { // Add some informations about ORM & client connection definition.orm = 'mongoose'; definition.client = _.get(strapi.config.connections[definition.connection], 'client'); + definition.associations = []; // Register the final model for Mongoose. definition.loadedModel = _.cloneDeep(definition.attributes); diff --git a/packages/strapi-plugin-upload/models/File.settings.json b/packages/strapi-plugin-upload/models/File.settings.json index c68086fda6..de096edcd4 100644 --- a/packages/strapi-plugin-upload/models/File.settings.json +++ b/packages/strapi-plugin-upload/models/File.settings.json @@ -34,6 +34,10 @@ "type": "string", "configurable": false, "required": true + }, + "related": { + "collection": "*", + "filter": "field" } } } diff --git a/packages/strapi-plugin-users-permissions/models/User.settings.json b/packages/strapi-plugin-users-permissions/models/User.settings.json index e18430d84d..99479b1cba 100644 --- a/packages/strapi-plugin-users-permissions/models/User.settings.json +++ b/packages/strapi-plugin-users-permissions/models/User.settings.json @@ -38,14 +38,6 @@ "via": "users", "plugin": "users-permissions", "configurable": false - }, - "avatar": { - "model": "upload", - "via": "uploaded" - }, - "photos": { - "collection": "upload", - "via": "uploaded" } } -} \ No newline at end of file +} diff --git a/packages/strapi-utils/lib/models.js b/packages/strapi-utils/lib/models.js index a073fb2596..bd53f6b9f1 100755 --- a/packages/strapi-utils/lib/models.js +++ b/packages/strapi-utils/lib/models.js @@ -230,12 +230,12 @@ module.exports = { nature: 'oneMorphToOne', verbose: 'belongsToMorph' }; - } else if (types.current === 'morphTo' && types.other === 'model') { + } else if (types.current === 'morphTo' && (types.other === 'model' || association.hasOwnProperty('model'))) { return { nature: 'manyMorphToOne', verbose: 'belongsToManyMorph' }; - } else if (types.current === 'morphTo' && types.other === 'collection') { + } else if (types.current === 'morphTo' && (types.other === 'collection' || association.hasOwnProperty('collection'))) { return { nature: 'manyMorphToMany', verbose: 'belongsToManyMorph' @@ -358,6 +358,7 @@ module.exports = { Object.keys(strapi.plugins[current].models).forEach((entity) => { Object.keys(strapi.plugins[current].models[entity].attributes).forEach((attribute) => { const attr = strapi.plugins[current].models[entity].attributes[attribute]; + if ( (attr.collection || attr.model || '').toLowerCase() === model.toLowerCase() && strapi.plugins[current].models[entity].globalId !== definition.globalId From fb549945a1c5f91d1ef5ca150be81ae29c0d0e8d Mon Sep 17 00:00:00 2001 From: Aurelsicoko Date: Mon, 26 Feb 2018 14:39:06 +0100 Subject: [PATCH 4/5] Fix oneToMany relationship --- packages/strapi-utils/lib/models.js | 34 ++++++++++++++++------------- 1 file changed, 19 insertions(+), 15 deletions(-) diff --git a/packages/strapi-utils/lib/models.js b/packages/strapi-utils/lib/models.js index bd53f6b9f1..e1a2299102 100755 --- a/packages/strapi-utils/lib/models.js +++ b/packages/strapi-utils/lib/models.js @@ -137,24 +137,28 @@ module.exports = { // We have to find if they are a model linked to this key _.forIn(_.omit(models, currentModelName || ''), model => { - _.forIn(model.attributes, attribute => { - if (attribute.hasOwnProperty('via') && attribute.via === key && attribute.hasOwnProperty('collection') && attribute.collection !== '*') { - types.other = 'collection'; + Object.keys(model.attributes) + .filter(key => key === association.via) + .forEach(attr => { + const attribute = model.attributes[attr]; - // Break loop - return false; - } else if (attribute.hasOwnProperty('model') && attribute.model !== '*') { - types.other = 'model'; + if (attribute.hasOwnProperty('via') && attribute.via === key && attribute.hasOwnProperty('collection') && attribute.collection !== '*') { + types.other = 'collection'; - // Break loop - return false; - } else if (attribute.hasOwnProperty('collection') || attribute.hasOwnProperty('model')) { - types.other = 'morphTo'; + // Break loop + return false; + } else if (attribute.hasOwnProperty('model') && attribute.model !== '*') { + types.other = 'model'; - // Break loop - return false; - } - }); + // Break loop + return false; + } else if (attribute.hasOwnProperty('collection') || attribute.hasOwnProperty('model')) { + types.other = 'morphTo'; + + // Break loop + return false; + } + }); }); } else if (association.hasOwnProperty('model')) { types.current = 'model'; From 7af7922f2bd5dfd9dd501b996e184a1af1439b3c Mon Sep 17 00:00:00 2001 From: Jim Laurie Date: Mon, 26 Feb 2018 16:33:27 +0100 Subject: [PATCH 5/5] Backend content type builder media type Co-authored-by: soupette --- .../admin/src/containers/Form/actions.js | 1 + .../admin/src/containers/Form/forms.json | 2 +- .../admin/src/containers/ModelPage/actions.js | 2 +- .../admin/src/containers/ModelPage/sagas.js | 3 +- .../services/ContentTypeBuilder.js | 29 ++++++++++++++----- .../models/File.settings.json | 3 +- .../models/User.settings.json | 6 +++- 7 files changed, 33 insertions(+), 13 deletions(-) diff --git a/packages/strapi-plugin-content-type-builder/admin/src/containers/Form/actions.js b/packages/strapi-plugin-content-type-builder/admin/src/containers/Form/actions.js index 053efc44b7..94a9991fef 100644 --- a/packages/strapi-plugin-content-type-builder/admin/src/containers/Form/actions.js +++ b/packages/strapi-plugin-content-type-builder/admin/src/containers/Form/actions.js @@ -251,6 +251,7 @@ function setAttributeFormData(hash) { unique: false, maxLength: false, minLength: false, + multiple: false, min: false, max: false, }), diff --git a/packages/strapi-plugin-content-type-builder/admin/src/containers/Form/forms.json b/packages/strapi-plugin-content-type-builder/admin/src/containers/Form/forms.json index 2928393c43..8ecf385475 100644 --- a/packages/strapi-plugin-content-type-builder/admin/src/containers/Form/forms.json +++ b/packages/strapi-plugin-content-type-builder/admin/src/containers/Form/forms.json @@ -725,7 +725,7 @@ "label": { "id": "content-type-builder.form.attribute.item.media.multiple" }, - "name": "multiple", + "name": "params.multiple", "type": "checkbox", "value": false, "validations": { diff --git a/packages/strapi-plugin-content-type-builder/admin/src/containers/ModelPage/actions.js b/packages/strapi-plugin-content-type-builder/admin/src/containers/ModelPage/actions.js index dcb476ee04..219f15d33b 100644 --- a/packages/strapi-plugin-content-type-builder/admin/src/containers/ModelPage/actions.js +++ b/packages/strapi-plugin-content-type-builder/admin/src/containers/ModelPage/actions.js @@ -120,7 +120,7 @@ export function modelFetch(modelName) { export function modelFetchSucceeded(data) { const model = data; - const defaultKeys = ['required', 'unique', 'type', 'key', 'target', 'nature', 'targetColumnName', 'columnName']; + const defaultKeys = ['required', 'unique', 'type', 'key', 'target', 'nature', 'targetColumnName', 'columnName', 'multiple']; forEach(model.model.attributes, (attribute, index) => { map(attribute.params, (value, key) => { diff --git a/packages/strapi-plugin-content-type-builder/admin/src/containers/ModelPage/sagas.js b/packages/strapi-plugin-content-type-builder/admin/src/containers/ModelPage/sagas.js index ebb690db6c..f0da32e794 100644 --- a/packages/strapi-plugin-content-type-builder/admin/src/containers/ModelPage/sagas.js +++ b/packages/strapi-plugin-content-type-builder/admin/src/containers/ModelPage/sagas.js @@ -100,7 +100,7 @@ export function* submitChanges(action) { set(body.attributes[index].params, 'plugin', true); } - if (!value) { + if (!value && key !== 'multiple') { const paramsKey = includes(key, 'Value') ? replace(key,'Value', '') : key; unset(body.attributes[index].params, paramsKey); } @@ -116,6 +116,7 @@ export function* submitChanges(action) { const baseUrl = '/content-type-builder/models/'; const requestUrl = method === 'POST' ? baseUrl : `${baseUrl}${body.name}`; const opts = { method, body }; + const response = yield call(request, requestUrl, opts, true); if (response.ok) { diff --git a/packages/strapi-plugin-content-type-builder/services/ContentTypeBuilder.js b/packages/strapi-plugin-content-type-builder/services/ContentTypeBuilder.js index 325cb90dfc..09a03eba67 100755 --- a/packages/strapi-plugin-content-type-builder/services/ContentTypeBuilder.js +++ b/packages/strapi-plugin-content-type-builder/services/ContentTypeBuilder.js @@ -44,18 +44,23 @@ module.exports = { const model = source ? _.get(strapi.plugins, [source, 'models', name]) : _.get(strapi.models, name); - // const model = _.get(strapi.models, name); - const attributes = []; _.forEach(model.attributes, (params, name) => { const relation = _.find(model.associations, { alias: name }); - if (relation) { - params = _.omit(params, ['collection', 'model', 'via']); - params.target = relation.model || relation.collection; - params.key = relation.via; - params.nature = relation.nature; - params.targetColumnName = _.get((params.plugin ? strapi.plugins[params.plugin].models : strapi.models )[params.target].attributes[params.key], 'columnName', ''); + if (relation && !_.isArray(_.get(relation, 'related'))) { + if (params.plugin === 'upload' && relation.model || relation.collection === 'file') { + params = { + type: 'media', + multiple: params.collection ? true : false + }; + } else { + params = _.omit(params, ['collection', 'model', 'via']); + params.target = relation.model || relation.collection; + params.key = relation.via; + params.nature = relation.nature; + params.targetColumnName = _.get((params.plugin ? strapi.plugins[params.plugin].models : strapi.models )[params.target].attributes[params.key], 'columnName', ''); + } } attributes.push({ @@ -144,6 +149,14 @@ module.exports = { _.forEach(attributesConfigurable, attribute => { if (_.has(attribute, 'params.type')) { attrs[attribute.name] = attribute.params; + + if (attribute.params.type === 'media') { + attrs[attribute.name] = { + [attribute.params.multiple ? 'collection' : 'model']: 'file', + via: 'related', + plugin: 'upload' + } + } } else if (_.has(attribute, 'params.target')) { const relation = attribute.params; const attr = { diff --git a/packages/strapi-plugin-upload/models/File.settings.json b/packages/strapi-plugin-upload/models/File.settings.json index cdd330c296..57ed36057b 100644 --- a/packages/strapi-plugin-upload/models/File.settings.json +++ b/packages/strapi-plugin-upload/models/File.settings.json @@ -36,7 +36,8 @@ }, "related": { "collection": "*", - "filter": "field" + "filter": "field", + "configurable": false } } } diff --git a/packages/strapi-plugin-users-permissions/models/User.settings.json b/packages/strapi-plugin-users-permissions/models/User.settings.json index 99479b1cba..d7d33e058c 100644 --- a/packages/strapi-plugin-users-permissions/models/User.settings.json +++ b/packages/strapi-plugin-users-permissions/models/User.settings.json @@ -38,6 +38,10 @@ "via": "users", "plugin": "users-permissions", "configurable": false + }, + "products": { + "collection": "product", + "via": "manager" } } -} +} \ No newline at end of file