From 76a2e6befb3aea6e890bb3c2e001a4635d05091a Mon Sep 17 00:00:00 2001 From: Henry Jameson Date: Sun, 25 Apr 2021 12:50:17 +0300 Subject: remove Vue.component from hooks --- src/hocs/with_subscription/with_subscription.jsx | 93 ++++++++++++++++++++++++ 1 file changed, 93 insertions(+) create mode 100644 src/hocs/with_subscription/with_subscription.jsx (limited to 'src/hocs/with_subscription/with_subscription.jsx') diff --git a/src/hocs/with_subscription/with_subscription.jsx b/src/hocs/with_subscription/with_subscription.jsx new file mode 100644 index 00000000..7e590f73 --- /dev/null +++ b/src/hocs/with_subscription/with_subscription.jsx @@ -0,0 +1,93 @@ +import isEmpty from 'lodash/isEmpty' +import { getComponentProps } from '../../services/component_utils/component_utils' +import './with_subscription.scss' + +import { FontAwesomeIcon as FAIcon } from '@fortawesome/vue-fontawesome' +import { library } from '@fortawesome/fontawesome-svg-core' +import { + faCircleNotch +} from '@fortawesome/free-solid-svg-icons' + +library.add( + faCircleNotch +) + +const withSubscription = ({ + fetch, // function to fetch entries and return a promise + select, // function to select data from store + childPropName = 'content', // name of the prop to be passed into the wrapped component + additionalPropNames = [] // additional prop name list of the wrapper component +}) => (WrappedComponent) => { + const originalProps = Object.keys(getComponentProps(WrappedComponent)) + const props = originalProps.filter(v => v !== childPropName).concat(additionalPropNames) + + return { + props: [ + ...props, + 'refresh' // boolean saying to force-fetch data whenever created + ], + data () { + return { + loading: false, + error: false + } + }, + computed: { + fetchedData () { + return select(this.$props, this.$store) + } + }, + created () { + if (this.refresh || isEmpty(this.fetchedData)) { + this.fetchData() + } + }, + methods: { + fetchData () { + if (!this.loading) { + this.loading = true + this.error = false + fetch(this.$props, this.$store) + .then(() => { + this.loading = false + }) + .catch(() => { + this.error = true + this.loading = false + }) + } + } + }, + render (h) { + if (!this.error && !this.loading) { + const props = { + props: { + ...this.$props, + [childPropName]: this.fetchedData + }, + on: this.$listeners, + scopedSlots: this.$scopedSlots + } + const children = Object.entries(this.$slots).map(([key, value]) => h('template', { slot: key }, value)) + return ( +
+ + {children} + +
+ ) + } else { + return ( +
+ {this.error + ? {this.$t('general.generic_error')} + : + } +
+ ) + } + } + } +} + +export default withSubscription -- cgit v1.2.3-70-g09d2