Commit 2bf3b324 authored by Dave Pisek's avatar Dave Pisek

Refactor based no review feedback

Moves the logic of transforming the table-data into utils so
it follows the pattern used with the other components.

Adds specs and js-doc comments to explain the logic.
parent 3f4feeba
...@@ -17,33 +17,12 @@ export default { ...@@ -17,33 +17,12 @@ export default {
required: true, required: true,
}, },
}, },
computed: {
fields() {
const addKey = (headerItem, index) => ({
...headerItem,
key: this.getKeyForIndex(index),
});
return this.header.map(addKey);
},
items() {
const getCellEntry = (cell, index) => [this.getKeyForIndex(index), cell];
const cellsArrayToObject = (cells) => Object.fromEntries(cells.map(getCellEntry));
return this.rows.map(cellsArrayToObject);
},
},
methods: {
getKeyForIndex(index) {
return `column_${index}`;
},
},
}; };
</script> </script>
<template> <template>
<gl-table <gl-table
:items="items" :fields="header"
:fields="fields" :items="rows"
bordered bordered
borderless borderless
thead-class="gl-border-t-0 gl-border-b-solid gl-border-b-1 gl-border-b-gray-100" thead-class="gl-border-t-0 gl-border-b-solid gl-border-b-1 gl-border-b-gray-100"
......
...@@ -18,13 +18,21 @@ const isSupportedType = ({ type }) => Object.values(REPORT_TYPES).includes(type) ...@@ -18,13 +18,21 @@ const isSupportedType = ({ type }) => Object.values(REPORT_TYPES).includes(type)
const isOfType = (typeToCheck) => ({ type }) => type === typeToCheck; const isOfType = (typeToCheck) => ({ type }) => type === typeToCheck;
/** /**
* Check if the given report is of type list * Check if the given report is of type 'list'
* *
* @param {{ type: string } } reportItem * @param {{ type: string } } reportItem
* @returns boolean * @returns boolean
*/ */
export const isOfTypeList = isOfType(REPORT_TYPES.list); export const isOfTypeList = isOfType(REPORT_TYPES.list);
/**
* Check if the given report is of type 'table'
*
* @param {{ type: string } } reportItem
* @returns boolean
*/
const isOfTypeTable = isOfType(REPORT_TYPES.table);
/** /**
* Check if the given report is of type named-list * Check if the given report is of type named-list
* *
...@@ -122,6 +130,40 @@ const transformItemsIntoArray = (items) => { ...@@ -122,6 +130,40 @@ const transformItemsIntoArray = (items) => {
return Object.entries(items).map(([label, value]) => ({ ...value, label })); return Object.entries(items).map(([label, value]) => ({ ...value, label }));
}; };
/**
* Takes a report item's entry and transforms each item of type `table` in the following ways:
*
* 1. Adds a index-based key to each header-item (eg.: ` { key: column_0, ...headerData }`)
* 2. Transforms each item within the `rows` array into an object where each item's key corresponds
* to it's header's key
* (e.g: `rows: [
* [{ column_0: {...cellData }}]
* ]`)
*
* This prepares the data to be rendered into a table.
*
* @param [String, {*}] report entry
* @returns [String, {*}]
*/
const transformTableItems = ([label, item]) => {
const newItem = isOfTypeTable(item)
? {
...item,
header: item.header.map((headerItem, index) => ({
...headerItem,
key: `column_${index}`,
})),
rows: item.rows.map((row) => {
const getCellEntry = (cell, index) => [`column_${index}`, cell];
// transforms the array into an object with `column_N` as keys
return Object.fromEntries(row.map(getCellEntry));
}),
}
: item;
return [label, newItem];
};
/** /**
* Takes a vulnerabilities details object - containing generic report data * Takes a vulnerabilities details object - containing generic report data
* Returns a copy of the report data with the following items being filtered: * Returns a copy of the report data with the following items being filtered:
...@@ -143,6 +185,7 @@ export const filterTypesAndLimitListDepth = (data, { maxDepth = 5 } = {}) => { ...@@ -143,6 +185,7 @@ export const filterTypesAndLimitListDepth = (data, { maxDepth = 5 } = {}) => {
flow([ flow([
filterNestedListsItems(filterCriteria), filterNestedListsItems(filterCriteria),
overEveryNamedListItem(flow([filterTypesAndLimitListDepth, transformItemsIntoArray])), overEveryNamedListItem(flow([filterTypesAndLimitListDepth, transformItemsIntoArray])),
transformTableItems,
]), ]),
); );
......
...@@ -6,8 +6,12 @@ import Table from 'ee/vulnerabilities/components/generic_report/types/table.vue' ...@@ -6,8 +6,12 @@ import Table from 'ee/vulnerabilities/components/generic_report/types/table.vue'
import { extendedWrapper } from 'helpers/vue_test_utils_helper'; import { extendedWrapper } from 'helpers/vue_test_utils_helper';
const TEST_DATA = { const TEST_DATA = {
header: [{ type: REPORT_TYPES.text, value: 'foo ' }], header: [{ key: 'column_1', type: REPORT_TYPES.text, value: 'foo ' }],
rows: [[{ type: REPORT_TYPES.url, href: 'bar' }]], rows: [
{
column_1: { type: REPORT_TYPES.url, href: 'bar' },
},
],
}; };
describe('ee/vulnerabilities/components/generic_report/types/table.vue', () => { describe('ee/vulnerabilities/components/generic_report/types/table.vue', () => {
...@@ -50,7 +54,7 @@ describe('ee/vulnerabilities/components/generic_report/types/table.vue', () => { ...@@ -50,7 +54,7 @@ describe('ee/vulnerabilities/components/generic_report/types/table.vue', () => {
it('renders a table cell containing the given report type', () => { it('renders a table cell containing the given report type', () => {
expect(findTableBody().findComponent(ReportItem).props('item')).toMatchObject( expect(findTableBody().findComponent(ReportItem).props('item')).toMatchObject(
TEST_DATA.rows[0][0], TEST_DATA.rows[0].column_1,
); );
}); });
}); });
...@@ -49,6 +49,19 @@ const TEST_DATA = { ...@@ -49,6 +49,19 @@ const TEST_DATA = {
unsupported: { type: MOCK_REPORT_TYPE_UNSUPPORTED }, unsupported: { type: MOCK_REPORT_TYPE_UNSUPPORTED },
}, },
}, },
table: {
type: REPORT_TYPES.table,
header: [
{ type: REPORT_TYPES.text, value: 'foo ' },
{ type: REPORT_TYPES.text, value: 'bar ' },
],
rows: [
[
{ type: REPORT_TYPES.text, value: 'foo' },
{ type: REPORT_TYPES.text, value: 'bar' },
],
],
},
}; };
describe('ee/vulnerabilities/components/generic_report/types/utils', () => { describe('ee/vulnerabilities/components/generic_report/types/utils', () => {
...@@ -94,5 +107,20 @@ describe('ee/vulnerabilities/components/generic_report/types/utils', () => { ...@@ -94,5 +107,20 @@ describe('ee/vulnerabilities/components/generic_report/types/utils', () => {
]); ]);
}); });
}); });
describe('with tables', () => {
const filteredData = filterTypesAndLimitListDepth(TEST_DATA);
it('adds a key to each header item', () => {
expect(filteredData.table.header).toMatchObject([{ key: 'column_0' }, { key: 'column_1' }]);
});
it(`transforms the "rows" array into an object with it's keys corresponding to the header keys`, () => {
expect(filteredData.table.rows[0]).toMatchObject({
column_0: TEST_DATA.table.rows[0][0],
column_1: TEST_DATA.table.rows[0][1],
});
});
});
}); });
}); });
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment