Last active
January 13, 2017 05:31
-
-
Save xavxyz/65cb4869f709fbf95fd09c66c118b775 to your computer and use it in GitHub Desktop.
Over-engineered experiment, yet interesting, on Nova forms and data loading with GraphQL
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
// custom field on Categories, querying a list of Categories | |
{ | |
fieldName: 'attachedTeams', | |
fieldSchema: { | |
type: [String], | |
control: Components.CategoriesAttachedTeams, | |
optional: true, | |
insertableBy: ['admins'], | |
editableBy: ['admins'], | |
viewableBy: ['members'], | |
resolveAs: 'attachedTeams: [Category]', // I want to access these data | |
} | |
}, | |
// ...... | |
// CategoriesEditForm.jsx | |
<SmartForm | |
collection={Categories} | |
documentId={props.category._id} | |
successCallback={category => { | |
props.closeCallback(); | |
props.flash(context.intl.formatMessage({id: 'categories.edit_success'}, {name: category.name}), "success"); | |
}} | |
removeSuccessCallback={({documentId, documentTitle}) => { | |
props.closeCallback(); | |
props.flash(context.intl.formatMessage({id: 'categories.delete_success'}, {name: documentTitle}), "success"); | |
// context.events.track("category deleted", {_id: documentId}); | |
}} | |
showRemove={true} | |
/** | |
* I want to have the ability to query my custom resolvers here | |
*/ | |
/> | |
// .... | |
// current state of FormWrapper.jsx | |
// see https://github.com/TelescopeJS/Telescope/blob/devel/packages/nova-forms/lib/FormWrapper.jsx#L67-L80 | |
// fields with resolvers that contain "[" should be treated as arrays of _ids | |
// TODO: find a cleaner way to handle this | |
relevantFields = relevantFields.map(fieldName => { | |
const resolveAs = this.getSchema()[fieldName].resolveAs; | |
return resolveAs && resolveAs.indexOf('[') > -1 ? `${fieldName}{_id}` : fieldName; | |
}); | |
// generate fragment based on the fields that can be edited. Note: always add _id. | |
const queryFragment = gql` | |
fragment ${fragmentName} on ${this.props.collection.typeName} { | |
_id | |
${relevantFields.join('\n')} | |
} | |
` |
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
// CategoriesEditForm.jsx modifications | |
<SmartForm | |
collection={Categories} | |
// ... | |
queryCustomResolverFields={{ | |
attachedTeams: ['name', 'image', 'slug'], | |
}} | |
/> | |
// ....... | |
// FormWrapper.jsx modifications | |
relevantFields = relevantFields.map(fieldName => { | |
const resolveAs = this.getSchema()[fieldName].resolveAs; | |
if (resolveAs && resolveAs.includes('[')) { | |
let baseFields = ['_id']; | |
const additionalFields = this.props.queryCustomResolverFields && this.props.queryCustomResolverFields[fieldName] || []; | |
return `${fieldName}{ ${[...baseFields, ...additionalFields].join(' ')} }`; | |
} else { | |
return fieldName; | |
} | |
}); | |
// conclusion: it works, but asking for the data is lame: | |
// | |
// queryCustomResolverFields={{ | |
// attachedTeams: ['name', 'image', 'slug'], | |
// }} |
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
// CategoriesEditForm.jsx modifications | |
<SmartForm | |
collection={Categories} | |
// ... | |
additionnalFragments={{ | |
// youhou 🎉 I'm using directly a gql fragment that I could import from somewhere else! | |
attachedTeams: gql` | |
fragment attachedTeams on Category { | |
_id | |
name | |
slug | |
image | |
} | |
` | |
}} | |
/> | |
// FormWrapper.jsx modifications | |
// fields with resolvers that contain "[" should be treated as arrays of _ids by default, or queried with an additional fragment supplied as a prop | |
relevantFields = relevantFields.map(fieldName => { | |
const resolveAs = this.getSchema()[fieldName].resolveAs; | |
if (resolveAs && resolveAs.includes('[')) { | |
const additionalFragment = this.props.additionnalFragments && this.props.additionnalFragments[fieldName]; | |
// no additional fragment supplied for this field | |
if (!additionalFragment) { | |
return `${fieldName} { _id }`; | |
} | |
// there is a fragment supplied, add it to the final query sent | |
const additionalFragmentBody = additionalFragment.loc.source.body; | |
additionalFragmentsList.push(additionalFragmentBody); | |
// add the field name + fragment name to the query sent | |
const additionalFragmentName = additionalFragment.definitions[0].name.value; | |
return `${fieldName} { ...${additionalFragmentName} }`; | |
} else { | |
return fieldName; | |
} | |
}); | |
// generate fragment based on the fields that can be edited. Note: always add _id. | |
const queryFragment = gql` | |
fragment ${fragmentName} on ${this.props.collection.typeName} { | |
_id | |
${relevantFields.join('\n')} | |
} | |
${additionalFragmentsList.join('\n')} | |
` | |
// conclusion: it's overcomplicated. let's just add an option to pass a custom query to the form. 🎩 |
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
// generate fragment based on the fields that can be edited. Note: always add _id. | |
const generatedFragment = gql` | |
fragment ${fragmentName} on ${this.props.collection.typeName} { | |
_id | |
${relevantFields.join('\n')} | |
} | |
` | |
// get query & mutation fragment from props or else default to generatedFragment | |
const queryFragment = this.props.fragment || generatedFragment; | |
const mutationFragment = this.props.fragment || generatedFragment; | |
// 🤙 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment