diff --git a/src/components/Widgets/WidgetBase.vue b/src/components/Widgets/WidgetBase.vue index 39582b25..3b810030 100644 --- a/src/components/Widgets/WidgetBase.vue +++ b/src/components/Widgets/WidgetBase.vue @@ -319,7 +319,10 @@ export default { }, /* Returns users specified widget options, or empty object */ widgetOptions() { - return this.widget.options || {}; + const options = this.widget.options || {}; + const useProxy = !!this.widget.useProxy; + const updateInterval = this.widget.updateInterval || 0; + return { useProxy, updateInterval, ...options }; }, /* A unique string to reference the widget by */ widgetRef() { diff --git a/src/mixins/WidgetMixin.js b/src/mixins/WidgetMixin.js index fc0fd956..ef35644c 100644 --- a/src/mixins/WidgetMixin.js +++ b/src/mixins/WidgetMixin.js @@ -2,8 +2,10 @@ * Mixin that all pre-built and custom widgets extend from. * Manages loading state, error handling, data updates and user options */ +import axios from 'axios'; import ProgressBar from 'rsup-progress'; import ErrorHandler from '@/utils/ErrorHandler'; +import { serviceEndpoints } from '@/utils/defaults'; const WidgetMixin = { props: { @@ -19,6 +21,15 @@ const WidgetMixin = { mounted() { this.fetchData(); }, + computed: { + proxyReqEndpoint() { + const baseUrl = process.env.VUE_APP_DOMAIN || window.location.origin; + return `${baseUrl}${serviceEndpoints.corsProxy}`; + }, + useProxy() { + return this.options.useProxy; + }, + }, methods: { /* Re-fetches external data, called by parent. Usually overridden by widget */ update() { @@ -44,9 +55,31 @@ const WidgetMixin = { fetchData() { this.finishLoading(); }, + /* Used as v-tooltip, pass text content in, and will show on hover */ tooltip(content) { return { content, trigger: 'hover focus', delay: 250 }; }, + /* Makes data request, returns promise */ + makeRequest(endpoint, options = {}) { + // Request Options + const method = 'GET'; + const url = this.useProxy ? this.proxyReqEndpoint : endpoint; + const headers = this.useProxy ? { 'Target-URL': endpoint, ...options } : options; + // Make request + return new Promise((resolve, reject) => { + axios.request({ method, url, headers }) + .then((response) => { + resolve(response.data); + }) + .catch((dataFetchError) => { + this.error('Unable to fetch data', dataFetchError); + reject(dataFetchError); + }) + .finally(() => { + this.finishLoading(); + }); + }); + }, }, };