Last active
September 21, 2016 20:22
-
-
Save davidgljay/1d1223c819456c36df1a90543eaa5dc9 to your computer and use it in GitHub Desktop.
Coral Dynamic Config Proposal
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
let config = { | |
/* | |
* Unique identifier used to find this config file's view | |
*/ | |
uuid: 'abcd12345', | |
/* | |
* Item that serves as the root of the view and that | |
* is passed to children of RootContainer. | |
*/ | |
root:{ | |
type:'stream' | |
}, | |
/* | |
* A list of queries that will be called on the backend view. | |
* These can be accessed via some action. | |
*/ | |
queries:{ | |
init:'a_query_string', //Query to initialize | |
getItems: 'another_query_string' //Query to get an array of items | |
}, | |
/* | |
* A list of components that will be placed in the application's containers. | |
* They can appear in any order. | |
*/ | |
components: [ | |
/* | |
* This is an example of a simple config object. | |
* It's container recieves an id, it uses that id to look up | |
* a comment object, and it passes the 'pubdate' prop of that object | |
* to component PubDate. | |
* | |
* Renders component 'Pubdate' in container 'Comment' with props: | |
* this.props === { | |
* pubdate: somedate | |
* } | |
*/ | |
{ | |
container:'Comment', //The container in which to instantiate this component | |
component:'PubDate', //The component to instantiate | |
order:-10, //The order that this component should appear within the container | |
graphQL: '(type='comment'){{pubdate}}' //GraphQL for retreiving data for the component from the appropriate item | |
}, | |
/* | |
* An example of a config object that traverses a path. The container is passed a comment id | |
* and retrieves that comment's author. All such pathing must be handled in this configuration file | |
* so that it is transparent to both the front and back end. | |
* | |
* Renders component 'DefaultAuthor in container 'Author' with props: | |
* this.props === { | |
* name: 'Suzan' | |
* } | |
*/ | |
{ | |
container: 'Author', | |
component: 'DefaultAuthor', | |
order: 10, | |
graphQL: '(type='comment'){{author(type='user'){name}}}' //Get the name of the author for this comment | |
}, | |
/* | |
* This is an example of a config item which references its children and employs iteration. | |
* In this case, the container gets an array called "comments" from an item of type "Stream" | |
* and iterates over those items, passing each comment id as prop 'id' to each of its children. | |
* | |
* Renders the children of the Stream container with props: | |
* this.props === { | |
* comments: [ | |
* commentId1, | |
* commentId2, | |
* etc | |
* ] | |
* } | |
*/ | |
{ | |
container:'Stream', | |
mapChildren: true, //Rather than loading a component, this config item | |
//passes its props to the container's children. | |
order:0, | |
graphQL: '(type='stream'){{comments(type='comment'){id}}}' //Gets an array of comments and returns their ids | |
}, | |
{ | |
/* | |
* This is an example of a component with a one to many relationship: a list of users | |
* who like a comment. | |
* The ItemPath encounters a one-to-many relationship between comments and likes. When this | |
* happens it splits the remainder of the path into an array. Multidimensional arrays could be | |
* created this way. | |
* | |
* Renders component 'UsersWhoLike' in container 'UsersWhoLikeContainer' with props: | |
* this.props === { | |
* users:[ | |
* { | |
* name: 'Joe' | |
* }, | |
* { | |
* name: 'Sue' | |
* } | |
* ] | |
* } | |
*/ | |
container: 'UsersWhoLikeContainer', | |
component: 'UsersWhoLike', | |
order:10, | |
graphQL:'(type='comment'){{likes(type='like'){user(type='user'){name}}}}' | |
}, | |
/* | |
* This is an example of a component which which pulls information from multiple item types. | |
* This is expessed through multiple item types, and some specification in propTypes. | |
* In this example, we're a going to show a graph of likes on the user's comments since | |
* they've joined. | |
* | |
* Renders component 'UserLikesGraph' in container 'Stats' with props: | |
* | |
* this.props === { | |
* created_at: somedate, | |
* likes: [ | |
* { | |
* created_at: anotherdate | |
* }, | |
* { | |
* created_at: yetanotherdate | |
* } | |
* ] | |
* } | |
* | |
*/ | |
{ | |
container: 'Stats', | |
component: 'UserLikesGraph', | |
order: 5, | |
graphQL: '(type='user'){{created_at, likes(type='like'){created_at}}}' | |
} | |
] | |
}; | |
export default config; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React from 'react'; | |
import { connect } from 'react-redux'; | |
import Radium from 'radium'; | |
import {RootContainer, Container, MapContainer} from 'react-dynamic-containers'; | |
@connect(state => state.playground) | |
@Radium | |
class Preview extends React.Component { | |
render() { | |
return ( | |
<div> | |
{ | |
/* | |
* RootContainer takes an ID of a root component used to kick off a query | |
* for the view. | |
*/ | |
} | |
<RootContainer type="stream" id={this.props.params.streamId}> | |
{ | |
/* | |
* These components are then each passed the id of the stream object. | |
* That id is used as a starting place for graphQL queries for that container. | |
*/ | |
} | |
<Container name='Guidelines' /> | |
<Container name='CommentBox' /> | |
{ | |
/* | |
* This component has children, which can be rendered in config along with | |
* other components. | |
*/ | |
} | |
<Container name='Stream'> | |
{ | |
/* | |
* MapContainer looks for an array in props (in this case "comments") | |
* and maps its children to that array. | |
* | |
* If MapContainer is passed props like so: | |
* | |
* this.props === { | |
* comments:[ | |
* { | |
* id:1 | |
* }, | |
* { | |
* id:2 | |
* } | |
* ] | |
* } | |
* Then it will render an Author and Comment container with id=1, then with id=2, etc. | |
*/ | |
} | |
<MapContainer array="comments"> | |
{ | |
/* | |
* These containers will be passed an ID for a item of type comment. | |
*/ | |
} | |
<Container name='Author'/> | |
<Container name='Comment' /> | |
</MapContainer> | |
</Container> | |
</RootContainer> | |
</div> | |
); | |
} | |
} | |
export default Preview; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Proposal for Coral Configuration
Above is a proposal for how an application like Talk could be structured around dynamic components.