diff options
Diffstat (limited to 'app/assets/javascripts/behaviors/markdown/render_json_table.js')
-rw-r--r-- | app/assets/javascripts/behaviors/markdown/render_json_table.js | 70 |
1 files changed, 70 insertions, 0 deletions
diff --git a/app/assets/javascripts/behaviors/markdown/render_json_table.js b/app/assets/javascripts/behaviors/markdown/render_json_table.js new file mode 100644 index 00000000000..4d9ac1d266b --- /dev/null +++ b/app/assets/javascripts/behaviors/markdown/render_json_table.js @@ -0,0 +1,70 @@ +import { memoize } from 'lodash'; +import Vue from 'vue'; +import { __ } from '~/locale'; +import { createAlert } from '~/flash'; + +// Async import component since we might not need it... +const JSONTable = memoize(() => + import(/* webpackChunkName: 'gfm_json_table' */ '../components/json_table.vue'), +); + +const mountParseError = (element) => { + // Let the error container be a sibling to the element. + // Otherwise, dismissing the alert causes the copy button to be misplaced. + const container = document.createElement('div'); + element.insertAdjacentElement('beforebegin', container); + + // We need to create a child element with a known selector for `createAlert` + const el = document.createElement('div'); + el.classList.add('js-json-table-error'); + + container.insertAdjacentElement('afterbegin', el); + + return createAlert({ + message: __('Unable to parse JSON'), + variant: 'warning', + parent: container, + containerSelector: '.js-json-table-error', + }); +}; + +const mountJSONTableVueComponent = (userData, element) => { + const { fields = [], items = [], filter, caption } = userData; + + const container = document.createElement('div'); + element.innerHTML = ''; + element.appendChild(container); + + return new Vue({ + el: container, + render(h) { + return h(JSONTable, { + props: { + fields, + items, + hasFilter: filter, + caption, + }, + }); + }, + }); +}; + +const renderTable = (element) => { + // Avoid rendering multiple times + if (!element || element.classList.contains('js-json-table')) { + return; + } + + element.classList.add('js-json-table'); + + try { + mountJSONTableVueComponent(JSON.parse(element.textContent), element); + } catch (e) { + mountParseError(element); + } +}; + +export const renderJSONTable = (elements) => { + elements.forEach(renderTable); +}; |