From 76a2e6befb3aea6e890bb3c2e001a4635d05091a Mon Sep 17 00:00:00 2001
From: Henry Jameson <me@hjkos.com>
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 (
+          <div class="with-subscription">
+            <WrappedComponent {...props}>
+              {children}
+            </WrappedComponent>
+          </div>
+        )
+      } else {
+        return (
+          <div class="with-subscription-loading">
+            {this.error
+              ? <a onClick={this.fetchData} class="alert error">{this.$t('general.generic_error')}</a>
+              : <FAIcon spin icon="circle-notch"/>
+            }
+          </div>
+        )
+      }
+    }
+  }
+}
+
+export default withSubscription
-- 
cgit v1.2.3-70-g09d2

