From 0e7d30146cf861e6c2eb36322be317b32ccccdf6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rge=20N=C3=A6ss?= Date: Wed, 30 Jan 2019 12:04:53 +0100 Subject: [PATCH] [base] Create part of referring documents hoc/util-component (#1188) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is a tiny refactor of the `enhanceWithReferringDocuments` utility used in desk tool for fetching a list of document that refers to the one you are attempting to unpublish/delete. Since it is useful for other packages as well, i moved it into base and made a sanity-part of it. Additionally it is usable not only a higher order component, but also as a component that takes a render func as child, so it can be used like this: ```jsx import {WithReferringDocuments} from 'part:@sanity/base/with-referring-documents' function MyComponent(props) { return ( {({isLoading, referringDocuments}) => isLoading ? 'Loading referring documents…' : `Found ${referringDocuments.length} documents referring to ${props.documentId}` } ) } ``` --- packages/@sanity/base/sanity.json | 8 +++ .../src/components/WithReferringDocuments.js | 25 +++++++ .../enhanceWithReferringDocuments.js | 67 ++++++------------- 3 files changed, 55 insertions(+), 45 deletions(-) create mode 100644 packages/@sanity/base/src/components/WithReferringDocuments.js diff --git a/packages/@sanity/base/sanity.json b/packages/@sanity/base/sanity.json index a7b9e5683ea..956350e9541 100644 --- a/packages/@sanity/base/sanity.json +++ b/packages/@sanity/base/sanity.json @@ -187,6 +187,10 @@ "name": "part:@sanity/base/query-container", "description": "Wraps a query and passes down results as props to its child component" }, + { + "name": "part:@sanity/base/with-referring-documents", + "description": "A utility component that takes a document id and calls its child render prop with a list of documents referring to it" + }, { "name": "part:@sanity/base/theme/layout/resets-style", "description": "Provides resets for resetting browser styling" @@ -410,6 +414,10 @@ "implements": "part:@sanity/base/query-container", "path": "components/QueryContainer" }, + { + "implements": "part:@sanity/base/with-referring-documents", + "path": "components/WithReferringDocuments" + }, { "implements": "part:@sanity/base/locale/formatters", "path": "components/IntlWrapper.js" diff --git a/packages/@sanity/base/src/components/WithReferringDocuments.js b/packages/@sanity/base/src/components/WithReferringDocuments.js new file mode 100644 index 00000000000..cf3e0e033d5 --- /dev/null +++ b/packages/@sanity/base/src/components/WithReferringDocuments.js @@ -0,0 +1,25 @@ +import documentStore from 'part:@sanity/base/datastore/document' +import {withPropsStream} from 'react-props-stream' +import {concat, of} from 'rxjs' +import {distinctUntilChanged, map, switchMap} from 'rxjs/operators' + +const loadProps = receivedProps$ => + receivedProps$.pipe( + distinctUntilChanged((prev, next) => prev.id === next.id), + switchMap(receivedProps => + concat( + of({...receivedProps, referringDocuments: [], isLoading: true}), + documentStore.query('*[references($docId)] [0...101]', {docId: receivedProps.id}).pipe( + map(event => ({ + ...receivedProps, + referringDocuments: event.documents, + isLoading: false + })) + ) + ) + ) + ) + +export const WithReferringDocuments = withPropsStream(loadProps, ({children, ...props}) => + children(props) +) diff --git a/packages/@sanity/desk-tool/src/components/enhanceWithReferringDocuments.js b/packages/@sanity/desk-tool/src/components/enhanceWithReferringDocuments.js index 8a33a4396b8..d4291d7c35a 100644 --- a/packages/@sanity/desk-tool/src/components/enhanceWithReferringDocuments.js +++ b/packages/@sanity/desk-tool/src/components/enhanceWithReferringDocuments.js @@ -1,51 +1,28 @@ import React from 'react' import PropTypes from 'prop-types' -import documentStore from 'part:@sanity/base/datastore/document' +import {WithReferringDocuments} from 'part:@sanity/base/with-referring-documents' -export default function withReferringDocuments(Component) { - return class extends React.PureComponent { - static displayName = `enhanceWithAvailHeight(${Component.displayName || Component.name})` - - static propTypes = { - published: PropTypes.object - } - - state = { - isLoading: false, - referringDocuments: [] - } - - componentDidMount() { - const {published} = this.props - if (!published) { - return - } - this.setState({isLoading: true}) - this.refSubscription = documentStore - .query('*[references($docId)] [0...101]', {docId: published._id}) - .subscribe(event => { - this.setState({ - referringDocuments: event.documents || [], - isLoading: false - }) - }) - } - - componentWillUnmount() { - if (this.refSubscription) { - this.refSubscription.unsubscribe() - } - } +export default function enhanceWithReferringDocuments(Component) { + function EnhancedWithReferringDocuments(props) { + // eslint-disable-next-line react/no-multi-comp + const renderChild = ({isLoading, referringDocuments}) => ( + + ) + return props.published ? ( + {renderChild} + ) : ( + renderChild({referringDocuments: [], isLoading: false}) + ) + } - render() { - const {isLoading, referringDocuments} = this.state - return ( - - ) - } + EnhancedWithReferringDocuments.displayName = `enhanceWithReferringDocuments(${Component.displayName || + Component.name})` + EnhancedWithReferringDocuments.propTypes = { + published: PropTypes.object } + return EnhancedWithReferringDocuments }