|
11 | 11 | * or submit itself to any jurisdiction. |
12 | 12 | */ |
13 | 13 |
|
14 | | -import { h } from '/js/src/index.js'; |
| 14 | +import { h, iconPlus, iconMinus } from '/js/src/index.js'; |
15 | 15 |
|
16 | 16 | /** |
17 | 17 | * Renders a single row with content |
18 | 18 | * @param {Object} value The key value potentially containing a formatter function |
19 | 19 | * @param {String} text The content text |
| 20 | + * @param {String} rowId The current rowId |
| 21 | + * @param {Object} model The global model object |
20 | 22 | * @return {vnode} A single table cell containing (formatted) text |
21 | 23 | */ |
22 | | -const row = (value, text) => { |
23 | | - const formatted = value && value.format ? value.format(text) : text; |
24 | | - return h('td#', formatted); |
| 24 | +const row = (value, text, rowId, model) => { |
| 25 | + const formattedText = value && value.format ? value.format(text) : text; |
| 26 | + |
| 27 | + const columnId = `${rowId}-${value.name.toLowerCase()}`; |
| 28 | + const canExpand = model.logs.canColumnExpand(rowId, value.name); |
| 29 | + const isExpanded = model.logs.isColumnExpanded(rowId, value.name); |
| 30 | + const base = `.${value.size}#${columnId}`; |
| 31 | + |
| 32 | + return h(`td${base}`, { |
| 33 | + onupdate: () => { |
| 34 | + if (value.expand) { |
| 35 | + const element = model.document.getElementById(`${columnId}-text`); |
| 36 | + const minimalHeight = model.logs.getMinimalColumnHeight(rowId, value.name); |
| 37 | + const shouldCollapse = element.scrollHeight > minimalHeight || |
| 38 | + element.scrollHeight > element.offsetHeight; |
| 39 | + if (!canExpand && shouldCollapse) { |
| 40 | + model.logs.addCollapsableColumn(rowId, value.name, element.offsetHeight); |
| 41 | + } else if (canExpand && element.scrollHeight <= minimalHeight) { |
| 42 | + model.logs.disableCollapsableColumn(rowId, value.name); |
| 43 | + } |
| 44 | + } |
| 45 | + }, |
| 46 | + onclick: canExpand ? (e) => e.stopPropagation() : null, |
| 47 | + }, [ |
| 48 | + h('.flex-row.items-center', [ |
| 49 | + h(`div#${columnId}-text.overflow${isExpanded ? '.show-overflow' : ''}`, formattedText), |
| 50 | + value.expand && canExpand && |
| 51 | + h(`#${columnId}-${!isExpanded ? 'plus' : 'minus'}.${isExpanded ? 'danger' : 'primary'}`, { |
| 52 | + onclick: (e) => { |
| 53 | + e.stopPropagation(); |
| 54 | + model.logs.toggleCollapse(rowId, value.name); |
| 55 | + }, |
| 56 | + }, isExpanded |
| 57 | + ? h('.collapse-button', iconMinus()) |
| 58 | + : h('.flex-row', [h('.black', '...'), h('.collapse-button', iconPlus())])), |
| 59 | + ]), |
| 60 | + ]); |
25 | 61 | }; |
26 | 62 |
|
27 | 63 | /** |
28 | 64 | * Renders a list of rows with content |
29 | 65 | * @param {Array} data The full collection of API data corresponding to the keys |
30 | 66 | * @param {Object} keys The full collection of API keys and their corresponding header values |
31 | 67 | * @param {Function} params Additional element parameters, wrapped in a function |
| 68 | + * @param {Object} model The global model object |
32 | 69 | * @return {vnode} A filled array of rows based on the given data and keys |
33 | 70 | */ |
34 | | -const content = (data, keys, params) => { |
| 71 | +const content = (data, keys, params, model) => { |
35 | 72 | const idKey = Object.keys(keys).find((key) => keys[key] && keys[key].primary); |
36 | | - return h('tbody', data.map((entry) => |
37 | | - h(`tr#row${entry[idKey]}`, params(entry), Object.entries(keys).map(([key, value]) => row(value, entry[key]))))); |
| 73 | + |
| 74 | + return h('tbody', data.map((entry) => { |
| 75 | + const rowId = `row${entry[idKey]}`; |
| 76 | + return h(`tr#${rowId}`, params(entry), Object.entries(keys) |
| 77 | + .map(([key, value]) => row(value, entry[key], rowId, model))); |
| 78 | + })); |
38 | 79 | }; |
39 | 80 |
|
40 | 81 | export default content; |
0 commit comments