From daa5f9d81728dd7e97285a87d46e5530fc1dc74a Mon Sep 17 00:00:00 2001 From: AJ Moon Date: Sat, 10 Feb 2018 16:39:03 -0800 Subject: [PATCH 1/5] implementing relations: working (no autocomplete) --- example/config.yml | 8 + package.json | 2 + .../EditorWidgets/EditorWidgets.css | 1 + .../EditorWidgets/Relations/Relations.css | 39 ++++ .../Relations/RelationsControl.js | 176 ++++++++++++++++++ src/components/EditorWidgets/index.js | 3 +- .../site/content/docs/widgets/relations.md | 34 ++++ yarn.lock | 10 + 8 files changed, 272 insertions(+), 1 deletion(-) create mode 100644 src/components/EditorWidgets/Relations/Relations.css create mode 100644 src/components/EditorWidgets/Relations/RelationsControl.js create mode 100644 website/site/content/docs/widgets/relations.md diff --git a/example/config.yml b/example/config.yml index 9e245c33c788..a282f7b9cb6d 100644 --- a/example/config.yml +++ b/example/config.yml @@ -68,6 +68,14 @@ collections: # A list of collections the CMS should be able to edit folder: "_sink" create: true fields: + - label: "Tags" + name: "tags" + widget: "relations" + limit: "3" + collection: "posts" + searchFields: ["title"] + valueField: "title" + - label: "Related Post" name: "post" widget: "relationKitchenSinkPost" diff --git a/package.json b/package.json index 411396bc65fc..4a0adacdb0ec 100644 --- a/package.json +++ b/package.json @@ -154,6 +154,7 @@ "react-dom": "^16.0.0", "react-frame-component": "^2.0.0", "react-immutable-proptypes": "^2.1.0", + "react-input-autosize": "^2.2.1", "react-modal": "^3.1.5", "react-redux": "^4.4.0", "react-router-dom": "^4.2.2", @@ -161,6 +162,7 @@ "react-scroll-sync": "^0.4.0", "react-sortable-hoc": "^0.6.8", "react-split-pane": "^0.1.66", + "react-tagsinput": "^3.19.0", "react-textarea-autosize": "^5.2.0", "react-toggled": "^1.1.2", "react-topbar-progress-indicator": "^2.0.0", diff --git a/src/components/EditorWidgets/EditorWidgets.css b/src/components/EditorWidgets/EditorWidgets.css index 1c7eec76c7ba..05fc5a55ea55 100644 --- a/src/components/EditorWidgets/EditorWidgets.css +++ b/src/components/EditorWidgets/EditorWidgets.css @@ -7,6 +7,7 @@ @import "./Boolean/Boolean.css"; @import "./Relation/Relation.css"; @import "./DateTime/DateTime.css"; +@import "./Relations/Relations.css"; :root { --widgetNestDistance: 14px; diff --git a/src/components/EditorWidgets/Relations/Relations.css b/src/components/EditorWidgets/Relations/Relations.css new file mode 100644 index 000000000000..2751773fde12 --- /dev/null +++ b/src/components/EditorWidgets/Relations/Relations.css @@ -0,0 +1,39 @@ +@import "../Relation/ReactAutosuggest.css"; + +.react-tagsinput-tag { + background-color: var(--colorBackground); + border-radius: 2px; + border: 1px solid var(--colorActive); + color: var(--colorTextLead); + display: inline-block; + font-family: var(--fontFamilyMono); + font-size: 13px; + font-weight: 400; + margin-right: 5px; + padding: 5px; + +} + +.react-tagsinput-remove { + cursor: pointer; + font-weight: bold; +} + +.react-tagsinput-tag a::before { + content: " Γ—"; +} + +.react-tagsinput-input { + background: transparent; + border: 0; + color: var(--colorTextLead); + font-family: var(--fontFamilyPrimary); + font-size: 13px; + font-weight: 400; + margin-bottom: auto; + margin-top: auto; + outline: none; + padding: 5px; + width: 80px; + +} diff --git a/src/components/EditorWidgets/Relations/RelationsControl.js b/src/components/EditorWidgets/Relations/RelationsControl.js new file mode 100644 index 000000000000..d537c3145de5 --- /dev/null +++ b/src/components/EditorWidgets/Relations/RelationsControl.js @@ -0,0 +1,176 @@ +import React, { Component } from 'react'; +import { Loader } from 'UI'; +import TagsInput from 'react-tagsinput'; +import PropTypes from 'prop-types'; +import Autosuggest from 'react-autosuggest'; +import uuid from 'uuid/v4'; +import { Map } from 'immutable'; +import { connect } from 'react-redux'; +import { debounce } from 'lodash'; +import { query, clearSearch } from 'Actions/search'; + +class RelationsControl extends Component { + static propTypes = { + onChange: PropTypes.func.isRequired, + forID: PropTypes.string, + value: PropTypes.array, + field: PropTypes.node, + isFetching: PropTypes.node, + query: PropTypes.func.isRequired, + clearSearch: PropTypes.func.isRequired, + queryHits: PropTypes.oneOfType([ + PropTypes.array, + PropTypes.object, + ]), + classNameWrapper: PropTypes.string.isRequired, + setActiveStyle: PropTypes.func.isRequired, + setInactiveStyle: PropTypes.func.isRequired, + }; + + constructor(props, ctx) { + super(props, ctx); + this.controlID = uuid(); + this.didInitialSearch = false; + this.state = { value: [] }; + } + + componentDidMount() { + const { value, field } = this.props; + if (value) { + const collection = field.get('collection'); + const searchFields = field.get('searchFields').toJS(); + this.props.query(this.controlID, collection, searchFields, value); + } + } + + componentWillReceiveProps(nextProps) { + if (this.didInitialSearch) return; + if (nextProps.queryHits !== this.props.queryHits && nextProps.queryHits.get && nextProps.queryHits.get(this.controlID)) { + this.didInitialSearch = true; + const suggestion = nextProps.queryHits.get(this.controlID); + if (suggestion && suggestion.length === 1) { + const val = this.getSuggestionValue(suggestion[0]); + this.props.onChange(val, { [nextProps.field.get('collection')]: { [val]: suggestion[0].data } }); + } + } + } + + onChange = (tags) => { + this.setState({ value: tags }); + + this.props.onChange(tags.map(val => val.trim())); + }; + + onSuggestionSelected = (event, { suggestion }) => { + const value = this.getSuggestionValue(suggestion); + this.props.onChange({ [this.props.field.get('collection')]: { [value]: suggestion.data } }); + }; + + onSuggestionsFetchRequested = debounce(({ value }) => { + if (value.length < 2) return; + const { field } = this.props; + const collection = field.get('collection'); + const searchFields = field.get('searchFields').toJS(); + this.props.query(this.controlID, collection, searchFields, value); + }, 500); + + onSuggestionsClearRequested = () => { + this.props.clearSearch(); + }; + + getSuggestionValue = (suggestion) => { + const { field } = this.props; + const valueField = field.get('valueField'); + return suggestion.data[valueField]; + }; + + renderSuggestion = (suggestion) => { + const { field } = this.props; + const valueField = field.get('valueField'); + return {suggestion.data[valueField]}; + }; + + render() { + function autocompleteRenderInput({ addTag, ...props }) { + const handleOnChange = (e, { newValue, method }) => { + if (method === 'enter') { + e.preventDefault(); + } else { + props.onChange(e); + } + }; + + const inputValue = (props.value && props.value.trim().toLowerCase()) || ''; + // const inputLength = inputValue.length; + + const inputProps = { + placeholder: 'Add a Relation', + value: inputValue || '', + onChange: handleOnChange, + }; + + const suggestions = (this.queryHits.get) ? this.queryHits.get(this.controlID, []) : []; + + return ( +
+ + +
+ ); + } + + // Tags Input Variable Initialization. + const { + forID, + value, + classNameWrapper, + setActiveStyle, + setInactiveStyle, + } = this.props; + + const limit = this.props.field.get("limit", "-1"); + const unique = this.props.field.get("unique", false); + + return ( + + ); + } +} + +function mapStateToProps(state, ownProps) { + const { className } = ownProps; + const isFetching = state.search.get('isFetching'); + const queryHits = state.search.get('queryHits'); + return { isFetching, queryHits, className }; +} + +export default connect( + mapStateToProps, + { + query, + clearSearch, + }, + null, + { + withRef: true, + } +)(RelationsControl); diff --git a/src/components/EditorWidgets/index.js b/src/components/EditorWidgets/index.js index 94dc6c715c7e..305ff2ce740b 100644 --- a/src/components/EditorWidgets/index.js +++ b/src/components/EditorWidgets/index.js @@ -26,7 +26,7 @@ import ObjectPreview from './Object/ObjectPreview'; import RelationControl from './Relation/RelationControl'; import RelationPreview from './Relation/RelationPreview'; import BooleanControl from './Boolean/BooleanControl'; - +import RelationsControl from './Relations/RelationsControl'; registerWidget('string', StringControl, StringPreview); registerWidget('text', TextControl, TextPreview); @@ -41,4 +41,5 @@ registerWidget('select', SelectControl, SelectPreview); registerWidget('object', ObjectControl, ObjectPreview); registerWidget('relation', RelationControl, RelationPreview); registerWidget('boolean', BooleanControl); +registerWidget('relations', RelationsControl); registerWidget('unknown', UnknownControl, UnknownPreview); diff --git a/website/site/content/docs/widgets/relations.md b/website/site/content/docs/widgets/relations.md new file mode 100644 index 000000000000..1982fca302de --- /dev/null +++ b/website/site/content/docs/widgets/relations.md @@ -0,0 +1,34 @@ +--- +label: "Relations" +target: "relations" +type: "widget" +--- + +### Relations + +The relations widget allows you to reference items from another collection. It provides a search input with a list of entries from the collection you're referencing, and the list automatically updates with matched entries based on what you've typed. + +- **Name:** `relations` +- **UI:** text input with search result dropdown +- **Data type:** data type of the value pulled from the related collection item +- **Options:** + - `default`: accepts any widget data type; defaults to an empty string + - `collection`: (**required**) name of the collection being referenced (string) + - `searchFields`: (**required**) list of one or more names of fields in the referenced collection to search for the typed value + - `valueField`: (**required**) name of the field from the referenced collection whose value will be stored for the relation + - `limit`: limits the number of relations. defaults to unlimited relations. (number) + - `unique`: only allow unique relations. defaults to false. (boolean) + +- **Example** (assuming a separate "authors" collection with "name" and "twitterHandle" fields): + + ```yaml + - label: "Post Author" + name: "author" + widget: "relation" + limit: "4" + unique: true + collection: "authors" + searchFields: ["name", "twitterHandle"] + valueField: "name" + ``` + The generated UI input will search the authors collection by name and twitterHandle as the user types. On selection, the author name will be saved for the field. diff --git a/yarn.lock b/yarn.lock index 43bd0a379cca..2af6735c0dc8 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7403,6 +7403,12 @@ react-immutable-proptypes@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/react-immutable-proptypes/-/react-immutable-proptypes-2.1.0.tgz#023d6f39bb15c97c071e9e60d00d136eac5fa0b4" +react-input-autosize@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/react-input-autosize/-/react-input-autosize-2.2.1.tgz#ec428fa15b1592994fb5f9aa15bb1eb6baf420f8" + dependencies: + prop-types "^15.5.8" + react-modal@^3.1.5: version "3.1.6" resolved "https://registry.yarnpkg.com/react-modal/-/react-modal-3.1.6.tgz#82e63f1ec86b80e242518250d066ee37fa035f8a" @@ -7492,6 +7498,10 @@ react-style-proptype@^3.0.0: dependencies: prop-types "^15.5.4" +react-tagsinput@^3.19.0: + version "3.19.0" + resolved "https://registry.yarnpkg.com/react-tagsinput/-/react-tagsinput-3.19.0.tgz#6e3b45595f2d295d4657bf194491988f948caabf" + react-test-renderer@^16.0.0, react-test-renderer@^16.0.0-0: version "16.1.1" resolved "https://registry.yarnpkg.com/react-test-renderer/-/react-test-renderer-16.1.1.tgz#a05184688d564be799f212449262525d1e350537" From 52b242e65946992775823cd903201b3dbd6fb5be Mon Sep 17 00:00:00 2001 From: AJ Moon Date: Sun, 11 Feb 2018 20:35:18 -0800 Subject: [PATCH 2/5] auto suggest implemented --- .../EditorWidgets/Relations/Relations.css | 37 ++++---- .../Relations/RelationsControl.js | 94 +++++++++---------- .../site/content/docs/widgets/relations.md | 2 + 3 files changed, 68 insertions(+), 65 deletions(-) diff --git a/src/components/EditorWidgets/Relations/Relations.css b/src/components/EditorWidgets/Relations/Relations.css index 2751773fde12..03cfab850911 100644 --- a/src/components/EditorWidgets/Relations/Relations.css +++ b/src/components/EditorWidgets/Relations/Relations.css @@ -1,39 +1,42 @@ -@import "../Relation/ReactAutosuggest.css"; +@import '../Relation/ReactAutosuggest.css'; .react-tagsinput-tag { - background-color: var(--colorBackground); - border-radius: 2px; border: 1px solid var(--colorActive); - color: var(--colorTextLead); + border-radius: var(--borderWidth); display: inline-block; - font-family: var(--fontFamilyMono); + background-color: var(--colorBackground); + margin: 2.5px; + padding: 5px; + color: var(--colorTextLead); font-size: 13px; + font-family: var(--fontFamilyMono); font-weight: 400; - margin-right: 5px; - padding: 5px; - } .react-tagsinput-remove { - cursor: pointer; font-weight: bold; + cursor: pointer; } .react-tagsinput-tag a::before { - content: " Γ—"; + content: ' Γ—'; } .react-tagsinput-input { - background: transparent; border: 0; + margin-top: auto; + margin-bottom: auto; + background: var(--colorInputBackground); + padding: 5px; + outline: none; + width: auto; color: var(--colorTextLead); - font-family: var(--fontFamilyPrimary); font-size: 13px; font-weight: 400; - margin-bottom: auto; - margin-top: auto; - outline: none; - padding: 5px; - width: 80px; + font-family: var(--fontFamilyPrimary); +} +.nc-relations-container { + display: inline-block; + width: auto; } diff --git a/src/components/EditorWidgets/Relations/RelationsControl.js b/src/components/EditorWidgets/Relations/RelationsControl.js index d537c3145de5..ac29e19da52c 100644 --- a/src/components/EditorWidgets/Relations/RelationsControl.js +++ b/src/components/EditorWidgets/Relations/RelationsControl.js @@ -55,15 +55,9 @@ class RelationsControl extends Component { } } - onChange = (tags) => { - this.setState({ value: tags }); - - this.props.onChange(tags.map(val => val.trim())); - }; - - onSuggestionSelected = (event, { suggestion }) => { - const value = this.getSuggestionValue(suggestion); - this.props.onChange({ [this.props.field.get('collection')]: { [value]: suggestion.data } }); + onChange = (relations) => { + this.setState({ value: relations }); + this.props.onChange(relations.map(val => val)); }; onSuggestionsFetchRequested = debounce(({ value }) => { @@ -84,50 +78,49 @@ class RelationsControl extends Component { return suggestion.data[valueField]; }; + autocompleteRenderInput = ({ addTag, ...props }) => { + const handleOnChange = (e, { newValue, method }) => { + if (method === 'enter') { + e.preventDefault(); + } else { + this.onChange(e); + } + }; + + const inputprops = { + placeholder: props.placeholder, + onChange: handleOnChange, + }; + + const suggestions = (this.props.queryHits.get) ? this.props.queryHits.get(this.controlID, []) : []; + + return ( +
+ { + const value = this.getSuggestionValue(suggestion); + addTag(value); + }} + getSuggestionValue={this.getSuggestionValue} + renderSuggestion={this.renderSuggestion} + inputProps={{ ...props, inputprops }} + focusInputOnSuggestionClick={false} + /> + +
+ ); + }; + renderSuggestion = (suggestion) => { const { field } = this.props; const valueField = field.get('valueField'); return {suggestion.data[valueField]}; - }; + }; render() { - function autocompleteRenderInput({ addTag, ...props }) { - const handleOnChange = (e, { newValue, method }) => { - if (method === 'enter') { - e.preventDefault(); - } else { - props.onChange(e); - } - }; - - const inputValue = (props.value && props.value.trim().toLowerCase()) || ''; - // const inputLength = inputValue.length; - - const inputProps = { - placeholder: 'Add a Relation', - value: inputValue || '', - onChange: handleOnChange, - }; - - const suggestions = (this.queryHits.get) ? this.queryHits.get(this.controlID, []) : []; - - return ( -
- - -
- ); - } - // Tags Input Variable Initialization. const { forID, @@ -139,6 +132,10 @@ class RelationsControl extends Component { const limit = this.props.field.get("limit", "-1"); const unique = this.props.field.get("unique", false); + const inputProps = { + placeholder: this.props.field.get("placeholder", 'Add a Relation'), + }; + return ( ); } diff --git a/website/site/content/docs/widgets/relations.md b/website/site/content/docs/widgets/relations.md index 1982fca302de..21f7ab38779d 100644 --- a/website/site/content/docs/widgets/relations.md +++ b/website/site/content/docs/widgets/relations.md @@ -18,6 +18,7 @@ The relations widget allows you to reference items from another collection. It p - `valueField`: (**required**) name of the field from the referenced collection whose value will be stored for the relation - `limit`: limits the number of relations. defaults to unlimited relations. (number) - `unique`: only allow unique relations. defaults to false. (boolean) + - `placeholder`: the placeholder text in the input field. defaults to "Add a Relation". (string) - **Example** (assuming a separate "authors" collection with "name" and "twitterHandle" fields): @@ -27,6 +28,7 @@ The relations widget allows you to reference items from another collection. It p widget: "relation" limit: "4" unique: true + placeholder: "Add Author Here" collection: "authors" searchFields: ["name", "twitterHandle"] valueField: "name" From 4c912c1ad77dcd73a0f7b9e98fc01753715db2b0 Mon Sep 17 00:00:00 2001 From: AJ Moon Date: Sun, 11 Feb 2018 21:27:11 -0800 Subject: [PATCH 3/5] add self as contributer --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index 4a1a1a441a87..e22c814fe7b2 100644 --- a/README.md +++ b/README.md @@ -62,8 +62,12 @@ Thanks goes to these wonderful people ([emoji key](https://github.com/kentcdodds | [
Bryan Robinson](http://bryanlrobinson.com)
[πŸ“–](https://github.com/netlify/netlify-cms/commits?author=brob "Documentation") | [
Darren](https://github.com/dardub)
[πŸ“–](https://github.com/netlify/netlify-cms/commits?author=dardub "Documentation") | [
Richard Pullinger](http://www.richardpullinger.com)
[πŸ’»](https://github.com/netlify/netlify-cms/commits?author=rpullinger "Code") | [
Taylor Bryant](https://taylorbryant.blog)
[πŸ“–](https://github.com/netlify/netlify-cms/commits?author=taylorbryant "Documentation") | [
kvanerkelens](https://github.com/kvanerkelens)
[πŸ“–](https://github.com/netlify/netlify-cms/commits?author=kvanerkelens "Documentation") | [
Patrick Sier](https://patsier.com/)
[πŸ’»](https://github.com/netlify/netlify-cms/commits?author=pjsier "Code") | [
Christian Nolte](http://noltech.net)
[πŸ’»](https://github.com/netlify/netlify-cms/commits?author=drlogout "Code") | | [
Edward Betts](http://edwardbetts.com/)
[πŸ“–](https://github.com/netlify/netlify-cms/commits?author=EdwardBetts "Documentation") | [
Josh Hardman](https://github.com/jhardman0830)
[πŸ“–](https://github.com/netlify/netlify-cms/commits?author=jhardman0830 "Documentation") | [
Mantas](https://behance.net/mistermantas)
[πŸ“–](https://github.com/netlify/netlify-cms/commits?author=mistermantas "Documentation") | [
Marco Biedermann](https://www.marcobiedermann.com)
[πŸ“–](https://github.com/netlify/netlify-cms/commits?author=marcobiedermann "Documentation") | [
Max Stoiber](https://mxstbr.blog/newsletter)
[πŸ“–](https://github.com/netlify/netlify-cms/commits?author=mxstbr "Documentation") | [
Vyacheslav Matyukhin](http://berekuk.ru)
[πŸ“–](https://github.com/netlify/netlify-cms/commits?author=berekuk "Documentation") | [
jimmaaay](https://jimmythompson.me)
[πŸ’»](https://github.com/netlify/netlify-cms/commits?author=jimmaaay "Code") | | [
LuΓ­s Miguel](https://github.com/Quicksaver)
[πŸ›](https://github.com/netlify/netlify-cms/issues?q=author%3AQuicksaver "Bug reports") [πŸ’»](https://github.com/netlify/netlify-cms/commits?author=Quicksaver "Code") | [
Chris Swithinbank](http://chrisswithinbank.net/)
[πŸ“–](https://github.com/netlify/netlify-cms/commits?author=delucis "Documentation") | [
remmah](https://github.com/remmah)
[πŸ“–](https://github.com/netlify/netlify-cms/commits?author=remmah "Documentation") | [
Sumeet Jain](http://sumeetjain.com)
[πŸ“–](https://github.com/netlify/netlify-cms/commits?author=sumeetjain "Documentation") | [
Sagar Khatri](https://github.com/ragasirtahk)
[πŸ“–](https://github.com/netlify/netlify-cms/commits?author=ragasirtahk "Documentation") [πŸ’‘](#example-ragasirtahk "Examples") | [
Kevin Doocey](https://www.dooceykev.in)
[πŸ’»](https://github.com/netlify/netlify-cms/commits?author=Doocey "Code") | [
Swieckowski](https://www.linkedin.com/in/arthur-swieckowski/)
[πŸ’»](https://github.com/netlify/netlify-cms/commits?author=Swieckowski "Code") [πŸ“–](https://github.com/netlify/netlify-cms/commits?author=Swieckowski "Documentation") [⚠️](https://github.com/netlify/netlify-cms/commits?author=Swieckowski "Tests") | +<<<<<<< 52b242e65946992775823cd903201b3dbd6fb5be | [
Tim Carry](http://www.pixelastic.com/)
[πŸ’»](https://github.com/netlify/netlify-cms/commits?author=pixelastic "Code") [🎨](#design-pixelastic "Design") [πŸ“–](https://github.com/netlify/netlify-cms/commits?author=pixelastic "Documentation") | [
Sol Park](https://github.com/solpark)
[πŸ’»](https://github.com/netlify/netlify-cms/commits?author=solpark "Code") | [
Michael Romani](https://github.com/michaelromani)
[πŸ’»](https://github.com/netlify/netlify-cms/commits?author=michaelromani "Code") | [
Xifeng Jin](http://linkedin/in/xifengjin88)
[πŸ›](https://github.com/netlify/netlify-cms/issues?q=author%3Axifengjin88 "Bug reports") [πŸ’»](https://github.com/netlify/netlify-cms/commits?author=xifengjin88 "Code") | [
Pedro Duarte](http://pedroduarte.me)
[πŸ›](https://github.com/netlify/netlify-cms/issues?q=author%3Apeduarte "Bug reports") [πŸ’»](https://github.com/netlify/netlify-cms/commits?author=peduarte "Code") [πŸ“–](https://github.com/netlify/netlify-cms/commits?author=peduarte "Documentation") | [
Antonio Argote](http://antonioargote.com)
[🎨](#design-Strangehill "Design") | [
Kristaps Taube](https://www.ktaube.com)
[πŸ’»](https://github.com/netlify/netlify-cms/commits?author=ktaube "Code") | | [
David Ko](https://github.com/daveyko)
[πŸ’»](https://github.com/netlify/netlify-cms/commits?author=daveyko "Code") | [
IΓ±aki GarcΓ­a](http://www.txorua.com)
[🎨](#design-igarbla "Design") | +======= +| [
Tim Carry](http://www.pixelastic.com/)
[πŸ’»](https://github.com/netlify/netlify-cms/commits?author=pixelastic "Code") [🎨](#design-pixelastic "Design") [πŸ“–](https://github.com/netlify/netlify-cms/commits?author=pixelastic "Documentation") | [
Sol Park](https://github.com/solpark)
[πŸ’»](https://github.com/netlify/netlify-cms/commits?author=solpark "Code") | [
Michael Romani](https://github.com/michaelromani)
[πŸ’»](https://github.com/netlify/netlify-cms/commits?author=michaelromani "Code") | [
Alex Moon](https://github.com/moonmeister)
[πŸ’»](https://github.com/netlify/netlify-cms/commits?author=moonmeister "Code") [πŸ“–](https://github.com/netlify/netlify-cms/commits?author=moonmeister "Documentation") | +>>>>>>> add self as contributer This project follows the [all-contributors](https://github.com/kentcdodds/all-contributors) specification. Contributions of any kind welcome! From d723b28a2a6bdc156bd4b0f8f5e6142a6e533df9 Mon Sep 17 00:00:00 2001 From: AJ Moon Date: Tue, 13 Feb 2018 23:06:31 -0800 Subject: [PATCH 4/5] Cleanup upneeded local state management calls --- .../EditorWidgets/Relations/RelationsControl.js | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/src/components/EditorWidgets/Relations/RelationsControl.js b/src/components/EditorWidgets/Relations/RelationsControl.js index ac29e19da52c..245afada83ce 100644 --- a/src/components/EditorWidgets/Relations/RelationsControl.js +++ b/src/components/EditorWidgets/Relations/RelationsControl.js @@ -31,7 +31,6 @@ class RelationsControl extends Component { super(props, ctx); this.controlID = uuid(); this.didInitialSearch = false; - this.state = { value: [] }; } componentDidMount() { @@ -56,7 +55,6 @@ class RelationsControl extends Component { } onChange = (relations) => { - this.setState({ value: relations }); this.props.onChange(relations.map(val => val)); }; @@ -86,12 +84,12 @@ class RelationsControl extends Component { this.onChange(e); } }; - + const inputprops = { placeholder: props.placeholder, onChange: handleOnChange, }; - + const suggestions = (this.props.queryHits.get) ? this.props.queryHits.get(this.controlID, []) : []; return ( @@ -128,20 +126,20 @@ class RelationsControl extends Component { classNameWrapper, setActiveStyle, setInactiveStyle, - } = this.props; + } = this.props; const limit = this.props.field.get("limit", "-1"); const unique = this.props.field.get("unique", false); const inputProps = { placeholder: this.props.field.get("placeholder", 'Add a Relation'), }; - + return ( - Date: Wed, 21 Feb 2018 11:44:16 -0800 Subject: [PATCH 5/5] add preview...wip --- .../Relations/RelationsControl.js | 1 - .../Relations/RelationsPreview.js | 18 ++++++++++++++++++ src/components/EditorWidgets/index.js | 4 +++- 3 files changed, 21 insertions(+), 2 deletions(-) create mode 100644 src/components/EditorWidgets/Relations/RelationsPreview.js diff --git a/src/components/EditorWidgets/Relations/RelationsControl.js b/src/components/EditorWidgets/Relations/RelationsControl.js index 245afada83ce..d74647eb8a44 100644 --- a/src/components/EditorWidgets/Relations/RelationsControl.js +++ b/src/components/EditorWidgets/Relations/RelationsControl.js @@ -134,7 +134,6 @@ class RelationsControl extends Component { placeholder: this.props.field.get("placeholder", 'Add a Relation'), }; - return ( + {value.map(val => + {val} + ) + } + + ); +} + +RelationsPreview.propTypes = { + value: PropTypes.node, + field: PropTypes.node, +}; diff --git a/src/components/EditorWidgets/index.js b/src/components/EditorWidgets/index.js index 305ff2ce740b..a715444fd61c 100644 --- a/src/components/EditorWidgets/index.js +++ b/src/components/EditorWidgets/index.js @@ -27,6 +27,8 @@ import RelationControl from './Relation/RelationControl'; import RelationPreview from './Relation/RelationPreview'; import BooleanControl from './Boolean/BooleanControl'; import RelationsControl from './Relations/RelationsControl'; +import RelationsPreview from './Relations/RelationsPreview'; + registerWidget('string', StringControl, StringPreview); registerWidget('text', TextControl, TextPreview); @@ -41,5 +43,5 @@ registerWidget('select', SelectControl, SelectPreview); registerWidget('object', ObjectControl, ObjectPreview); registerWidget('relation', RelationControl, RelationPreview); registerWidget('boolean', BooleanControl); -registerWidget('relations', RelationsControl); +registerWidget('relations', RelationsControl, RelationsPreview); registerWidget('unknown', UnknownControl, UnknownPreview);