summaryrefslogtreecommitdiff
path: root/app/assets/javascripts/ensure_data.js
blob: 5b4d1afc9d0ec9261086ad9a0d28ed98fa45bbab (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
import emptySvg from '@gitlab/svgs/dist/illustrations/security-dashboard-empty-state.svg';
import { GlEmptyState } from '@gitlab/ui';
import * as Sentry from '@sentry/browser';
import { __ } from '~/locale';

const ERROR_FETCHING_DATA_HEADER = __('Could not get the data properly');
const ERROR_FETCHING_DATA_DESCRIPTION = __(
  'Please try and refresh the page. If the problem persists please contact support.',
);

/**
 * This function takes a Component and extends it with data from the `parseData` function.
 * The data will be made available through `props` and `proivde`.
 * If the `parseData` throws, the `GlEmptyState` will be returned.
 * @param  {Component} Component a component to render
 * @param  {Object} options
 * @param  {Function} options.parseData a function to parse `data`
 * @param  {Object} options.data an object to pass to `parseData`
 * @param  {Boolean} options.shouldLog to tell whether to log any thrown error by `parseData` to Sentry
 * @param  {Object} options.props to override passed `props` data
 * @param  {Object} options.provide to override passed `provide` data
 * @param  {*} ...options the remaining options will be passed as properties to `createElement`
 * @return {Component} a Vue component to render, either the GlEmptyState or the extended Component
 */
export default function ensureData(Component, options = {}) {
  const { parseData, data, shouldLog = false, props, provide, ...rest } = options;
  try {
    const parsedData = parseData(data);
    return {
      provide: { ...parsedData, ...provide },
      render(createElement) {
        return createElement(Component, {
          props: { ...parsedData, ...props },
          ...rest,
        });
      },
    };
  } catch (error) {
    if (shouldLog) {
      Sentry.captureException(error);
    }

    return {
      functional: true,
      render(createElement) {
        return createElement(GlEmptyState, {
          props: {
            title: ERROR_FETCHING_DATA_HEADER,
            description: ERROR_FETCHING_DATA_DESCRIPTION,
            svgPath: `data:image/svg+xml;utf8,${encodeURIComponent(emptySvg)}`,
          },
        });
      },
    };
  }
}