From 7a19911ac065410cf47bc56810d272d58c0f5115 Mon Sep 17 00:00:00 2001 From: Nicolas Staub Date: Thu, 3 Dec 2020 11:31:44 +0100 Subject: [PATCH 01/29] Use array.every() for getting minibar-types #108 --- .vscode/launch.json | 2 +- helpers/minibars.js | 14 ++++------- package-lock.json | 58 ++++++++++++++++++++++----------------------- package.json | 12 +++++----- 4 files changed, 40 insertions(+), 46 deletions(-) diff --git a/.vscode/launch.json b/.vscode/launch.json index f656c509..c905eef1 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -3,7 +3,7 @@ // Hover to view descriptions of existing attributes. // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 "version": "0.2.0", - "configurations": [ + "configurations": [ { "type": "node", "request": "launch", diff --git a/helpers/minibars.js b/helpers/minibars.js index 151bf028..f2e0e9be 100644 --- a/helpers/minibars.js +++ b/helpers/minibars.js @@ -13,10 +13,6 @@ function getMinibarNumbersWithType(data, selectedColumnIndex) { items: [], numbers: [] }; - let typeAmount = { - positives: 0, - negatives: 0 - }; let dataCopy = clone(data); dataCopy[0] = dataCopy[0].map(cell => (cell = "")); // first row is always header so ignore it @@ -26,10 +22,8 @@ function getMinibarNumbersWithType(data, selectedColumnIndex) { if (cell < 0) { type = miniBarTypes.negative; - typeAmount.negatives++; } else if (cell > 0) { type = miniBarTypes.positive; - typeAmount.positives++; } else { type = miniBarTypes.empty; } @@ -42,7 +36,7 @@ function getMinibarNumbersWithType(data, selectedColumnIndex) { } }); - minibarsWithType.type = getMinibarType(typeAmount); + minibarsWithType.type = getMinibarType(minibarsWithType.numbers); return minibarsWithType; } @@ -94,10 +88,10 @@ function getMinibarValue(type, value, min, max) { } } -function getMinibarType(types) { - if (types.positives > 0 && types.negatives === 0) { +function getMinibarType(numbers) { + if (numbers.every(n => {return n > 0;})) { return miniBarTypes.positive; - } else if (types.negatives > 0 && types.positives === 0) { + } else if (numbers.every(n => {return n < 0;})) { return miniBarTypes.negative; } else { return miniBarTypes.mixed; diff --git a/package-lock.json b/package-lock.json index fe408ce4..ed0ca9bf 100644 --- a/package-lock.json +++ b/package-lock.json @@ -327,16 +327,16 @@ "integrity": "sha512-EwaJS7RjoXUZ2cXXKZZxZqieGtc7RbvQhUy8FwDoMQtxWVi14tFjeFCYPZAM1mBCpOpiBpyaZbb9NeHc7eGKgw==" }, "@hapi/inert": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/@hapi/inert/-/inert-6.0.2.tgz", - "integrity": "sha512-cq0a8jstkLW1+oJaw4jp52PZBEkVbX9d0YDy5aOs3rOKYSjpzs2nQBahnCHEMchOrOSUffLpE+IDoivYHcx8uA==", + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/@hapi/inert/-/inert-6.0.3.tgz", + "integrity": "sha512-Z6Pi0Wsn2pJex5CmBaq+Dky9q40LGzXLUIUFrYpDtReuMkmfy9UuUeYc4064jQ1Xe9uuw7kbwE6Fq6rqKAdjAg==", "requires": { "@hapi/ammo": "5.x.x", "@hapi/boom": "9.x.x", "@hapi/bounce": "2.x.x", "@hapi/hoek": "9.x.x", "@hapi/validate": "1.x.x", - "lru-cache": "5.x.x" + "lru-cache": "^6.0.0" } }, "@hapi/iron": { @@ -692,9 +692,9 @@ "dev": true }, "ajv": { - "version": "6.12.3", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.3.tgz", - "integrity": "sha512-4K0cK3L1hsqk9xIb2z9vs/XU+PGJZ9PNpJRDS9YLzmNdX6jmVPfamLvTJr0aDAusnHyCHO6MjzlkAsgtqp9teA==", + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "requires": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", @@ -1385,9 +1385,9 @@ } }, "d3-format": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/d3-format/-/d3-format-1.4.4.tgz", - "integrity": "sha512-TWks25e7t8/cqctxCmxpUuzZN11QxIA7YrMbram94zMQ0PXjE4LVIMe/f6a4+xxL8HQ3OsAFULOINQi1pE62Aw==" + "version": "1.4.5", + "resolved": "https://registry.npmjs.org/d3-format/-/d3-format-1.4.5.tgz", + "integrity": "sha512-J0piedu6Z8iB6TbIGfZgDzfXxUFN3qQRMofy2oPdXzQibYGqPB/9iMcxr/TGalU+2RsyDO+U4f33id8tbnSRMQ==" }, "dashdash": { "version": "1.14.1", @@ -2536,11 +2536,11 @@ "dev": true }, "lru-cache": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", - "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", "requires": { - "yallist": "^3.0.2" + "yallist": "^4.0.0" } }, "mdn-data": { @@ -2869,9 +2869,9 @@ "dev": true }, "postcss": { - "version": "7.0.32", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.32.tgz", - "integrity": "sha512-03eXong5NLnNCD05xscnGKGDZ98CyzoqPSMjOe6SuoQY7Z2hIj0Ld1g/O/UQRuOle2aRtiIRDg9tDcTGAkLfKw==", + "version": "7.0.35", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.35.tgz", + "integrity": "sha512-3QT8bBJeX/S5zKTTjTCIjRF3If4avAT6kqxcASlTWEtAFCb9NH0OUxNDfgZSWdP5fJnBYCMEWkIFfWeugjzYMg==", "dev": true, "requires": { "chalk": "^2.4.2", @@ -3469,9 +3469,9 @@ "dev": true }, "sass": { - "version": "1.26.10", - "resolved": "https://registry.npmjs.org/sass/-/sass-1.26.10.tgz", - "integrity": "sha512-bzN0uvmzfsTvjz0qwccN1sPm2HxxpNI/Xa+7PlUEMS+nQvbyuEK7Y0qFqxlPHhiNHb1Ze8WQJtU31olMObkAMw==", + "version": "1.29.0", + "resolved": "https://registry.npmjs.org/sass/-/sass-1.29.0.tgz", + "integrity": "sha512-ZpwAUFgnvAUCdkjwPREny+17BpUj8nh5Yr6zKPGtLNTLrmtoRYIjm7njP24COhjJldjwW1dcv52Lpf4tNZVVRA==", "dev": true, "requires": { "chokidar": ">=2.0.0 <4.0.0" @@ -3865,9 +3865,9 @@ "dev": true }, "uglify-js": { - "version": "3.10.1", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.10.1.tgz", - "integrity": "sha512-RjxApKkrPJB6kjJxQS3iZlf///REXWYxYJxO/MpmlQzVkDWVI3PSnCBWezMecmTU/TRkNxrl8bmsfFQCp+LO+Q==" + "version": "3.12.1", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.12.1.tgz", + "integrity": "sha512-o8lHP20KjIiQe5b/67Rh68xEGRrc2SRsCuuoYclXXoC74AfSRGblU1HKzJWH3HxPZ+Ort85fWHpSX7KwBUC9CQ==" }, "uniq": { "version": "1.0.1", @@ -3894,9 +3894,9 @@ "dev": true }, "uri-js": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", - "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.0.tgz", + "integrity": "sha512-B0yRTzYdUCCn9n+F4+Gh4yIDtMQcaJsmYBDsTSG8g/OejKBodLQ2IHfN3bM7jUsRXndopT7OIXWdYqc1fjmV6g==", "requires": { "punycode": "^2.1.0" } @@ -4059,9 +4059,9 @@ "dev": true }, "yallist": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==" + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" } } } diff --git a/package.json b/package.json index b1215224..b41d8afc 100644 --- a/package.json +++ b/package.json @@ -13,14 +13,14 @@ "dependencies": { "@hapi/boom": "^9.1.0", "@hapi/hapi": "^19.2.0", - "@hapi/inert": "^6.0.2", + "@hapi/inert": "^6.0.3", "@hapi/joi": "^17.1.1", - "ajv": "^6.12.3", + "ajv": "^6.12.6", "array2d": "0.0.5", "clone": "^2.1.2", - "d3-format": "^1.4.4", + "d3-format": "^1.4.5", "nunjucks": "^3.2.2", - "uglify-js": "^3.10.1" + "uglify-js": "^3.12.1" }, "devDependencies": { "@hapi/code": "^8.0.2", @@ -29,8 +29,8 @@ "cssnano": "^4.1.10", "html-minifier": "^4.0.0", "jsdom": "^16.4.0", - "postcss": "^7.0.32", + "postcss": "^7.0.35", "postcss-import": "^12.0.1", - "sass": "^1.26.10" + "sass": "^1.29.0" } } From bf6a52320f21d2dca8b3f8271fd58d44b43fe909 Mon Sep 17 00:00:00 2001 From: Nicolas Staub Date: Thu, 3 Dec 2020 11:39:22 +0100 Subject: [PATCH 02/29] Fix format issue --- .vscode/launch.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.vscode/launch.json b/.vscode/launch.json index c905eef1..f656c509 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -3,7 +3,7 @@ // Hover to view descriptions of existing attributes. // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 "version": "0.2.0", - "configurations": [ + "configurations": [ { "type": "node", "request": "launch", From 4f106a70bc947beb1b46294218d84b4091bb6ac6 Mon Sep 17 00:00:00 2001 From: Philip Kueng Date: Mon, 7 Dec 2020 11:00:30 +0100 Subject: [PATCH 03/29] Use array.every() for getting minibar-types --- helpers/minibars.js | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/helpers/minibars.js b/helpers/minibars.js index 151bf028..f2e0e9be 100644 --- a/helpers/minibars.js +++ b/helpers/minibars.js @@ -13,10 +13,6 @@ function getMinibarNumbersWithType(data, selectedColumnIndex) { items: [], numbers: [] }; - let typeAmount = { - positives: 0, - negatives: 0 - }; let dataCopy = clone(data); dataCopy[0] = dataCopy[0].map(cell => (cell = "")); // first row is always header so ignore it @@ -26,10 +22,8 @@ function getMinibarNumbersWithType(data, selectedColumnIndex) { if (cell < 0) { type = miniBarTypes.negative; - typeAmount.negatives++; } else if (cell > 0) { type = miniBarTypes.positive; - typeAmount.positives++; } else { type = miniBarTypes.empty; } @@ -42,7 +36,7 @@ function getMinibarNumbersWithType(data, selectedColumnIndex) { } }); - minibarsWithType.type = getMinibarType(typeAmount); + minibarsWithType.type = getMinibarType(minibarsWithType.numbers); return minibarsWithType; } @@ -94,10 +88,10 @@ function getMinibarValue(type, value, min, max) { } } -function getMinibarType(types) { - if (types.positives > 0 && types.negatives === 0) { +function getMinibarType(numbers) { + if (numbers.every(n => {return n > 0;})) { return miniBarTypes.positive; - } else if (types.negatives > 0 && types.positives === 0) { + } else if (numbers.every(n => {return n < 0;})) { return miniBarTypes.negative; } else { return miniBarTypes.mixed; From ebdd366439c0788f46546630bf29d4099e7c511a Mon Sep 17 00:00:00 2001 From: Nicolas Staub Date: Mon, 7 Dec 2020 11:28:34 +0100 Subject: [PATCH 04/29] Add searchbox --- helpers/renderingInfoScript.js | 81 +++++++++++++++++++++++++++++++++- routes/rendering-info/web.js | 3 ++ 2 files changed, 83 insertions(+), 1 deletion(-) diff --git a/helpers/renderingInfoScript.js b/helpers/renderingInfoScript.js index 08c0ea95..f354f0a4 100644 --- a/helpers/renderingInfoScript.js +++ b/helpers/renderingInfoScript.js @@ -217,9 +217,88 @@ function getMinibarsScript(context) { `; } +function getSearchTextBoxScript(context) { + const dataObject = `window.${context.id}Data`; + const searchTextBoxCreateElement = `searchTextBoxCreateElement${context.id}`; + const searchTextBoxHideRows = `searchTextBoxHideRows${context.id}`; + const searchTextBoxShowRows = `searchTextBoxShowRows${context.id}`; + + return ` + function ${searchTextBoxHideRows}() { + ${dataObject}.showMoreButtonElement.style.display = ''; + + ${dataObject}.tableElement.querySelectorAll('tbody tr').forEach(function(rowElement, index) { + if (index >= (${dataObject}.numberOfRows - ${dataObject}.numberOfRowsToHide)) { + rowElement.classList.remove('q-table-state-visible'); + rowElement.classList.add('q-table-state-hidden'); + } + }); + ${dataObject}.showMoreButtonElement.textContent = 'Alle ' + ${dataObject}.numberOfRows + ' anzeigen'; + ${dataObject}.rowVisibilityState = 'hidden'; + } + + function ${searchTextBoxShowRows}() { + ${dataObject}.showMoreButtonElement.style.display = 'none'; + + ${dataObject}.tableElement.querySelectorAll('tbody tr').forEach(function(rowElement, index) { + rowElement.classList.remove('q-table-state-hidden'); + rowElement.classList.add('q-table-state-visible'); + }); + ${dataObject}.showMoreButtonElement.textContent = "Tabelle zuklappen"; + ${dataObject}.rowVisibilityState = 'visible'; + } + + function ${searchTextBoxCreateElement}() { + // If there is no ShowMoreButton, don't add the search box + if (${dataObject}.showMoreButtonElement === undefined) return; + + // Create the SearchTextBox + ${dataObject}.searchTextBoxElement = document.createElement('input'); + ${dataObject}.searchTextBoxElement.classList.add('s-input-field'); + ${dataObject}.searchTextBoxElement.setAttribute('type', 'search'); + ${dataObject}.searchTextBoxElement.setAttribute('placeholder', 'Bitte Suche eingeben'); + ${dataObject}.element.insertBefore(${dataObject}.searchTextBoxElement, ${dataObject}.element.querySelector(".s-q-item__subtitle").nextSibling); + + ${dataObject}.searchTextBoxElement.addEventListener('input', function(event) { + var filter = event.target.value.toUpperCase(); + + if (filter.length == 0) { + // No filter = show only x rows + ${searchTextBoxHideRows}(); + return; + } else if (filter.length == 1) { + // 1 char typed = show all rows + ${searchTextBoxShowRows}(); + return; + } + + // More than 1 char typed = start filtering! + ${dataObject}.tableElement.querySelectorAll('tbody tr .q-table__cell--text').forEach( + function(cellElement, index) { + txtValue = cellElement.innerText.toUpperCase(); + + if (txtValue.indexOf(filter) > -1) { + cellElement.parentElement.classList.remove('q-table-state-hidden'); + cellElement.parentElement.classList.add('q-table-state-visible'); + } else { + cellElement.parentElement.classList.remove('q-table-state-visible'); + cellElement.parentElement.classList.add('q-table-state-hidden'); + } + } + ); + }); + } + + window.q_domready.then(function() { + ${searchTextBoxCreateElement}(); + }); + `; +} + module.exports = { getDefaultScript: getDefaultScript, getCardLayoutScript: getCardLayoutScript, getShowMoreButtonScript: getShowMoreButtonScript, - getMinibarsScript: getMinibarsScript + getMinibarsScript: getMinibarsScript, + getSearchTextBoxScript: getSearchTextBoxScript }; diff --git a/routes/rendering-info/web.js b/routes/rendering-info/web.js index 0b3b782a..66fa93d7 100644 --- a/routes/rendering-info/web.js +++ b/routes/rendering-info/web.js @@ -199,6 +199,9 @@ module.exports = { renderingInfo.scripts.push({ content: renderingInfoScripts.getShowMoreButtonScript(context), }); + renderingInfo.scripts.push({ + content: renderingInfoScripts.getSearchTextBoxScript(context), + }); } if (Object.keys(context.minibar).length !== 0) { From e405be463d5c23b1f2a3cc02ebb7a4a405d15574 Mon Sep 17 00:00:00 2001 From: Nicolas Staub Date: Mon, 7 Dec 2020 12:14:02 +0100 Subject: [PATCH 05/29] change variable name --- helpers/minibars.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/helpers/minibars.js b/helpers/minibars.js index f2e0e9be..e2bbc72d 100644 --- a/helpers/minibars.js +++ b/helpers/minibars.js @@ -89,9 +89,9 @@ function getMinibarValue(type, value, min, max) { } function getMinibarType(numbers) { - if (numbers.every(n => {return n > 0;})) { + if (numbers.every(number => {return number > 0;})) { return miniBarTypes.positive; - } else if (numbers.every(n => {return n < 0;})) { + } else if (numbers.every(number => {return number < 0;})) { return miniBarTypes.negative; } else { return miniBarTypes.mixed; From 5039c97be1807c3f67d40bd3703aa0ba63b4a660 Mon Sep 17 00:00:00 2001 From: Nicolas Staub Date: Fri, 11 Dec 2020 17:32:56 +0100 Subject: [PATCH 06/29] add test and fixture data for table search #144 --- .../fixtures/data/table-search-hidden.json | 442 ++++++++++++++++++ .../fixtures/data/table-search-show.json | 442 ++++++++++++++++++ routes/fixtures/data.js | 2 + tasks/updateFixtureData.js | 8 + test/dom-tests.js | 36 ++ test/e2e-tests.js | 4 +- 6 files changed, 932 insertions(+), 2 deletions(-) create mode 100644 resources/fixtures/data/table-search-hidden.json create mode 100644 resources/fixtures/data/table-search-show.json diff --git a/resources/fixtures/data/table-search-hidden.json b/resources/fixtures/data/table-search-hidden.json new file mode 100644 index 00000000..cc3c82d5 --- /dev/null +++ b/resources/fixtures/data/table-search-hidden.json @@ -0,0 +1,442 @@ +{ + "title": "FIXTURE: table search hide", + "data": { + "table": [ + [ + "Country", + "Number" + ], + [ + "Somalia", + "-0.1459" + ], + [ + "Honduras", + "0.2758" + ], + [ + "Malawi", + "-0.0534" + ], + [ + "Comoros", + "0.0111" + ], + [ + "Greece", + "-0.1775" + ], + [ + "Turkmenistan", + "0.0803" + ], + [ + "Panama", + "0.0164" + ], + [ + "Austria", + "-0.0462" + ], + [ + "Saint Barthélemy", + "-0.0247" + ], + [ + "Kazakhstan", + "-0.0067" + ], + [ + "Azerbaijan", + "0.044" + ], + [ + "Netherlands", + "0.2486" + ], + [ + "Yemen", + "-0.106" + ], + [ + "Sint Maarten", + "0.4218" + ], + [ + "Svalbard and Jan Mayen Islands", + "-0.1107" + ], + [ + "Belarus", + "-0.4466" + ], + [ + "China", + "-0.4345" + ], + [ + "Congo (Brazzaville)", + "-0.1386" + ], + [ + "Belgium", + "-0.0206" + ], + [ + "Guam", + "-0.1694" + ], + [ + "Egypt", + "-0.3251" + ], + [ + "Turkmenistan", + "-0.0347" + ], + [ + "Vanuatu", + "0.0464" + ], + [ + "Mali", + "-0.4237" + ], + [ + "Slovenia", + "0.2262" + ], + [ + "Mongolia", + "-0.1295" + ], + [ + "Paraguay", + "0.39" + ], + [ + "Zambia", + "0.2487" + ], + [ + "Timor-Leste", + "0.3767" + ], + [ + "Singapore", + "0.0347" + ], + [ + "China", + "0.4352" + ], + [ + "Dominican Republic", + "0.032" + ], + [ + "Sint Maarten", + "0.0558" + ], + [ + "Iran", + "-0.2898" + ], + [ + "Azerbaijan", + "-0.4263" + ], + [ + "Isle of Man", + "0.0565" + ], + [ + "Trinidad and Tobago", + "0.0105" + ], + [ + "Malta", + "0.0858" + ], + [ + "Iraq", + "0.1162" + ], + [ + "Ghana", + "0.0011" + ], + [ + "Morocco", + "0.3071" + ], + [ + "Greece", + "-0.5361" + ], + [ + "Poland", + "0.2016" + ], + [ + "Bolivia", + "-0.7247" + ], + [ + "Anguilla", + "-0.1922" + ], + [ + "Saint Vincent and The Grenadines", + "0.0358" + ], + [ + "Tokelau", + "0.021" + ], + [ + "Chad", + "-0.1331" + ], + [ + "India", + "-0.0073" + ], + [ + "Tajikistan", + "0.1737" + ], + [ + "Saint Barthélemy", + "0.1724" + ], + [ + "Egypt", + "-0.5759" + ], + [ + "Nepal", + "0.2836" + ], + [ + "Saint Pierre and Miquelon", + "0.3836" + ], + [ + "Cyprus", + "0.253" + ], + [ + "Seychelles", + "-0.2235" + ], + [ + "Samoa", + "0.4766" + ], + [ + "Gibraltar", + "-0.5111" + ], + [ + "Georgia", + "-0.0481" + ], + [ + "Moldova", + "0.2778" + ], + [ + "United Arab Emirates", + "0.0571" + ], + [ + "Bonaire, Sint Eustatius and Saba", + "-0.0598" + ], + [ + "Mongolia", + "-0.1613" + ], + [ + "Maldives", + "-0.1707" + ], + [ + "Lebanon", + "-0.2072" + ], + [ + "Ethiopia", + "0.0483" + ], + [ + "Hungary", + "0.529" + ], + [ + "Slovakia", + "-0.0181" + ], + [ + "Afghanistan", + "-0.1582" + ], + [ + "Kyrgyzstan", + "-0.2432" + ], + [ + "Uganda", + "-0.3201" + ], + [ + "Malawi", + "-0.2205" + ], + [ + "Serbia", + "0.2737" + ], + [ + "Liberia", + "0.1353" + ], + [ + "Japan", + "0.5669" + ], + [ + "Mayotte", + "0.5685" + ], + [ + "Papua New Guinea", + "-0.1687" + ], + [ + "Curaçao", + "0.43" + ], + [ + "Mexico", + "0.2183" + ], + [ + "Myanmar", + "-0.0774" + ], + [ + "Puerto Rico", + "0.099" + ], + [ + "Martinique", + "-0.028" + ], + [ + "Tanzania", + "-0.0047" + ], + [ + "American Samoa", + "-0.5019" + ], + [ + "Saint Barthélemy", + "-0.2906" + ], + [ + "French Guiana", + "0.4136" + ], + [ + "Slovenia", + "0.2494" + ], + [ + "Somalia", + "0.2739" + ], + [ + "French Polynesia", + "-0.0177" + ], + [ + "Montserrat", + "0.1914" + ], + [ + "Syria", + "-0.0182" + ], + [ + "Ireland", + "-0.1243" + ], + [ + "Panama", + "-0.003" + ], + [ + "Pitcairn Islands", + "0.1128" + ], + [ + "Sint Maarten", + "-0.2559" + ], + [ + "Virgin Islands, British", + "0.1381" + ], + [ + "Saint Kitts and Nevis", + "0.1776" + ], + [ + "South Sudan", + "0.2227" + ], + [ + "Bahamas", + "-0.112" + ], + [ + "Kuwait", + "0.0461" + ] + ], + "metaData": { + "cells": [] + } + }, + "sources": [ + { + "link": {}, + "text": "The Very Important Center For Very Important Data" + } + ], + "options": { + "hideTableHeader": false, + "showTableSearch": false, + "cardLayout": false, + "cardLayoutIfSmall": true, + "minibar": { + "invertColors": false, + "barColor": { + "positive": { + "className": "", + "colorCode": "" + }, + "negative": { + "className": "", + "colorCode": "" + } + }, + "selectedColumn": null + } + }, + "tool": "table", + "subtitle": "Very important data country by country" + } \ No newline at end of file diff --git a/resources/fixtures/data/table-search-show.json b/resources/fixtures/data/table-search-show.json new file mode 100644 index 00000000..6e9a6370 --- /dev/null +++ b/resources/fixtures/data/table-search-show.json @@ -0,0 +1,442 @@ +{ + "title": "FIXTURE: table search show", + "data": { + "table": [ + [ + "Country", + "Number" + ], + [ + "Somalia", + "-0.1459" + ], + [ + "Honduras", + "0.2758" + ], + [ + "Malawi", + "-0.0534" + ], + [ + "Comoros", + "0.0111" + ], + [ + "Greece", + "-0.1775" + ], + [ + "Turkmenistan", + "0.0803" + ], + [ + "Panama", + "0.0164" + ], + [ + "Austria", + "-0.0462" + ], + [ + "Saint Barthélemy", + "-0.0247" + ], + [ + "Kazakhstan", + "-0.0067" + ], + [ + "Azerbaijan", + "0.044" + ], + [ + "Netherlands", + "0.2486" + ], + [ + "Yemen", + "-0.106" + ], + [ + "Sint Maarten", + "0.4218" + ], + [ + "Svalbard and Jan Mayen Islands", + "-0.1107" + ], + [ + "Belarus", + "-0.4466" + ], + [ + "China", + "-0.4345" + ], + [ + "Congo (Brazzaville)", + "-0.1386" + ], + [ + "Belgium", + "-0.0206" + ], + [ + "Guam", + "-0.1694" + ], + [ + "Egypt", + "-0.3251" + ], + [ + "Turkmenistan", + "-0.0347" + ], + [ + "Vanuatu", + "0.0464" + ], + [ + "Mali", + "-0.4237" + ], + [ + "Slovenia", + "0.2262" + ], + [ + "Mongolia", + "-0.1295" + ], + [ + "Paraguay", + "0.39" + ], + [ + "Zambia", + "0.2487" + ], + [ + "Timor-Leste", + "0.3767" + ], + [ + "Singapore", + "0.0347" + ], + [ + "China", + "0.4352" + ], + [ + "Dominican Republic", + "0.032" + ], + [ + "Sint Maarten", + "0.0558" + ], + [ + "Iran", + "-0.2898" + ], + [ + "Azerbaijan", + "-0.4263" + ], + [ + "Isle of Man", + "0.0565" + ], + [ + "Trinidad and Tobago", + "0.0105" + ], + [ + "Malta", + "0.0858" + ], + [ + "Iraq", + "0.1162" + ], + [ + "Ghana", + "0.0011" + ], + [ + "Morocco", + "0.3071" + ], + [ + "Greece", + "-0.5361" + ], + [ + "Poland", + "0.2016" + ], + [ + "Bolivia", + "-0.7247" + ], + [ + "Anguilla", + "-0.1922" + ], + [ + "Saint Vincent and The Grenadines", + "0.0358" + ], + [ + "Tokelau", + "0.021" + ], + [ + "Chad", + "-0.1331" + ], + [ + "India", + "-0.0073" + ], + [ + "Tajikistan", + "0.1737" + ], + [ + "Saint Barthélemy", + "0.1724" + ], + [ + "Egypt", + "-0.5759" + ], + [ + "Nepal", + "0.2836" + ], + [ + "Saint Pierre and Miquelon", + "0.3836" + ], + [ + "Cyprus", + "0.253" + ], + [ + "Seychelles", + "-0.2235" + ], + [ + "Samoa", + "0.4766" + ], + [ + "Gibraltar", + "-0.5111" + ], + [ + "Georgia", + "-0.0481" + ], + [ + "Moldova", + "0.2778" + ], + [ + "United Arab Emirates", + "0.0571" + ], + [ + "Bonaire, Sint Eustatius and Saba", + "-0.0598" + ], + [ + "Mongolia", + "-0.1613" + ], + [ + "Maldives", + "-0.1707" + ], + [ + "Lebanon", + "-0.2072" + ], + [ + "Ethiopia", + "0.0483" + ], + [ + "Hungary", + "0.529" + ], + [ + "Slovakia", + "-0.0181" + ], + [ + "Afghanistan", + "-0.1582" + ], + [ + "Kyrgyzstan", + "-0.2432" + ], + [ + "Uganda", + "-0.3201" + ], + [ + "Malawi", + "-0.2205" + ], + [ + "Serbia", + "0.2737" + ], + [ + "Liberia", + "0.1353" + ], + [ + "Japan", + "0.5669" + ], + [ + "Mayotte", + "0.5685" + ], + [ + "Papua New Guinea", + "-0.1687" + ], + [ + "Curaçao", + "0.43" + ], + [ + "Mexico", + "0.2183" + ], + [ + "Myanmar", + "-0.0774" + ], + [ + "Puerto Rico", + "0.099" + ], + [ + "Martinique", + "-0.028" + ], + [ + "Tanzania", + "-0.0047" + ], + [ + "American Samoa", + "-0.5019" + ], + [ + "Saint Barthélemy", + "-0.2906" + ], + [ + "French Guiana", + "0.4136" + ], + [ + "Slovenia", + "0.2494" + ], + [ + "Somalia", + "0.2739" + ], + [ + "French Polynesia", + "-0.0177" + ], + [ + "Montserrat", + "0.1914" + ], + [ + "Syria", + "-0.0182" + ], + [ + "Ireland", + "-0.1243" + ], + [ + "Panama", + "-0.003" + ], + [ + "Pitcairn Islands", + "0.1128" + ], + [ + "Sint Maarten", + "-0.2559" + ], + [ + "Virgin Islands, British", + "0.1381" + ], + [ + "Saint Kitts and Nevis", + "0.1776" + ], + [ + "South Sudan", + "0.2227" + ], + [ + "Bahamas", + "-0.112" + ], + [ + "Kuwait", + "0.0461" + ] + ], + "metaData": { + "cells": [] + } + }, + "sources": [ + { + "link": {}, + "text": "The Very Important Center For Very Important Data" + } + ], + "options": { + "hideTableHeader": false, + "showTableSearch": true, + "cardLayout": false, + "cardLayoutIfSmall": true, + "minibar": { + "invertColors": false, + "barColor": { + "positive": { + "className": "", + "colorCode": "" + }, + "negative": { + "className": "", + "colorCode": "" + } + }, + "selectedColumn": null + } + }, + "tool": "table", + "subtitle": "Very important data country by country" +} \ No newline at end of file diff --git a/routes/fixtures/data.js b/routes/fixtures/data.js index 18ef90a2..a32686d0 100644 --- a/routes/fixtures/data.js +++ b/routes/fixtures/data.js @@ -35,6 +35,8 @@ const fixtureData = [ require(`${fixtureDataDirectory}/formatted-numbers.json`), require(`${fixtureDataDirectory}/formatted-numbers-mixed.json`), require(`${fixtureDataDirectory}/formatted-numbers-negative.json`), + require(`${fixtureDataDirectory}/table-search-hidden.json`), + require(`${fixtureDataDirectory}/table-search-show.json`), ]; module.exports = { diff --git a/tasks/updateFixtureData.js b/tasks/updateFixtureData.js index 1a7eda90..313efa0f 100644 --- a/tasks/updateFixtureData.js +++ b/tasks/updateFixtureData.js @@ -131,6 +131,14 @@ const fixtureData = [ `${fixtureDataDirectory}/formatted-number-negative.json`, require(`${fixtureDataDirectory}/formatted-number-negative.json`), ], + [ + `${fixtureDataDirectory}/table-search-show.json`, + require(`${fixtureDataDirectory}/table-search-show.json`), + ], + [ + `${fixtureDataDirectory}/table-search-hidden.json`, + require(`${fixtureDataDirectory}/table-search-hidden.json`), + ], ]; // register migration scripts here in order of version, diff --git a/test/dom-tests.js b/test/dom-tests.js index 83d58298..bca3912f 100644 --- a/test/dom-tests.js +++ b/test/dom-tests.js @@ -711,3 +711,39 @@ lab.experiment("footnotes", () => { expect(response.statusCode).to.be.equal(200); }); }); + +lab.experiment("table search", () => { + it("shows table search", async () => { + const response = await server.inject({ + url: "/rendering-info/web?_id=someid", + method: "POST", + payload: { + item: require("../resources/fixtures/data/table-search-show.json"), + toolRuntimeConfig: {}, + }, + }); + + return elementCount(response.result.markup, ".search-form-input").then( + (value) => { + expect(value).to.be.equal(1); + } + ); + }); + + it("doesn't show table search", async () => { + const response = await server.inject({ + url: "/rendering-info/web?_id=someid", + method: "POST", + payload: { + item: require("../resources/fixtures/data/table-search-hidden.json"), + toolRuntimeConfig: {}, + }, + }); + + return elementCount(response.result.markup, ".search-form-input").then( + (value) => { + expect(value).to.be.equal(0); + } + ); + }); +}); \ No newline at end of file diff --git a/test/e2e-tests.js b/test/e2e-tests.js index acc6727f..5a5983cc 100644 --- a/test/e2e-tests.js +++ b/test/e2e-tests.js @@ -166,9 +166,9 @@ lab.experiment("dynamic schema endpoint", () => { }); lab.experiment("fixture data endpoint", () => { - it("returns 33 fixture data items for /fixtures/data", async () => { + it("returns 35 fixture data items for /fixtures/data", async () => { const response = await server.inject("/fixtures/data"); expect(response.statusCode).to.be.equal(200); - expect(response.result.length).to.be.equal(33); + expect(response.result.length).to.be.equal(35); }); }); From 966c129b7d00b1697a9772ee3d17f84f434d6cc3 Mon Sep 17 00:00:00 2001 From: Nicolas Staub Date: Fri, 11 Dec 2020 17:43:39 +0100 Subject: [PATCH 07/29] add option for editor to show or hide table search #144 --- resources/schema.json | 16 ++++++++++++++++ routes/option-availability.js | 6 ++++++ routes/rendering-info/web.js | 5 ++++- 3 files changed, 26 insertions(+), 1 deletion(-) diff --git a/resources/schema.json b/resources/schema.json index 0a10ea4c..f1a648ae 100644 --- a/resources/schema.json +++ b/resources/schema.json @@ -131,6 +131,22 @@ "type": "boolean", "default": false }, + "showTableSearch": { + "title": "Tabellensuche anzeigen", + "type": "boolean", + "default": false, + "Q:options": { + "availabilityChecks": [ + { + "type": "ToolEndpoint", + "config": { + "endpoint": "option-availability/showTableSearch", + "fields": ["options", "data"] + } + } + ] + } + }, "cardLayout": { "title": "Card-Layout", "type": "boolean", diff --git a/routes/option-availability.js b/routes/option-availability.js index 9a52f9fc..822fc6cd 100644 --- a/routes/option-availability.js +++ b/routes/option-availability.js @@ -21,6 +21,12 @@ module.exports = { }; } + if (request.params.optionName === "showTableSearch") { + return { + available: (item.data.table.length > 16) + }; + } + if ( request.params.optionName === "minibars" || request.params.optionName === "selectedColumn" diff --git a/routes/rendering-info/web.js b/routes/rendering-info/web.js index 66fa93d7..3648d4ef 100644 --- a/routes/rendering-info/web.js +++ b/routes/rendering-info/web.js @@ -199,8 +199,11 @@ module.exports = { renderingInfo.scripts.push({ content: renderingInfoScripts.getShowMoreButtonScript(context), }); + } + + if (item.options.showTableSearch) { renderingInfo.scripts.push({ - content: renderingInfoScripts.getSearchTextBoxScript(context), + content: renderingInfoScripts.getSearchFormInputScript(context), }); } From c884085b1987e0882d20e5bb074398f3699d4715 Mon Sep 17 00:00:00 2001 From: Nicolas Staub Date: Mon, 14 Dec 2020 11:06:47 +0100 Subject: [PATCH 08/29] add clear button for input box --- helpers/renderingInfoScript.js | 94 +++++++++++++++++++++------------- views/table.html | 7 +++ 2 files changed, 64 insertions(+), 37 deletions(-) diff --git a/helpers/renderingInfoScript.js b/helpers/renderingInfoScript.js index f354f0a4..501ec519 100644 --- a/helpers/renderingInfoScript.js +++ b/helpers/renderingInfoScript.js @@ -217,14 +217,18 @@ function getMinibarsScript(context) { `; } -function getSearchTextBoxScript(context) { +function getSearchFormInputScript(context) { const dataObject = `window.${context.id}Data`; - const searchTextBoxCreateElement = `searchTextBoxCreateElement${context.id}`; - const searchTextBoxHideRows = `searchTextBoxHideRows${context.id}`; - const searchTextBoxShowRows = `searchTextBoxShowRows${context.id}`; + const searchFormInputAddEventListener = `searchFormInputAddEventListener${context.id}`; + const searchFormInputClearAddEventListener = `searchFormInputClearAddEventListener${context.id}`; + const searchFormInputHideRows = `searchFormInputHideRows${context.id}`; + const searchFormInputShowRows = `searchFormInputShowRows${context.id}`; + const searchFormInputClearHide = `searchFormInputClearHide${context.id}`; + const searchFormInputClearShow = `searchFormInputClearShow${context.id}`; + const filterRows = `filterRows${context.id}`; return ` - function ${searchTextBoxHideRows}() { + function ${searchFormInputHideRows}() { ${dataObject}.showMoreButtonElement.style.display = ''; ${dataObject}.tableElement.querySelectorAll('tbody tr').forEach(function(rowElement, index) { @@ -237,7 +241,7 @@ function getSearchTextBoxScript(context) { ${dataObject}.rowVisibilityState = 'hidden'; } - function ${searchTextBoxShowRows}() { + function ${searchFormInputShowRows}() { ${dataObject}.showMoreButtonElement.style.display = 'none'; ${dataObject}.tableElement.querySelectorAll('tbody tr').forEach(function(rowElement, index) { @@ -248,49 +252,65 @@ function getSearchTextBoxScript(context) { ${dataObject}.rowVisibilityState = 'visible'; } - function ${searchTextBoxCreateElement}() { - // If there is no ShowMoreButton, don't add the search box - if (${dataObject}.showMoreButtonElement === undefined) return; + function ${searchFormInputClearHide}() { + document.querySelector('.search-form-input-clear').classList.add('hidden'); + } + + function ${searchFormInputClearShow}() { + document.querySelector('.search-form-input-clear').classList.remove('hidden'); + } + + function ${filterRows}(filter) { + filter = filter.toUpperCase(); + + if (filter.length < 2) return; + + ${dataObject}.tableElement.querySelectorAll('tbody tr .q-table__cell--text').forEach( + function(cellElement, index) { + txtValue = cellElement.innerText.toUpperCase(); - // Create the SearchTextBox - ${dataObject}.searchTextBoxElement = document.createElement('input'); - ${dataObject}.searchTextBoxElement.classList.add('s-input-field'); - ${dataObject}.searchTextBoxElement.setAttribute('type', 'search'); - ${dataObject}.searchTextBoxElement.setAttribute('placeholder', 'Bitte Suche eingeben'); - ${dataObject}.element.insertBefore(${dataObject}.searchTextBoxElement, ${dataObject}.element.querySelector(".s-q-item__subtitle").nextSibling); + if (txtValue.indexOf(filter) > -1) { + cellElement.parentElement.classList.remove('q-table-state-hidden'); + cellElement.parentElement.classList.add('q-table-state-visible'); + } else { + cellElement.parentElement.classList.remove('q-table-state-visible'); + cellElement.parentElement.classList.add('q-table-state-hidden'); + } + } + ); + } - ${dataObject}.searchTextBoxElement.addEventListener('input', function(event) { - var filter = event.target.value.toUpperCase(); + function ${searchFormInputAddEventListener}() { + document.querySelector('.search-form-input').addEventListener('input', function(event) { + var filter = event.target.value; if (filter.length == 0) { // No filter = show only x rows - ${searchTextBoxHideRows}(); - return; + ${searchFormInputHideRows}(); + ${searchFormInputClearHide}(); } else if (filter.length == 1) { // 1 char typed = show all rows - ${searchTextBoxShowRows}(); - return; + ${searchFormInputShowRows}(); + ${searchFormInputClearShow}(); + } else { + ${filterRows}(filter); } - - // More than 1 char typed = start filtering! - ${dataObject}.tableElement.querySelectorAll('tbody tr .q-table__cell--text').forEach( - function(cellElement, index) { - txtValue = cellElement.innerText.toUpperCase(); + }); + } - if (txtValue.indexOf(filter) > -1) { - cellElement.parentElement.classList.remove('q-table-state-hidden'); - cellElement.parentElement.classList.add('q-table-state-visible'); - } else { - cellElement.parentElement.classList.remove('q-table-state-visible'); - cellElement.parentElement.classList.add('q-table-state-hidden'); - } - } - ); + function ${searchFormInputClearAddEventListener}() { + document.querySelector('.search-form-input-clear').addEventListener('click', function(event) { + document.querySelector('.search-form-input').value = ''; + + ${searchFormInputShowRows}(); + ${searchFormInputHideRows}(); + ${searchFormInputClearHide}(); }); } window.q_domready.then(function() { - ${searchTextBoxCreateElement}(); + ${searchFormInputAddEventListener}(); + ${searchFormInputClearAddEventListener}(); }); `; } @@ -300,5 +320,5 @@ module.exports = { getCardLayoutScript: getCardLayoutScript, getShowMoreButtonScript: getShowMoreButtonScript, getMinibarsScript: getMinibarsScript, - getSearchTextBoxScript: getSearchTextBoxScript + getSearchFormInputScript: getSearchFormInputScript }; diff --git a/views/table.html b/views/table.html index 291d748e..1cdbda59 100644 --- a/views/table.html +++ b/views/table.html @@ -4,6 +4,13 @@

{{ item.title }}

{% endif %} {%- if item.subtitl
{{ item.subtitle }}
{%- endif %}
+ {%- if item.options.showTableSearch === true %} +
+ + + +
+ {%- endif %} {%- if item.options.hideTableHeader !== true %} From 2bc4044226d5d98e8b1bda3f4b7a49b3c18aed50 Mon Sep 17 00:00:00 2001 From: Nicolas Staub Date: Mon, 14 Dec 2020 11:08:31 +0100 Subject: [PATCH 09/29] reset .json files --- package-lock.json | 58 +++++++++++++++++++++++------------------------ package.json | 12 +++++----- 2 files changed, 35 insertions(+), 35 deletions(-) diff --git a/package-lock.json b/package-lock.json index ed0ca9bf..fe408ce4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -327,16 +327,16 @@ "integrity": "sha512-EwaJS7RjoXUZ2cXXKZZxZqieGtc7RbvQhUy8FwDoMQtxWVi14tFjeFCYPZAM1mBCpOpiBpyaZbb9NeHc7eGKgw==" }, "@hapi/inert": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/@hapi/inert/-/inert-6.0.3.tgz", - "integrity": "sha512-Z6Pi0Wsn2pJex5CmBaq+Dky9q40LGzXLUIUFrYpDtReuMkmfy9UuUeYc4064jQ1Xe9uuw7kbwE6Fq6rqKAdjAg==", + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/@hapi/inert/-/inert-6.0.2.tgz", + "integrity": "sha512-cq0a8jstkLW1+oJaw4jp52PZBEkVbX9d0YDy5aOs3rOKYSjpzs2nQBahnCHEMchOrOSUffLpE+IDoivYHcx8uA==", "requires": { "@hapi/ammo": "5.x.x", "@hapi/boom": "9.x.x", "@hapi/bounce": "2.x.x", "@hapi/hoek": "9.x.x", "@hapi/validate": "1.x.x", - "lru-cache": "^6.0.0" + "lru-cache": "5.x.x" } }, "@hapi/iron": { @@ -692,9 +692,9 @@ "dev": true }, "ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "version": "6.12.3", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.3.tgz", + "integrity": "sha512-4K0cK3L1hsqk9xIb2z9vs/XU+PGJZ9PNpJRDS9YLzmNdX6jmVPfamLvTJr0aDAusnHyCHO6MjzlkAsgtqp9teA==", "requires": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", @@ -1385,9 +1385,9 @@ } }, "d3-format": { - "version": "1.4.5", - "resolved": "https://registry.npmjs.org/d3-format/-/d3-format-1.4.5.tgz", - "integrity": "sha512-J0piedu6Z8iB6TbIGfZgDzfXxUFN3qQRMofy2oPdXzQibYGqPB/9iMcxr/TGalU+2RsyDO+U4f33id8tbnSRMQ==" + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/d3-format/-/d3-format-1.4.4.tgz", + "integrity": "sha512-TWks25e7t8/cqctxCmxpUuzZN11QxIA7YrMbram94zMQ0PXjE4LVIMe/f6a4+xxL8HQ3OsAFULOINQi1pE62Aw==" }, "dashdash": { "version": "1.14.1", @@ -2536,11 +2536,11 @@ "dev": true }, "lru-cache": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", - "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", + "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", "requires": { - "yallist": "^4.0.0" + "yallist": "^3.0.2" } }, "mdn-data": { @@ -2869,9 +2869,9 @@ "dev": true }, "postcss": { - "version": "7.0.35", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.35.tgz", - "integrity": "sha512-3QT8bBJeX/S5zKTTjTCIjRF3If4avAT6kqxcASlTWEtAFCb9NH0OUxNDfgZSWdP5fJnBYCMEWkIFfWeugjzYMg==", + "version": "7.0.32", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.32.tgz", + "integrity": "sha512-03eXong5NLnNCD05xscnGKGDZ98CyzoqPSMjOe6SuoQY7Z2hIj0Ld1g/O/UQRuOle2aRtiIRDg9tDcTGAkLfKw==", "dev": true, "requires": { "chalk": "^2.4.2", @@ -3469,9 +3469,9 @@ "dev": true }, "sass": { - "version": "1.29.0", - "resolved": "https://registry.npmjs.org/sass/-/sass-1.29.0.tgz", - "integrity": "sha512-ZpwAUFgnvAUCdkjwPREny+17BpUj8nh5Yr6zKPGtLNTLrmtoRYIjm7njP24COhjJldjwW1dcv52Lpf4tNZVVRA==", + "version": "1.26.10", + "resolved": "https://registry.npmjs.org/sass/-/sass-1.26.10.tgz", + "integrity": "sha512-bzN0uvmzfsTvjz0qwccN1sPm2HxxpNI/Xa+7PlUEMS+nQvbyuEK7Y0qFqxlPHhiNHb1Ze8WQJtU31olMObkAMw==", "dev": true, "requires": { "chokidar": ">=2.0.0 <4.0.0" @@ -3865,9 +3865,9 @@ "dev": true }, "uglify-js": { - "version": "3.12.1", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.12.1.tgz", - "integrity": "sha512-o8lHP20KjIiQe5b/67Rh68xEGRrc2SRsCuuoYclXXoC74AfSRGblU1HKzJWH3HxPZ+Ort85fWHpSX7KwBUC9CQ==" + "version": "3.10.1", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.10.1.tgz", + "integrity": "sha512-RjxApKkrPJB6kjJxQS3iZlf///REXWYxYJxO/MpmlQzVkDWVI3PSnCBWezMecmTU/TRkNxrl8bmsfFQCp+LO+Q==" }, "uniq": { "version": "1.0.1", @@ -3894,9 +3894,9 @@ "dev": true }, "uri-js": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.0.tgz", - "integrity": "sha512-B0yRTzYdUCCn9n+F4+Gh4yIDtMQcaJsmYBDsTSG8g/OejKBodLQ2IHfN3bM7jUsRXndopT7OIXWdYqc1fjmV6g==", + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", + "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", "requires": { "punycode": "^2.1.0" } @@ -4059,9 +4059,9 @@ "dev": true }, "yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", + "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==" } } } diff --git a/package.json b/package.json index b41d8afc..b1215224 100644 --- a/package.json +++ b/package.json @@ -13,14 +13,14 @@ "dependencies": { "@hapi/boom": "^9.1.0", "@hapi/hapi": "^19.2.0", - "@hapi/inert": "^6.0.3", + "@hapi/inert": "^6.0.2", "@hapi/joi": "^17.1.1", - "ajv": "^6.12.6", + "ajv": "^6.12.3", "array2d": "0.0.5", "clone": "^2.1.2", - "d3-format": "^1.4.5", + "d3-format": "^1.4.4", "nunjucks": "^3.2.2", - "uglify-js": "^3.12.1" + "uglify-js": "^3.10.1" }, "devDependencies": { "@hapi/code": "^8.0.2", @@ -29,8 +29,8 @@ "cssnano": "^4.1.10", "html-minifier": "^4.0.0", "jsdom": "^16.4.0", - "postcss": "^7.0.35", + "postcss": "^7.0.32", "postcss-import": "^12.0.1", - "sass": "^1.29.0" + "sass": "^1.26.10" } } From 46e3b472fb4a7ea906a769892e0cf057d4f4d6ea Mon Sep 17 00:00:00 2001 From: Nicolas Staub Date: Mon, 14 Dec 2020 12:20:33 +0100 Subject: [PATCH 10/29] remove redundant css class --- views/table.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/views/table.html b/views/table.html index 1cdbda59..f42e2291 100644 --- a/views/table.html +++ b/views/table.html @@ -7,7 +7,7 @@

{{ item.title }}

{% endif %} {%- if item.subtitl {%- if item.options.showTableSearch === true %}
- +
{%- endif %} From 4a1580daba040f23003b782f0890b97eceacd163 Mon Sep 17 00:00:00 2001 From: Nicolas Staub Date: Mon, 14 Dec 2020 16:21:39 +0100 Subject: [PATCH 11/29] remove clear button for input box --- helpers/renderingInfoScript.js | 35 +++++++++------------------------- views/table.html | 7 ++----- 2 files changed, 11 insertions(+), 31 deletions(-) diff --git a/helpers/renderingInfoScript.js b/helpers/renderingInfoScript.js index 501ec519..12693e08 100644 --- a/helpers/renderingInfoScript.js +++ b/helpers/renderingInfoScript.js @@ -219,12 +219,9 @@ function getMinibarsScript(context) { function getSearchFormInputScript(context) { const dataObject = `window.${context.id}Data`; - const searchFormInputAddEventListener = `searchFormInputAddEventListener${context.id}`; - const searchFormInputClearAddEventListener = `searchFormInputClearAddEventListener${context.id}`; + const searchFormInputAddEventListeners = `searchFormInputAddEventListeners${context.id}`; const searchFormInputHideRows = `searchFormInputHideRows${context.id}`; const searchFormInputShowRows = `searchFormInputShowRows${context.id}`; - const searchFormInputClearHide = `searchFormInputClearHide${context.id}`; - const searchFormInputClearShow = `searchFormInputClearShow${context.id}`; const filterRows = `filterRows${context.id}`; return ` @@ -252,14 +249,6 @@ function getSearchFormInputScript(context) { ${dataObject}.rowVisibilityState = 'visible'; } - function ${searchFormInputClearHide}() { - document.querySelector('.search-form-input-clear').classList.add('hidden'); - } - - function ${searchFormInputClearShow}() { - document.querySelector('.search-form-input-clear').classList.remove('hidden'); - } - function ${filterRows}(filter) { filter = filter.toUpperCase(); @@ -280,37 +269,31 @@ function getSearchFormInputScript(context) { ); } - function ${searchFormInputAddEventListener}() { - document.querySelector('.search-form-input').addEventListener('input', function(event) { + function ${searchFormInputAddEventListeners}() { + document.querySelector('#search-form-input').addEventListener('input', function(event) { var filter = event.target.value; if (filter.length == 0) { // No filter = show only x rows ${searchFormInputHideRows}(); - ${searchFormInputClearHide}(); } else if (filter.length == 1) { // 1 char typed = show all rows ${searchFormInputShowRows}(); - ${searchFormInputClearShow}(); } else { ${filterRows}(filter); } }); - } - function ${searchFormInputClearAddEventListener}() { - document.querySelector('.search-form-input-clear').addEventListener('click', function(event) { - document.querySelector('.search-form-input').value = ''; - - ${searchFormInputShowRows}(); - ${searchFormInputHideRows}(); - ${searchFormInputClearHide}(); + document.querySelector('#search-form-input').addEventListener('search', function(event) { + if (event.target.value == '') { + ${searchFormInputShowRows}(); + ${searchFormInputHideRows}(); + } }); } window.q_domready.then(function() { - ${searchFormInputAddEventListener}(); - ${searchFormInputClearAddEventListener}(); + ${searchFormInputAddEventListeners}(); }); `; } diff --git a/views/table.html b/views/table.html index f42e2291..63fd5798 100644 --- a/views/table.html +++ b/views/table.html @@ -5,11 +5,8 @@

{{ item.title }}

{% endif %} {%- if item.subtitl {%- endif %}
{%- if item.options.showTableSearch === true %} -
- - - -
+ + {%- endif %}
{%- if item.options.hideTableHeader !== true %} From 068c66f720bd822d0eb269d42de8ac7518aef945 Mon Sep 17 00:00:00 2001 From: Nicolas Staub Date: Mon, 14 Dec 2020 16:37:57 +0100 Subject: [PATCH 12/29] rename html element --- test/dom-tests.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/dom-tests.js b/test/dom-tests.js index bca3912f..06d4fb4e 100644 --- a/test/dom-tests.js +++ b/test/dom-tests.js @@ -723,7 +723,7 @@ lab.experiment("table search", () => { }, }); - return elementCount(response.result.markup, ".search-form-input").then( + return elementCount(response.result.markup, "#search-form-input").then( (value) => { expect(value).to.be.equal(1); } @@ -740,7 +740,7 @@ lab.experiment("table search", () => { }, }); - return elementCount(response.result.markup, ".search-form-input").then( + return elementCount(response.result.markup, "#search-form-input").then( (value) => { expect(value).to.be.equal(0); } From 8c5c07833c8d59f78bd7c7342f264b19d5a8ed52 Mon Sep 17 00:00:00 2001 From: Nicolas Staub Date: Tue, 15 Dec 2020 11:12:19 +0100 Subject: [PATCH 13/29] use hidden attribute instead css class --- views/table.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/views/table.html b/views/table.html index 63fd5798..2c56c221 100644 --- a/views/table.html +++ b/views/table.html @@ -5,7 +5,7 @@

{{ item.title }}

{% endif %} {%- if item.subtitl {%- endif %}
{%- if item.options.showTableSearch === true %} - + {%- endif %}
From 50a6c331e40800f53f35ef538c66d96717b360f5 Mon Sep 17 00:00:00 2001 From: Nicolas Staub Date: Tue, 15 Dec 2020 12:17:32 +0100 Subject: [PATCH 14/29] fix format issue and remove redundant html attribute and css style --- views/table.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/views/table.html b/views/table.html index 2c56c221..ebb318ad 100644 --- a/views/table.html +++ b/views/table.html @@ -3,10 +3,10 @@

{{ item.title }}

{% endif %} {%- if item.subtitle and item.subtitle !== '' %}
{{ item.subtitle }}
{%- endif %} -
+
{%- if item.options.showTableSearch === true %} - + {%- endif %}
{%- if item.options.hideTableHeader !== true %} From 77a2ce8e43ace4803b8505525f49d3c712c972a2 Mon Sep 17 00:00:00 2001 From: Nicolas Staub Date: Tue, 15 Dec 2020 12:42:24 +0100 Subject: [PATCH 15/29] fix in dom-tests after last commit --- test/dom-tests.js | 6 +++--- views/table.html | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/test/dom-tests.js b/test/dom-tests.js index 06d4fb4e..0603bf6a 100644 --- a/test/dom-tests.js +++ b/test/dom-tests.js @@ -265,7 +265,7 @@ lab.experiment("cardlayout on mobile", () => { lab.experiment("minibars", () => { it("shows the same markup for positive minibars", async () => { - const workingMinibarsMarkup = `

FIXTURE: minibars with negative values

State by state breakdown
20162017+/- %
Auftragseingang10 37510 989
–6
Umsatz9 68310 178
–5
Ebit-Mage (%)11,711,7
-
Cashflow aus Geschäftstätigkeite929810
–13
Quelle: The Centers for Disease Control and Prevention
`; + const workingMinibarsMarkup = `

FIXTURE: minibars with negative values

State by state breakdown
20162017+/- %
Auftragseingang10 37510 989
–6
Umsatz9 68310 178
–5
Ebit-Mage (%)11,711,7
-
Cashflow aus Geschäftstätigkeite929810
–13
Quelle: The Centers for Disease Control and Prevention
`; const response = await server.inject({ url: "/rendering-info/web?_id=someid", @@ -292,7 +292,7 @@ lab.experiment("minibars", () => { }); it("shows the same markup for negative minibars", async () => { - const workingMinibarsMarkup = `

FIXTURE: minibars with negative values

State by state breakdown
20162017+/- %
Auftragseingang10 37510 989
–6
Umsatz9 68310 178
–5
Ebit-Mage (%)11,711,7
-
Cashflow aus Geschäftstätigkeite929810
–13
Quelle: The Centers for Disease Control and Prevention
`; + const workingMinibarsMarkup = `

FIXTURE: minibars with negative values

State by state breakdown
20162017+/- %
Auftragseingang10 37510 989
–6
Umsatz9 68310 178
–5
Ebit-Mage (%)11,711,7
-
Cashflow aus Geschäftstätigkeite929810
–13
Quelle: The Centers for Disease Control and Prevention
`; const response = await server.inject({ url: "/rendering-info/web?_id=someid", @@ -319,7 +319,7 @@ lab.experiment("minibars", () => { }); it("shows the same markup for mixed minibars", async () => { - const workingMinibarsMarkup = `

FIXTURE: minibars with positive and negative values

State by state breakdown
20162017+/- %
Auftragseingang10 37510 989
6
Umsatz9 68310 178
5
Ebit-Mage (%)11,711,7
-
Cashflow aus Geschäftstätigkeite929810
–13
Quelle: The Centers for Disease Control and Prevention
`; + const workingMinibarsMarkup = `

FIXTURE: minibars with positive and negative values

State by state breakdown
20162017+/- %
Auftragseingang10 37510 989
6
Umsatz9 68310 178
5
Ebit-Mage (%)11,711,7
-
Cashflow aus Geschäftstätigkeite929810
–13
Quelle: The Centers for Disease Control and Prevention
`; const response = await server.inject({ url: "/rendering-info/web?_id=someid", method: "POST", diff --git a/views/table.html b/views/table.html index ebb318ad..3d11110e 100644 --- a/views/table.html +++ b/views/table.html @@ -3,7 +3,7 @@

{{ item.title }}

{% endif %} {%- if item.subtitle and item.subtitle !== '' %}
{{ item.subtitle }}
{%- endif %} -
+
{%- if item.options.showTableSearch === true %} From 9abc4e6d579380e6333d22a9e37ca00723d2e6c3 Mon Sep 17 00:00:00 2001 From: Nicolas Staub Date: Tue, 15 Dec 2020 17:10:22 +0100 Subject: [PATCH 16/29] some renamings, add aria-label to input element --- helpers/renderingInfoScript.js | 12 ++++++------ test/dom-tests.js | 10 +++++----- views/table.html | 5 ++--- 3 files changed, 13 insertions(+), 14 deletions(-) diff --git a/helpers/renderingInfoScript.js b/helpers/renderingInfoScript.js index 12693e08..2ddd7195 100644 --- a/helpers/renderingInfoScript.js +++ b/helpers/renderingInfoScript.js @@ -256,9 +256,9 @@ function getSearchFormInputScript(context) { ${dataObject}.tableElement.querySelectorAll('tbody tr .q-table__cell--text').forEach( function(cellElement, index) { - txtValue = cellElement.innerText.toUpperCase(); - - if (txtValue.indexOf(filter) > -1) { + textCellValue = cellElement.innerText.toUpperCase(); + + if (textCellValue.indexOf(filter) > -1) { cellElement.parentElement.classList.remove('q-table-state-hidden'); cellElement.parentElement.classList.add('q-table-state-visible'); } else { @@ -270,11 +270,11 @@ function getSearchFormInputScript(context) { } function ${searchFormInputAddEventListeners}() { - document.querySelector('#search-form-input').addEventListener('input', function(event) { + document.querySelector('.search-form-input').addEventListener('input', function(event) { var filter = event.target.value; if (filter.length == 0) { - // No filter = show only x rows + // No filter = show default view with show more button (15 rows) ${searchFormInputHideRows}(); } else if (filter.length == 1) { // 1 char typed = show all rows @@ -284,7 +284,7 @@ function getSearchFormInputScript(context) { } }); - document.querySelector('#search-form-input').addEventListener('search', function(event) { + document.querySelector('.search-form-input').addEventListener('search', function(event) { if (event.target.value == '') { ${searchFormInputShowRows}(); ${searchFormInputHideRows}(); diff --git a/test/dom-tests.js b/test/dom-tests.js index 0603bf6a..27e7923e 100644 --- a/test/dom-tests.js +++ b/test/dom-tests.js @@ -265,7 +265,7 @@ lab.experiment("cardlayout on mobile", () => { lab.experiment("minibars", () => { it("shows the same markup for positive minibars", async () => { - const workingMinibarsMarkup = `

FIXTURE: minibars with negative values

State by state breakdown
20162017+/- %
Auftragseingang10 37510 989
–6
Umsatz9 68310 178
–5
Ebit-Mage (%)11,711,7
-
Cashflow aus Geschäftstätigkeite929810
–13
Quelle: The Centers for Disease Control and Prevention
`; + const workingMinibarsMarkup = `

FIXTURE: minibars with negative values

State by state breakdown
20162017+/- %
Auftragseingang10 37510 989
–6
Umsatz9 68310 178
–5
Ebit-Mage (%)11,711,7
-
Cashflow aus Geschäftstätigkeite929810
–13
Quelle: The Centers for Disease Control and Prevention
`; const response = await server.inject({ url: "/rendering-info/web?_id=someid", @@ -292,7 +292,7 @@ lab.experiment("minibars", () => { }); it("shows the same markup for negative minibars", async () => { - const workingMinibarsMarkup = `

FIXTURE: minibars with negative values

State by state breakdown
20162017+/- %
Auftragseingang10 37510 989
–6
Umsatz9 68310 178
–5
Ebit-Mage (%)11,711,7
-
Cashflow aus Geschäftstätigkeite929810
–13
Quelle: The Centers for Disease Control and Prevention
`; + const workingMinibarsMarkup = `

FIXTURE: minibars with negative values

State by state breakdown
20162017+/- %
Auftragseingang10 37510 989
–6
Umsatz9 68310 178
–5
Ebit-Mage (%)11,711,7
-
Cashflow aus Geschäftstätigkeite929810
–13
Quelle: The Centers for Disease Control and Prevention
`; const response = await server.inject({ url: "/rendering-info/web?_id=someid", @@ -319,7 +319,7 @@ lab.experiment("minibars", () => { }); it("shows the same markup for mixed minibars", async () => { - const workingMinibarsMarkup = `

FIXTURE: minibars with positive and negative values

State by state breakdown
20162017+/- %
Auftragseingang10 37510 989
6
Umsatz9 68310 178
5
Ebit-Mage (%)11,711,7
-
Cashflow aus Geschäftstätigkeite929810
–13
Quelle: The Centers for Disease Control and Prevention
`; + const workingMinibarsMarkup = `

FIXTURE: minibars with positive and negative values

State by state breakdown
20162017+/- %
Auftragseingang10 37510 989
6
Umsatz9 68310 178
5
Ebit-Mage (%)11,711,7
-
Cashflow aus Geschäftstätigkeite929810
–13
Quelle: The Centers for Disease Control and Prevention
`; const response = await server.inject({ url: "/rendering-info/web?_id=someid", method: "POST", @@ -723,7 +723,7 @@ lab.experiment("table search", () => { }, }); - return elementCount(response.result.markup, "#search-form-input").then( + return elementCount(response.result.markup, ".search-form-input").then( (value) => { expect(value).to.be.equal(1); } @@ -740,7 +740,7 @@ lab.experiment("table search", () => { }, }); - return elementCount(response.result.markup, "#search-form-input").then( + return elementCount(response.result.markup, ".search-form-input").then( (value) => { expect(value).to.be.equal(0); } diff --git a/views/table.html b/views/table.html index 3d11110e..2aefd76c 100644 --- a/views/table.html +++ b/views/table.html @@ -3,10 +3,9 @@

{{ item.title }}

{% endif %} {%- if item.subtitle and item.subtitle !== '' %}
{{ item.subtitle }}
{%- endif %} -
+
{%- if item.options.showTableSearch === true %} - - + {%- endif %} {%- if item.options.hideTableHeader !== true %} From df368f5cdde53960ea43b1a0a63715cd61a71153 Mon Sep 17 00:00:00 2001 From: Nicolas Staub Date: Wed, 16 Dec 2020 11:16:26 +0100 Subject: [PATCH 17/29] update readme.md --- README.md | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/README.md b/README.md index c6b7fe31..946c90ed 100644 --- a/README.md +++ b/README.md @@ -182,6 +182,21 @@ Footnotes are a feature to display annotations in the table and the sources in t [to the top](#table-of-contents) +#### Table search + + + +This feature makes large tables searchable. + +###### Implementation details +- By default the table is collapsed and the `q-table_show-more-button` is visible at the bottom of the table ([see Collapsable table](#collapsable-table)). +- When the user starts typing, all rows will be made visible and the `q-table_show-more-button` disappears. +- The actual search function triggers, as soon as the user types the second character. +- At the moment only `q-table__cell--text` cells are searched. +- When the user deletes his input, the table collapses and the `q-table_show-more-button` will be visible again. + +[to the top](#table-of-contents) + ### Options #### hideTableHeader @@ -194,6 +209,16 @@ This options allows to hide the header of each column. By default it's `false` [to the top](#table-of-contents) +#### showTableSearch + +This option allows to show or hide the table search feature. The option is only available, when there are more than 16 rows in the table. Default value is `false`. + +###### Implementation details + +- If the option is used, the input element for the table search won't be rendered. + +[to the top](#table-of-contents) + #### cardLayout From b6c461238481509f36d4860f8ab4b70f533c3269 Mon Sep 17 00:00:00 2001 From: Nicolas Staub Date: Wed, 16 Dec 2020 11:18:54 +0100 Subject: [PATCH 18/29] add .png for readme.md --- doc/table-search.png | Bin 0 -> 83427 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 doc/table-search.png diff --git a/doc/table-search.png b/doc/table-search.png new file mode 100644 index 0000000000000000000000000000000000000000..fb9d39b8d7f232542537c4b78fb4d7dbaa1cc710 GIT binary patch literal 83427 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 Date: Wed, 16 Dec 2020 11:27:42 +0100 Subject: [PATCH 19/29] update readme.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 946c90ed..9c8ee396 100644 --- a/README.md +++ b/README.md @@ -192,7 +192,7 @@ This feature makes large tables searchable. - By default the table is collapsed and the `q-table_show-more-button` is visible at the bottom of the table ([see Collapsable table](#collapsable-table)). - When the user starts typing, all rows will be made visible and the `q-table_show-more-button` disappears. - The actual search function triggers, as soon as the user types the second character. -- At the moment only `q-table__cell--text` cells are searched. +- The filter searches through text-based columns only. - When the user deletes his input, the table collapses and the `q-table_show-more-button` will be visible again. [to the top](#table-of-contents) From 71cb1035f8d9c53349581b3b5978d98a6500387b Mon Sep 17 00:00:00 2001 From: Nicolas Staub Date: Wed, 16 Dec 2020 13:27:31 +0100 Subject: [PATCH 20/29] don't show table search in q-to-print --- routes/rendering-info/web.js | 6 +++++- views/table.html | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/routes/rendering-info/web.js b/routes/rendering-info/web.js index 3648d4ef..629a6a78 100644 --- a/routes/rendering-info/web.js +++ b/routes/rendering-info/web.js @@ -102,6 +102,7 @@ module.exports = { footnotes: footnotes, numberOfRows: item.data.table.length - 1, // do not count the header displayOptions: request.payload.toolRuntimeConfig.displayOptions || {}, + noInteraction: request.payload.toolRuntimeConfig.noInteraction, id: `q_table_${request.query._id}_${Math.floor( Math.random() * 100000 )}`.replace(/-/g, ""), @@ -201,7 +202,10 @@ module.exports = { }); } - if (item.options.showTableSearch) { + if ( + context.noInteraction !== true && + item.options.showTableSearch === true + ) { renderingInfo.scripts.push({ content: renderingInfoScripts.getSearchFormInputScript(context), }); diff --git a/views/table.html b/views/table.html index 2aefd76c..db94e895 100644 --- a/views/table.html +++ b/views/table.html @@ -4,7 +4,7 @@

{{ item.title }}

{% endif %} {%- if item.subtitl
{{ item.subtitle }}
{%- endif %}
- {%- if item.options.showTableSearch === true %} + {%- if noInteraction !== true and item.options.showTableSearch === true %} {%- endif %}
From 4af6a4941084cac96c2fab1872444cbda2b59f17 Mon Sep 17 00:00:00 2001 From: Nicolas Staub Date: Wed, 16 Dec 2020 15:03:12 +0100 Subject: [PATCH 21/29] fix input field format --- views/table.html | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/views/table.html b/views/table.html index db94e895..badb78b2 100644 --- a/views/table.html +++ b/views/table.html @@ -5,7 +5,9 @@

{{ item.title }}

{% endif %} {%- if item.subtitl {%- endif %}
{%- if noInteraction !== true and item.options.showTableSearch === true %} - +
+ +
{%- endif %}
{%- if item.options.hideTableHeader !== true %} From 8817364167cdf0c7f4aaee989180542d2962dbbe Mon Sep 17 00:00:00 2001 From: Nicolas Staub Date: Thu, 17 Dec 2020 08:36:34 +0100 Subject: [PATCH 22/29] rename css classes --- helpers/renderingInfoScript.js | 4 ++-- styles_src/q-table.scss | 4 ++++ test/dom-tests.js | 4 ++-- views/table.html | 4 ++-- 4 files changed, 10 insertions(+), 6 deletions(-) diff --git a/helpers/renderingInfoScript.js b/helpers/renderingInfoScript.js index 2ddd7195..ca0ce1fd 100644 --- a/helpers/renderingInfoScript.js +++ b/helpers/renderingInfoScript.js @@ -270,7 +270,7 @@ function getSearchFormInputScript(context) { } function ${searchFormInputAddEventListeners}() { - document.querySelector('.search-form-input').addEventListener('input', function(event) { + document.querySelector('.q-table__search__input').addEventListener('input', function(event) { var filter = event.target.value; if (filter.length == 0) { @@ -284,7 +284,7 @@ function getSearchFormInputScript(context) { } }); - document.querySelector('.search-form-input').addEventListener('search', function(event) { + document.querySelector('.q-table__search__input').addEventListener('search', function(event) { if (event.target.value == '') { ${searchFormInputShowRows}(); ${searchFormInputHideRows}(); diff --git a/styles_src/q-table.scss b/styles_src/q-table.scss index 1247c468..8d1f6242 100644 --- a/styles_src/q-table.scss +++ b/styles_src/q-table.scss @@ -2,6 +2,10 @@ opacity: 1 !important; } +.q-table__search { + padding: 0 1px; +} + .q-table__cell { text-align: left !important; } diff --git a/test/dom-tests.js b/test/dom-tests.js index 27e7923e..907bd202 100644 --- a/test/dom-tests.js +++ b/test/dom-tests.js @@ -723,7 +723,7 @@ lab.experiment("table search", () => { }, }); - return elementCount(response.result.markup, ".search-form-input").then( + return elementCount(response.result.markup, ".q-table__search__input").then( (value) => { expect(value).to.be.equal(1); } @@ -740,7 +740,7 @@ lab.experiment("table search", () => { }, }); - return elementCount(response.result.markup, ".search-form-input").then( + return elementCount(response.result.markup, ".q-table__search__input").then( (value) => { expect(value).to.be.equal(0); } diff --git a/views/table.html b/views/table.html index badb78b2..e6f507c6 100644 --- a/views/table.html +++ b/views/table.html @@ -5,8 +5,8 @@

{{ item.title }}

{% endif %} {%- if item.subtitl {%- endif %}
{%- if noInteraction !== true and item.options.showTableSearch === true %} -
- + {%- endif %}
From ab08a5f1da35588f8b7ad6941fb97dfece01c284 Mon Sep 17 00:00:00 2001 From: Nicolas Staub Date: Thu, 17 Dec 2020 10:31:54 +0100 Subject: [PATCH 23/29] fix in input event and remove redundant eventlistener --- helpers/renderingInfoScript.js | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) diff --git a/helpers/renderingInfoScript.js b/helpers/renderingInfoScript.js index ca0ce1fd..36210b98 100644 --- a/helpers/renderingInfoScript.js +++ b/helpers/renderingInfoScript.js @@ -273,23 +273,16 @@ function getSearchFormInputScript(context) { document.querySelector('.q-table__search__input').addEventListener('input', function(event) { var filter = event.target.value; - if (filter.length == 0) { - // No filter = show default view with show more button (15 rows) - ${searchFormInputHideRows}(); - } else if (filter.length == 1) { - // 1 char typed = show all rows + if (filter.length < 2) { + // Always make all rows visible again ${searchFormInputShowRows}(); + + // No filter = show default view with show more button (15 rows) + if (filter.length == 0) ${searchFormInputHideRows}(); } else { ${filterRows}(filter); } }); - - document.querySelector('.q-table__search__input').addEventListener('search', function(event) { - if (event.target.value == '') { - ${searchFormInputShowRows}(); - ${searchFormInputHideRows}(); - } - }); } window.q_domready.then(function() { From 4c152b4ed6023928fada987e5ba69e4968d7860d Mon Sep 17 00:00:00 2001 From: Nicolas Staub Date: Fri, 18 Dec 2020 11:06:17 +0100 Subject: [PATCH 24/29] fix in search function and new fixture data --- helpers/renderingInfoScript.js | 33 +- .../fixtures/data/table-search-show.json | 707 +++++++++++++----- 2 files changed, 529 insertions(+), 211 deletions(-) diff --git a/helpers/renderingInfoScript.js b/helpers/renderingInfoScript.js index 36210b98..a4a47699 100644 --- a/helpers/renderingInfoScript.js +++ b/helpers/renderingInfoScript.js @@ -250,20 +250,35 @@ function getSearchFormInputScript(context) { } function ${filterRows}(filter) { + var foundString = false; filter = filter.toUpperCase(); - + if (filter.length < 2) return; - ${dataObject}.tableElement.querySelectorAll('tbody tr .q-table__cell--text').forEach( - function(cellElement, index) { - textCellValue = cellElement.innerText.toUpperCase(); + // Loop through all table rows + ${dataObject}.tableElement.querySelectorAll('tbody tr').forEach( + function(rowElement) { + + foundString = false; - if (textCellValue.indexOf(filter) > -1) { - cellElement.parentElement.classList.remove('q-table-state-hidden'); - cellElement.parentElement.classList.add('q-table-state-visible'); + // Loop through all text cells + rowElement.querySelectorAll('.q-table__cell--text').forEach( + function(textCellElement) { + textCellValue = textCellElement.innerText.toUpperCase(); + + if (textCellValue.indexOf(filter) > -1) { + foundString = true; + return; + } + } + ) + + if (foundString) { + rowElement.classList.remove('q-table-state-hidden'); + rowElement.classList.add('q-table-state-visible'); } else { - cellElement.parentElement.classList.remove('q-table-state-visible'); - cellElement.parentElement.classList.add('q-table-state-hidden'); + rowElement.classList.remove('q-table-state-visible'); + rowElement.classList.add('q-table-state-hidden'); } } ); diff --git a/resources/fixtures/data/table-search-show.json b/resources/fixtures/data/table-search-show.json index 6e9a6370..1cfce282 100644 --- a/resources/fixtures/data/table-search-show.json +++ b/resources/fixtures/data/table-search-show.json @@ -3,408 +3,711 @@ "data": { "table": [ [ - "Country", - "Number" + "Country 1", + "Country 2", + "Number 1", + "Number 2", + "Company 1" ], [ - "Somalia", - "-0.1459" + "Marshall Islands", + "San Marino", + "4018", + "636", + "Sed Libero Proin Corp." ], [ - "Honduras", - "0.2758" + "Iran", + "Antigua and Barbuda", + "9722", + "419", + "Orci Lacus Incorporated" ], [ - "Malawi", - "-0.0534" + "Falkland Islands", + "Saint Barthélemy", + "8062", + "991", + "Eleifend Non Incorporated" ], [ - "Comoros", - "0.0111" + "Madagascar", + "Mexico", + "3518", + "698", + "Arcu Et Pede Limited" ], [ - "Greece", - "-0.1775" + "Tanzania", + "United States Minor Outlying Islands", + "8799", + "233", + "Parturient Montes Nascetur LLC" ], [ - "Turkmenistan", - "0.0803" + "Ireland", + "Russian Federation", + "4996", + "447", + "Nunc Commodo Incorporated" ], [ - "Panama", - "0.0164" + "Pakistan", + "Norway", + "4706", + "527", + "Orci Phasellus Dapibus Foundation" ], [ - "Austria", - "-0.0462" + "Cuba", + "Korea, South", + "9900", + "946", + "Imperdiet Corporation" ], [ - "Saint Barthélemy", - "-0.0247" + "Lebanon", + "United Arab Emirates", + "6943", + "988", + "Lorem Vitae Odio Institute" ], [ - "Kazakhstan", - "-0.0067" + "Maldives", + "Brazil", + "6868", + "134", + "Eu Corp." ], [ - "Azerbaijan", - "0.044" + "Cape Verde", + "Comoros", + "5269", + "746", + "Ante Inc." ], [ - "Netherlands", - "0.2486" + "Seychelles", + "Western Sahara", + "1891", + "636", + "Tempor Arcu Company" ], [ - "Yemen", - "-0.106" + "El Salvador", + "Montenegro", + "7089", + "735", + "Fringilla Donec Corp." ], [ - "Sint Maarten", - "0.4218" + "Montenegro", + "Japan", + "1565", + "415", + "Malesuada Id LLP" ], [ - "Svalbard and Jan Mayen Islands", - "-0.1107" + "Somalia", + "Ghana", + "2436", + "732", + "Pellentesque A Foundation" ], [ - "Belarus", - "-0.4466" + "Haiti", + "Faroe Islands", + "7910", + "140", + "Tempus Non Foundation" ], [ - "China", - "-0.4345" + "Botswana", + "Tonga", + "2868", + "854", + "Malesuada Augue Institute" ], [ - "Congo (Brazzaville)", - "-0.1386" + "Dominica", + "Saudi Arabia", + "9885", + "667", + "Suspendisse Sagittis Nullam Associates" ], [ - "Belgium", - "-0.0206" + "Ghana", + "Mauritius", + "5574", + "910", + "Et Lacinia Vitae Foundation" ], [ - "Guam", - "-0.1694" + "Anguilla", + "Saint Kitts and Nevis", + "4801", + "281", + "Posuere Vulputate Institute" ], [ - "Egypt", - "-0.3251" + "Hong Kong", + "Jamaica", + "4619", + "330", + "Metus In Corp." ], [ - "Turkmenistan", - "-0.0347" + "Argentina", + "Burkina Faso", + "4254", + "239", + "Feugiat Incorporated" ], [ - "Vanuatu", - "0.0464" + "France", + "Australia", + "5102", + "412", + "Mi Lacinia PC" ], [ - "Mali", - "-0.4237" + "Moldova", + "Switzerland", + "1778", + "256", + "Nam Ac Nulla Corporation" ], [ - "Slovenia", - "0.2262" + "Paraguay", + "Haiti", + "8196", + "997", + "Sapien Aenean Massa Corporation" ], [ - "Mongolia", - "-0.1295" + "Fiji", + "Saint Lucia", + "8830", + "737", + "Enim Company" ], [ - "Paraguay", - "0.39" + "Cayman Islands", + "Lithuania", + "7107", + "443", + "Nulla Tincidunt Ltd" ], [ - "Zambia", - "0.2487" + "Latvia", + "Uganda", + "8353", + "844", + "Laoreet Lectus Company" ], [ - "Timor-Leste", - "0.3767" + "Sao Tome and Principe", + "Faroe Islands", + "1249", + "178", + "Euismod Est Arcu Corporation" ], [ - "Singapore", - "0.0347" + "Libya", + "Mauritania", + "9488", + "981", + "Tristique Neque Venenatis Associates" ], [ - "China", - "0.4352" + "Malta", + "Costa Rica", + "9390", + "279", + "Ipsum Curabitur Corp." ], [ - "Dominican Republic", - "0.032" + "Taiwan", + "Lithuania", + "6691", + "140", + "Accumsan Inc." ], [ - "Sint Maarten", - "0.0558" + "Cook Islands", + "American Samoa", + "8521", + "836", + "Turpis Corporation" ], [ - "Iran", - "-0.2898" + "Nepal", + "French Guiana", + "4042", + "922", + "Tempor Foundation" ], [ - "Azerbaijan", - "-0.4263" + "Tajikistan", + "Angola", + "1683", + "548", + "Parturient Montes Limited" ], [ - "Isle of Man", - "0.0565" + "Thailand", + "United States", + "2446", + "931", + "Tortor At Company" ], [ - "Trinidad and Tobago", - "0.0105" + "Gabon", + "French Southern Territories", + "5184", + "198", + "Non Massa Non Inc." ], [ - "Malta", - "0.0858" + "Wallis and Futuna", + "Czech Republic", + "1980", + "864", + "Blandit Ltd" ], [ - "Iraq", - "0.1162" + "Mauritania", + "Thailand", + "7273", + "323", + "A Aliquet Institute" ], [ - "Ghana", - "0.0011" + "Tajikistan", + "Uganda", + "2679", + "596", + "Ut Sem Limited" ], [ - "Morocco", - "0.3071" + "Sri Lanka", + "Korea, North", + "3760", + "268", + "Fusce LLP" ], [ - "Greece", - "-0.5361" + "Faroe Islands", + "Jamaica", + "2382", + "291", + "Eget Laoreet Limited" ], [ - "Poland", - "0.2016" + "Czech Republic", + "Georgia", + "9912", + "229", + "Mauris Incorporated" ], [ - "Bolivia", - "-0.7247" + "Kyrgyzstan", + "Kyrgyzstan", + "5827", + "154", + "Tincidunt Dui Foundation" ], [ - "Anguilla", - "-0.1922" + "Nauru", + "Malawi", + "4437", + "565", + "Ornare Lectus Ante Institute" ], [ - "Saint Vincent and The Grenadines", - "0.0358" + "Costa Rica", + "Korea, South", + "2001", + "391", + "Porta Elit Incorporated" ], [ - "Tokelau", - "0.021" + "Niger", + "Hungary", + "9037", + "424", + "Auctor Odio LLC" ], [ - "Chad", - "-0.1331" + "Svalbard and Jan Mayen Islands", + "Northern Mariana Islands", + "4144", + "826", + "Sit Amet Risus Incorporated" ], [ - "India", - "-0.0073" + "Czech Republic", + "Myanmar", + "6319", + "408", + "Ipsum Suspendisse Sagittis Inc." ], [ - "Tajikistan", - "0.1737" + "Myanmar", + "Belgium", + "1750", + "193", + "Etiam Laoreet Libero Incorporated" ], [ - "Saint Barthélemy", - "0.1724" + "Åland Islands", + "Heard Island and Mcdonald Islands", + "3558", + "903", + "Sed Pede LLP" ], [ - "Egypt", - "-0.5759" + "Ireland", + "Laos", + "1457", + "281", + "Ipsum Company" ], [ - "Nepal", - "0.2836" + "Chile", + "Armenia", + "2612", + "190", + "Proin Sed Limited" ], [ - "Saint Pierre and Miquelon", - "0.3836" + "American Samoa", + "Isle of Man", + "3438", + "279", + "Magna Corp." ], [ - "Cyprus", - "0.253" + "Gabon", + "Egypt", + "7199", + "695", + "Orci Luctus Et LLC" ], [ - "Seychelles", - "-0.2235" + "Uganda", + "Lesotho", + "9107", + "695", + "Sed Congue Institute" ], [ - "Samoa", - "0.4766" + "Kazakhstan", + "Reunion", + "9044", + "651", + "Donec Ltd" ], [ - "Gibraltar", - "-0.5111" + "Faroe Islands", + "Macao", + "9330", + "114", + "Ac Corp." ], [ - "Georgia", - "-0.0481" + "Western Sahara", + "French Guiana", + "2970", + "785", + "Maecenas Mi Felis Institute" ], [ - "Moldova", - "0.2778" + "Bermuda", + "Bangladesh", + "7803", + "448", + "Quis Associates" ], [ - "United Arab Emirates", - "0.0571" + "Luxembourg", + "Senegal", + "4314", + "120", + "Purus Consulting" ], [ - "Bonaire, Sint Eustatius and Saba", - "-0.0598" + "Martinique", + "Western Sahara", + "5530", + "167", + "Duis Industries" ], [ - "Mongolia", - "-0.1613" + "Andorra", + "Wallis and Futuna", + "5382", + "921", + "Orci Lacus Ltd" ], [ - "Maldives", - "-0.1707" + "Indonesia", + "Botswana", + "3973", + "705", + "Dignissim Maecenas Ornare Company" ], [ - "Lebanon", - "-0.2072" + "Honduras", + "Bahamas", + "1976", + "722", + "A Aliquet Consulting" ], [ - "Ethiopia", - "0.0483" + "Liechtenstein", + "Italy", + "1211", + "677", + "Sed Diam Lorem Consulting" ], [ - "Hungary", - "0.529" + "Sint Maarten", + "Guyana", + "7031", + "198", + "Consequat Auctor Nunc Ltd" ], [ - "Slovakia", - "-0.0181" + "Brunei", + "Curaçao", + "5838", + "624", + "Vel LLC" ], [ - "Afghanistan", - "-0.1582" + "Zambia", + "Saint Helena, Ascension and Tristan da Cunha", + "7406", + "870", + "Lobortis Nisi Company" ], [ - "Kyrgyzstan", - "-0.2432" + "Uganda", + "Saint Helena, Ascension and Tristan da Cunha", + "7936", + "970", + "Ipsum Corporation" ], [ - "Uganda", - "-0.3201" + "Wallis and Futuna", + "Cape Verde", + "5186", + "804", + "Vestibulum Limited" ], [ - "Malawi", - "-0.2205" + "Canada", + "Yemen", + "8890", + "530", + "Volutpat Corp." ], [ - "Serbia", - "0.2737" + "Isle of Man", + "Virgin Islands, United States", + "5980", + "648", + "Elit Inc." ], [ - "Liberia", - "0.1353" + "Bhutan", + "Venezuela", + "3237", + "392", + "Urna Suscipit Inc." ], [ - "Japan", - "0.5669" + "Ukraine", + "Zimbabwe", + "3986", + "391", + "Nec Mauris Blandit Corp." ], [ - "Mayotte", - "0.5685" + "Iceland", + "Cocos (Keeling) Islands", + "8042", + "974", + "Egestas Corporation" ], [ - "Papua New Guinea", - "-0.1687" + "Sao Tome and Principe", + "Angola", + "6664", + "614", + "Eget Industries" ], [ - "Curaçao", - "0.43" + "Sao Tome and Principe", + "Bangladesh", + "9717", + "607", + "Feugiat Metus PC" ], [ - "Mexico", - "0.2183" + "Sudan", + "Guam", + "2493", + "263", + "Nibh Vulputate LLC" ], [ - "Myanmar", - "-0.0774" + "Zimbabwe", + "Bermuda", + "9232", + "797", + "Non Enim Mauris Incorporated" ], [ - "Puerto Rico", - "0.099" + "Cuba", + "Tokelau", + "9000", + "607", + "Et Lacinia Vitae Foundation" ], [ - "Martinique", - "-0.028" + "Oman", + "Taiwan", + "9086", + "267", + "Nulla Company" ], [ - "Tanzania", - "-0.0047" + "Netherlands", + "Seychelles", + "5013", + "677", + "Maecenas LLC" ], [ - "American Samoa", - "-0.5019" + "Uruguay", + "Belarus", + "8181", + "483", + "Sit Amet Company" ], [ - "Saint Barthélemy", - "-0.2906" + "Puerto Rico", + "Tunisia", + "6798", + "840", + "Turpis Aliquam Adipiscing Institute" ], [ - "French Guiana", - "0.4136" + "Sudan", + "Solomon Islands", + "4848", + "857", + "Pede Et Risus LLP" ], [ - "Slovenia", - "0.2494" + "Côte D'Ivoire (Ivory Coast)", + "Thailand", + "3368", + "209", + "Pellentesque Habitant Morbi Associates" ], [ - "Somalia", - "0.2739" + "Portugal", + "Malawi", + "5744", + "508", + "Diam Limited" ], [ - "French Polynesia", - "-0.0177" + "Qatar", + "Russian Federation", + "6819", + "194", + "Eu Accumsan Company" ], [ - "Montserrat", - "0.1914" + "Iraq", + "Virgin Islands, British", + "7298", + "782", + "Congue A Industries" ], [ - "Syria", - "-0.0182" + "Haiti", + "Iceland", + "7574", + "605", + "Aliquet Phasellus Fermentum Institute" ], [ - "Ireland", - "-0.1243" + "Tuvalu", + "Saint Pierre and Miquelon", + "5543", + "812", + "Convallis In Cursus PC" ], [ - "Panama", - "-0.003" + "French Polynesia", + "Armenia", + "8464", + "406", + "Ipsum Leo Elementum LLP" ], [ - "Pitcairn Islands", - "0.1128" + "Ireland", + "Venezuela", + "2753", + "145", + "Vitae Aliquam Eros Limited" ], [ - "Sint Maarten", - "-0.2559" + "Isle of Man", + "Italy", + "1366", + "625", + "In Foundation" ], [ - "Virgin Islands, British", - "0.1381" + "Namibia", + "Dominica", + "2482", + "351", + "Quisque Varius Inc." ], [ - "Saint Kitts and Nevis", - "0.1776" + "Tonga", + "Antigua and Barbuda", + "6447", + "722", + "Elit Corporation" ], [ - "South Sudan", - "0.2227" + "Afghanistan", + "Somalia", + "4928", + "488", + "Nunc Quis Arcu Incorporated" ], [ - "Bahamas", - "-0.112" + "Venezuela", + "Martinique", + "3793", + "437", + "Commodo Consulting" ], [ - "Kuwait", - "0.0461" + "Mauritania", + "Ecuador", + "7082", + "319", + "Rutrum Lorem LLC" ] ], "metaData": { From ba3b9b7720a169f463e78b265f0cb933710a639f Mon Sep 17 00:00:00 2001 From: Nicolas Staub Date: Mon, 21 Dec 2020 08:45:42 +0100 Subject: [PATCH 25/29] fix in addEventListener for input event --- helpers/renderingInfoScript.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/helpers/renderingInfoScript.js b/helpers/renderingInfoScript.js index a4a47699..e174ca1d 100644 --- a/helpers/renderingInfoScript.js +++ b/helpers/renderingInfoScript.js @@ -258,7 +258,6 @@ function getSearchFormInputScript(context) { // Loop through all table rows ${dataObject}.tableElement.querySelectorAll('tbody tr').forEach( function(rowElement) { - foundString = false; // Loop through all text cells @@ -285,7 +284,7 @@ function getSearchFormInputScript(context) { } function ${searchFormInputAddEventListeners}() { - document.querySelector('.q-table__search__input').addEventListener('input', function(event) { + ${dataObject}.element.querySelector('.q-table__search__input').addEventListener('input', function(event) { var filter = event.target.value; if (filter.length < 2) { From ebc58a4b96d6ceabcaa67b45424358ca5efa9edf Mon Sep 17 00:00:00 2001 From: Nicolas Staub Date: Mon, 21 Dec 2020 16:29:45 +0100 Subject: [PATCH 26/29] add new fixture data --- .../fixtures/data/table-search-hidden.json | 556 +++----------- .../fixtures/data/table-search-show.json | 697 +----------------- .../table-search-with-multiple-columns.json | 143 ++++ routes/fixtures/data.js | 1 + tasks/updateFixtureData.js | 8 +- test/e2e-tests.js | 4 +- 6 files changed, 307 insertions(+), 1102 deletions(-) create mode 100644 resources/fixtures/data/table-search-with-multiple-columns.json diff --git a/resources/fixtures/data/table-search-hidden.json b/resources/fixtures/data/table-search-hidden.json index cc3c82d5..8a5a1523 100644 --- a/resources/fixtures/data/table-search-hidden.json +++ b/resources/fixtures/data/table-search-hidden.json @@ -1,442 +1,122 @@ { - "title": "FIXTURE: table search hide", - "data": { - "table": [ - [ - "Country", - "Number" - ], - [ - "Somalia", - "-0.1459" - ], - [ - "Honduras", - "0.2758" - ], - [ - "Malawi", - "-0.0534" - ], - [ - "Comoros", - "0.0111" - ], - [ - "Greece", - "-0.1775" - ], - [ - "Turkmenistan", - "0.0803" - ], - [ - "Panama", - "0.0164" - ], - [ - "Austria", - "-0.0462" - ], - [ - "Saint Barthélemy", - "-0.0247" - ], - [ - "Kazakhstan", - "-0.0067" - ], - [ - "Azerbaijan", - "0.044" - ], - [ - "Netherlands", - "0.2486" - ], - [ - "Yemen", - "-0.106" - ], - [ - "Sint Maarten", - "0.4218" - ], - [ - "Svalbard and Jan Mayen Islands", - "-0.1107" - ], - [ - "Belarus", - "-0.4466" - ], - [ - "China", - "-0.4345" - ], - [ - "Congo (Brazzaville)", - "-0.1386" - ], - [ - "Belgium", - "-0.0206" - ], - [ - "Guam", - "-0.1694" - ], - [ - "Egypt", - "-0.3251" - ], - [ - "Turkmenistan", - "-0.0347" - ], - [ - "Vanuatu", - "0.0464" - ], - [ - "Mali", - "-0.4237" - ], - [ - "Slovenia", - "0.2262" - ], - [ - "Mongolia", - "-0.1295" - ], - [ - "Paraguay", - "0.39" - ], - [ - "Zambia", - "0.2487" - ], - [ - "Timor-Leste", - "0.3767" - ], - [ - "Singapore", - "0.0347" - ], - [ - "China", - "0.4352" - ], - [ - "Dominican Republic", - "0.032" - ], - [ - "Sint Maarten", - "0.0558" - ], - [ - "Iran", - "-0.2898" - ], - [ - "Azerbaijan", - "-0.4263" - ], - [ - "Isle of Man", - "0.0565" - ], - [ - "Trinidad and Tobago", - "0.0105" - ], - [ - "Malta", - "0.0858" - ], - [ - "Iraq", - "0.1162" - ], - [ - "Ghana", - "0.0011" - ], - [ - "Morocco", - "0.3071" - ], - [ - "Greece", - "-0.5361" - ], - [ - "Poland", - "0.2016" - ], - [ - "Bolivia", - "-0.7247" - ], - [ - "Anguilla", - "-0.1922" - ], - [ - "Saint Vincent and The Grenadines", - "0.0358" - ], - [ - "Tokelau", - "0.021" - ], - [ - "Chad", - "-0.1331" - ], - [ - "India", - "-0.0073" - ], - [ - "Tajikistan", - "0.1737" - ], - [ - "Saint Barthélemy", - "0.1724" - ], - [ - "Egypt", - "-0.5759" - ], - [ - "Nepal", - "0.2836" - ], - [ - "Saint Pierre and Miquelon", - "0.3836" - ], - [ - "Cyprus", - "0.253" - ], - [ - "Seychelles", - "-0.2235" - ], - [ - "Samoa", - "0.4766" - ], - [ - "Gibraltar", - "-0.5111" - ], - [ - "Georgia", - "-0.0481" - ], - [ - "Moldova", - "0.2778" - ], - [ - "United Arab Emirates", - "0.0571" - ], - [ - "Bonaire, Sint Eustatius and Saba", - "-0.0598" - ], - [ - "Mongolia", - "-0.1613" - ], - [ - "Maldives", - "-0.1707" - ], - [ - "Lebanon", - "-0.2072" - ], - [ - "Ethiopia", - "0.0483" - ], - [ - "Hungary", - "0.529" - ], - [ - "Slovakia", - "-0.0181" - ], - [ - "Afghanistan", - "-0.1582" - ], - [ - "Kyrgyzstan", - "-0.2432" - ], - [ - "Uganda", - "-0.3201" - ], - [ - "Malawi", - "-0.2205" - ], - [ - "Serbia", - "0.2737" - ], - [ - "Liberia", - "0.1353" - ], - [ - "Japan", - "0.5669" - ], - [ - "Mayotte", - "0.5685" - ], - [ - "Papua New Guinea", - "-0.1687" - ], - [ - "Curaçao", - "0.43" - ], - [ - "Mexico", - "0.2183" - ], - [ - "Myanmar", - "-0.0774" - ], - [ - "Puerto Rico", - "0.099" - ], - [ - "Martinique", - "-0.028" - ], - [ - "Tanzania", - "-0.0047" - ], - [ - "American Samoa", - "-0.5019" - ], - [ - "Saint Barthélemy", - "-0.2906" - ], - [ - "French Guiana", - "0.4136" - ], - [ - "Slovenia", - "0.2494" - ], - [ - "Somalia", - "0.2739" - ], - [ - "French Polynesia", - "-0.0177" - ], - [ - "Montserrat", - "0.1914" - ], - [ - "Syria", - "-0.0182" - ], - [ - "Ireland", - "-0.1243" - ], - [ - "Panama", - "-0.003" - ], - [ - "Pitcairn Islands", - "0.1128" - ], - [ - "Sint Maarten", - "-0.2559" - ], - [ - "Virgin Islands, British", - "0.1381" - ], - [ - "Saint Kitts and Nevis", - "0.1776" - ], - [ - "South Sudan", - "0.2227" - ], - [ - "Bahamas", - "-0.112" - ], - [ - "Kuwait", - "0.0461" - ] + "title": "FIXTURE: table search hide", + "data": { + "table": [ + [ + "Country", + "Number" ], - "metaData": { - "cells": [] - } - }, - "sources": [ - { - "link": {}, - "text": "The Very Important Center For Very Important Data" - } + [ + "Somalia", + "-0.1459" + ], + [ + "Honduras", + "0.2758" + ], + [ + "Malawi", + "-0.0534" + ], + [ + "Comoros", + "0.0111" + ], + [ + "Greece", + "-0.1775" + ], + [ + "Turkmenistan", + "0.0803" + ], + [ + "Panama", + "0.0164" + ], + [ + "Austria", + "-0.0462" + ], + [ + "Saint Barthélemy", + "-0.0247" + ], + [ + "Kazakhstan", + "-0.0067" + ], + [ + "Azerbaijan", + "0.044" + ], + [ + "Netherlands", + "0.2486" + ], + [ + "Yemen", + "-0.106" + ], + [ + "Sint Maarten", + "0.4218" + ], + [ + "Svalbard and Jan Mayen Islands", + "-0.1107" + ], + [ + "Belarus", + "-0.4466" + ], + [ + "China", + "-0.4345" + ], + [ + "Congo (Brazzaville)", + "-0.1386" + ], + [ + "Belgium", + "-0.0206" + ], + [ + "Poland", + "0.2016" + ] ], - "options": { - "hideTableHeader": false, - "showTableSearch": false, - "cardLayout": false, - "cardLayoutIfSmall": true, - "minibar": { - "invertColors": false, - "barColor": { - "positive": { - "className": "", - "colorCode": "" - }, - "negative": { - "className": "", - "colorCode": "" - } - }, - "selectedColumn": null + "metaData": { + "cells": [] + } + }, + "sources": [ + { + "link": {}, + "text": "The Very Important Center For Very Important Data" + } + ], + "options": { + "hideTableHeader": false, + "showTableSearch": false, + "cardLayout": false, + "cardLayoutIfSmall": true, + "minibar": { + "invertColors": false, + "barColor": { + "positive": { + "className": "", + "colorCode": "" + }, + "negative": { + "className": "", + "colorCode": "" } - }, - "tool": "table", - "subtitle": "Very important data country by country" - } \ No newline at end of file + }, + "selectedColumn": null + } + }, + "tool": "table", + "subtitle": "Very important data country by country" +} \ No newline at end of file diff --git a/resources/fixtures/data/table-search-show.json b/resources/fixtures/data/table-search-show.json index 1cfce282..b89930c9 100644 --- a/resources/fixtures/data/table-search-show.json +++ b/resources/fixtures/data/table-search-show.json @@ -3,711 +3,88 @@ "data": { "table": [ [ - "Country 1", - "Country 2", - "Number 1", - "Number 2", - "Company 1" - ], - [ - "Marshall Islands", - "San Marino", - "4018", - "636", - "Sed Libero Proin Corp." - ], - [ - "Iran", - "Antigua and Barbuda", - "9722", - "419", - "Orci Lacus Incorporated" - ], - [ - "Falkland Islands", - "Saint Barthélemy", - "8062", - "991", - "Eleifend Non Incorporated" - ], - [ - "Madagascar", - "Mexico", - "3518", - "698", - "Arcu Et Pede Limited" - ], - [ - "Tanzania", - "United States Minor Outlying Islands", - "8799", - "233", - "Parturient Montes Nascetur LLC" - ], - [ - "Ireland", - "Russian Federation", - "4996", - "447", - "Nunc Commodo Incorporated" - ], - [ - "Pakistan", - "Norway", - "4706", - "527", - "Orci Phasellus Dapibus Foundation" - ], - [ - "Cuba", - "Korea, South", - "9900", - "946", - "Imperdiet Corporation" - ], - [ - "Lebanon", - "United Arab Emirates", - "6943", - "988", - "Lorem Vitae Odio Institute" - ], - [ - "Maldives", - "Brazil", - "6868", - "134", - "Eu Corp." - ], - [ - "Cape Verde", - "Comoros", - "5269", - "746", - "Ante Inc." - ], - [ - "Seychelles", - "Western Sahara", - "1891", - "636", - "Tempor Arcu Company" - ], - [ - "El Salvador", - "Montenegro", - "7089", - "735", - "Fringilla Donec Corp." - ], - [ - "Montenegro", - "Japan", - "1565", - "415", - "Malesuada Id LLP" + "Country", + "Number" ], [ "Somalia", - "Ghana", - "2436", - "732", - "Pellentesque A Foundation" - ], - [ - "Haiti", - "Faroe Islands", - "7910", - "140", - "Tempus Non Foundation" - ], - [ - "Botswana", - "Tonga", - "2868", - "854", - "Malesuada Augue Institute" - ], - [ - "Dominica", - "Saudi Arabia", - "9885", - "667", - "Suspendisse Sagittis Nullam Associates" - ], - [ - "Ghana", - "Mauritius", - "5574", - "910", - "Et Lacinia Vitae Foundation" - ], - [ - "Anguilla", - "Saint Kitts and Nevis", - "4801", - "281", - "Posuere Vulputate Institute" - ], - [ - "Hong Kong", - "Jamaica", - "4619", - "330", - "Metus In Corp." - ], - [ - "Argentina", - "Burkina Faso", - "4254", - "239", - "Feugiat Incorporated" + "-0.1459" ], [ - "France", - "Australia", - "5102", - "412", - "Mi Lacinia PC" - ], - [ - "Moldova", - "Switzerland", - "1778", - "256", - "Nam Ac Nulla Corporation" - ], - [ - "Paraguay", - "Haiti", - "8196", - "997", - "Sapien Aenean Massa Corporation" - ], - [ - "Fiji", - "Saint Lucia", - "8830", - "737", - "Enim Company" - ], - [ - "Cayman Islands", - "Lithuania", - "7107", - "443", - "Nulla Tincidunt Ltd" - ], - [ - "Latvia", - "Uganda", - "8353", - "844", - "Laoreet Lectus Company" - ], - [ - "Sao Tome and Principe", - "Faroe Islands", - "1249", - "178", - "Euismod Est Arcu Corporation" - ], - [ - "Libya", - "Mauritania", - "9488", - "981", - "Tristique Neque Venenatis Associates" - ], - [ - "Malta", - "Costa Rica", - "9390", - "279", - "Ipsum Curabitur Corp." - ], - [ - "Taiwan", - "Lithuania", - "6691", - "140", - "Accumsan Inc." - ], - [ - "Cook Islands", - "American Samoa", - "8521", - "836", - "Turpis Corporation" - ], - [ - "Nepal", - "French Guiana", - "4042", - "922", - "Tempor Foundation" - ], - [ - "Tajikistan", - "Angola", - "1683", - "548", - "Parturient Montes Limited" - ], - [ - "Thailand", - "United States", - "2446", - "931", - "Tortor At Company" - ], - [ - "Gabon", - "French Southern Territories", - "5184", - "198", - "Non Massa Non Inc." - ], - [ - "Wallis and Futuna", - "Czech Republic", - "1980", - "864", - "Blandit Ltd" - ], - [ - "Mauritania", - "Thailand", - "7273", - "323", - "A Aliquet Institute" - ], - [ - "Tajikistan", - "Uganda", - "2679", - "596", - "Ut Sem Limited" - ], - [ - "Sri Lanka", - "Korea, North", - "3760", - "268", - "Fusce LLP" - ], - [ - "Faroe Islands", - "Jamaica", - "2382", - "291", - "Eget Laoreet Limited" - ], - [ - "Czech Republic", - "Georgia", - "9912", - "229", - "Mauris Incorporated" - ], - [ - "Kyrgyzstan", - "Kyrgyzstan", - "5827", - "154", - "Tincidunt Dui Foundation" + "Honduras", + "0.2758" ], [ - "Nauru", "Malawi", - "4437", - "565", - "Ornare Lectus Ante Institute" - ], - [ - "Costa Rica", - "Korea, South", - "2001", - "391", - "Porta Elit Incorporated" - ], - [ - "Niger", - "Hungary", - "9037", - "424", - "Auctor Odio LLC" - ], - [ - "Svalbard and Jan Mayen Islands", - "Northern Mariana Islands", - "4144", - "826", - "Sit Amet Risus Incorporated" - ], - [ - "Czech Republic", - "Myanmar", - "6319", - "408", - "Ipsum Suspendisse Sagittis Inc." - ], - [ - "Myanmar", - "Belgium", - "1750", - "193", - "Etiam Laoreet Libero Incorporated" + "-0.0534" ], [ - "Åland Islands", - "Heard Island and Mcdonald Islands", - "3558", - "903", - "Sed Pede LLP" + "Comoros", + "0.0111" ], [ - "Ireland", - "Laos", - "1457", - "281", - "Ipsum Company" + "Greece", + "-0.1775" ], [ - "Chile", - "Armenia", - "2612", - "190", - "Proin Sed Limited" + "Turkmenistan", + "0.0803" ], [ - "American Samoa", - "Isle of Man", - "3438", - "279", - "Magna Corp." + "Panama", + "0.0164" ], [ - "Gabon", - "Egypt", - "7199", - "695", - "Orci Luctus Et LLC" + "Austria", + "-0.0462" ], [ - "Uganda", - "Lesotho", - "9107", - "695", - "Sed Congue Institute" + "Saint Barthélemy", + "-0.0247" ], [ "Kazakhstan", - "Reunion", - "9044", - "651", - "Donec Ltd" - ], - [ - "Faroe Islands", - "Macao", - "9330", - "114", - "Ac Corp." - ], - [ - "Western Sahara", - "French Guiana", - "2970", - "785", - "Maecenas Mi Felis Institute" - ], - [ - "Bermuda", - "Bangladesh", - "7803", - "448", - "Quis Associates" - ], - [ - "Luxembourg", - "Senegal", - "4314", - "120", - "Purus Consulting" - ], - [ - "Martinique", - "Western Sahara", - "5530", - "167", - "Duis Industries" - ], - [ - "Andorra", - "Wallis and Futuna", - "5382", - "921", - "Orci Lacus Ltd" - ], - [ - "Indonesia", - "Botswana", - "3973", - "705", - "Dignissim Maecenas Ornare Company" - ], - [ - "Honduras", - "Bahamas", - "1976", - "722", - "A Aliquet Consulting" - ], - [ - "Liechtenstein", - "Italy", - "1211", - "677", - "Sed Diam Lorem Consulting" - ], - [ - "Sint Maarten", - "Guyana", - "7031", - "198", - "Consequat Auctor Nunc Ltd" - ], - [ - "Brunei", - "Curaçao", - "5838", - "624", - "Vel LLC" - ], - [ - "Zambia", - "Saint Helena, Ascension and Tristan da Cunha", - "7406", - "870", - "Lobortis Nisi Company" + "-0.0067" ], [ - "Uganda", - "Saint Helena, Ascension and Tristan da Cunha", - "7936", - "970", - "Ipsum Corporation" + "Azerbaijan", + "0.044" ], [ - "Wallis and Futuna", - "Cape Verde", - "5186", - "804", - "Vestibulum Limited" + "Netherlands", + "0.2486" ], [ - "Canada", "Yemen", - "8890", - "530", - "Volutpat Corp." - ], - [ - "Isle of Man", - "Virgin Islands, United States", - "5980", - "648", - "Elit Inc." - ], - [ - "Bhutan", - "Venezuela", - "3237", - "392", - "Urna Suscipit Inc." + "-0.106" ], [ - "Ukraine", - "Zimbabwe", - "3986", - "391", - "Nec Mauris Blandit Corp." - ], - [ - "Iceland", - "Cocos (Keeling) Islands", - "8042", - "974", - "Egestas Corporation" - ], - [ - "Sao Tome and Principe", - "Angola", - "6664", - "614", - "Eget Industries" - ], - [ - "Sao Tome and Principe", - "Bangladesh", - "9717", - "607", - "Feugiat Metus PC" - ], - [ - "Sudan", - "Guam", - "2493", - "263", - "Nibh Vulputate LLC" - ], - [ - "Zimbabwe", - "Bermuda", - "9232", - "797", - "Non Enim Mauris Incorporated" - ], - [ - "Cuba", - "Tokelau", - "9000", - "607", - "Et Lacinia Vitae Foundation" - ], - [ - "Oman", - "Taiwan", - "9086", - "267", - "Nulla Company" + "Sint Maarten", + "0.4218" ], [ - "Netherlands", - "Seychelles", - "5013", - "677", - "Maecenas LLC" + "Svalbard and Jan Mayen Islands", + "-0.1107" ], [ - "Uruguay", "Belarus", - "8181", - "483", - "Sit Amet Company" - ], - [ - "Puerto Rico", - "Tunisia", - "6798", - "840", - "Turpis Aliquam Adipiscing Institute" - ], - [ - "Sudan", - "Solomon Islands", - "4848", - "857", - "Pede Et Risus LLP" - ], - [ - "Côte D'Ivoire (Ivory Coast)", - "Thailand", - "3368", - "209", - "Pellentesque Habitant Morbi Associates" - ], - [ - "Portugal", - "Malawi", - "5744", - "508", - "Diam Limited" - ], - [ - "Qatar", - "Russian Federation", - "6819", - "194", - "Eu Accumsan Company" - ], - [ - "Iraq", - "Virgin Islands, British", - "7298", - "782", - "Congue A Industries" - ], - [ - "Haiti", - "Iceland", - "7574", - "605", - "Aliquet Phasellus Fermentum Institute" - ], - [ - "Tuvalu", - "Saint Pierre and Miquelon", - "5543", - "812", - "Convallis In Cursus PC" - ], - [ - "French Polynesia", - "Armenia", - "8464", - "406", - "Ipsum Leo Elementum LLP" + "-0.4466" ], [ - "Ireland", - "Venezuela", - "2753", - "145", - "Vitae Aliquam Eros Limited" + "China", + "-0.4345" ], [ - "Isle of Man", - "Italy", - "1366", - "625", - "In Foundation" + "Congo (Brazzaville)", + "-0.1386" ], [ - "Namibia", - "Dominica", - "2482", - "351", - "Quisque Varius Inc." - ], - [ - "Tonga", - "Antigua and Barbuda", - "6447", - "722", - "Elit Corporation" - ], - [ - "Afghanistan", - "Somalia", - "4928", - "488", - "Nunc Quis Arcu Incorporated" - ], - [ - "Venezuela", - "Martinique", - "3793", - "437", - "Commodo Consulting" + "Belgium", + "-0.0206" ], [ - "Mauritania", - "Ecuador", - "7082", - "319", - "Rutrum Lorem LLC" + "Poland", + "0.2016" ] ], "metaData": { diff --git a/resources/fixtures/data/table-search-with-multiple-columns.json b/resources/fixtures/data/table-search-with-multiple-columns.json new file mode 100644 index 00000000..eaf2a68e --- /dev/null +++ b/resources/fixtures/data/table-search-with-multiple-columns.json @@ -0,0 +1,143 @@ +{ + "title": "FIXTURE: table search with multiple columns", + "data": { + "table": [ + [ + "Country", + "City", + "Company" + ], + [ + "Italy", + "Bondo", + "Nisi Sem Consulting" + ], + [ + "Austria", + "Traiskirchen", + "In Incorporated" + ], + [ + "Italy", + "Romano d'Ezzelino", + "Lacus LLP" + ], + [ + "France", + "Nancy", + "Nam Company" + ], + [ + "France", + "Liévin", + "Sit Amet Ornare Foundation" + ], + [ + "Germany", + "Greifswald", + "Magna Tellus Faucibus PC" + ], + [ + "Germany", + "Rostock", + "Vulputate Risus Institute" + ], + [ + "Italy", + "Jerzu", + "Sapien Nunc Corporation" + ], + [ + "Italy", + "Salvirola", + "Suspendisse Sagittis Nullam Limited" + ], + [ + "France", + "Besançon", + "Adipiscing Foundation" + ], + [ + "Italy", + "Monghidoro", + "Ac Arcu Nunc Limited" + ], + [ + "Austria", + "Graz", + "Dictum Limited" + ], + [ + "France", + "Brive-la-Gaillarde", + "Ut Company" + ], + [ + "Italy", + "Melazzo", + "Non Feugiat Institute" + ], + [ + "Austria", + "St. Pölten", + "Nunc Quisque Ornare Corp." + ], + [ + "France", + "Colmar", + "Sed Facilisis Foundation" + ], + [ + "Germany", + "Karlsruhe", + "In Associates" + ], + [ + "Germany", + "Grimma", + "Suscipit Nonummy Corp." + ], + [ + "Austria", + "Bad Ischl", + "Adipiscing LLC" + ], + [ + "Italy", + "Romano d'Ezzelino", + "Lacus LLP" + ] + ], + "metaData": { + "cells": [] + } + }, + "sources": [ + { + "link": {}, + "text": "The Very Important Center For Very Important Data" + } + ], + "options": { + "hideTableHeader": false, + "showTableSearch": true, + "cardLayout": false, + "cardLayoutIfSmall": true, + "minibar": { + "invertColors": false, + "barColor": { + "positive": { + "className": "", + "colorCode": "" + }, + "negative": { + "className": "", + "colorCode": "" + } + }, + "selectedColumn": null + } + }, + "tool": "table", + "subtitle": "Very important data country by country" +} \ No newline at end of file diff --git a/routes/fixtures/data.js b/routes/fixtures/data.js index a32686d0..c07bd80e 100644 --- a/routes/fixtures/data.js +++ b/routes/fixtures/data.js @@ -37,6 +37,7 @@ const fixtureData = [ require(`${fixtureDataDirectory}/formatted-numbers-negative.json`), require(`${fixtureDataDirectory}/table-search-hidden.json`), require(`${fixtureDataDirectory}/table-search-show.json`), + require(`${fixtureDataDirectory}/table-search-with-multiple-columns.json`), ]; module.exports = { diff --git a/tasks/updateFixtureData.js b/tasks/updateFixtureData.js index 313efa0f..fac92805 100644 --- a/tasks/updateFixtureData.js +++ b/tasks/updateFixtureData.js @@ -131,13 +131,17 @@ const fixtureData = [ `${fixtureDataDirectory}/formatted-number-negative.json`, require(`${fixtureDataDirectory}/formatted-number-negative.json`), ], + [ + `${fixtureDataDirectory}/table-search-hidden.json`, + require(`${fixtureDataDirectory}/table-search-hidden.json`), + ], [ `${fixtureDataDirectory}/table-search-show.json`, require(`${fixtureDataDirectory}/table-search-show.json`), ], [ - `${fixtureDataDirectory}/table-search-hidden.json`, - require(`${fixtureDataDirectory}/table-search-hidden.json`), + `${fixtureDataDirectory}/table-search-with-multiple-columns.json`, + require(`${fixtureDataDirectory}/table-search-with-multiple-columns.json`), ], ]; diff --git a/test/e2e-tests.js b/test/e2e-tests.js index 5a5983cc..f09225d3 100644 --- a/test/e2e-tests.js +++ b/test/e2e-tests.js @@ -166,9 +166,9 @@ lab.experiment("dynamic schema endpoint", () => { }); lab.experiment("fixture data endpoint", () => { - it("returns 35 fixture data items for /fixtures/data", async () => { + it("returns 36 fixture data items for /fixtures/data", async () => { const response = await server.inject("/fixtures/data"); expect(response.statusCode).to.be.equal(200); - expect(response.result.length).to.be.equal(35); + expect(response.result.length).to.be.equal(36); }); }); From 6a59a0049c340bd8f629c772798420fdc260e5eb Mon Sep 17 00:00:00 2001 From: Nicolas Staub Date: Mon, 21 Dec 2020 17:25:22 +0100 Subject: [PATCH 27/29] changed fixture data --- .../table-search-with-multiple-columns.json | 133 ++++++++++-------- 1 file changed, 77 insertions(+), 56 deletions(-) diff --git a/resources/fixtures/data/table-search-with-multiple-columns.json b/resources/fixtures/data/table-search-with-multiple-columns.json index eaf2a68e..0d5a192a 100644 --- a/resources/fixtures/data/table-search-with-multiple-columns.json +++ b/resources/fixtures/data/table-search-with-multiple-columns.json @@ -3,109 +3,130 @@ "data": { "table": [ [ - "Country", - "City", - "Company" + "Country 1", + "Value 1", + "Country 2", + "Value 2" ], [ - "Italy", - "Bondo", - "Nisi Sem Consulting" + "Netherlands", + "orange", + "Netherlands", + "green" ], [ "Austria", - "Traiskirchen", - "In Incorporated" + "red", + "Netherlands", + "yellow" ], [ "Italy", - "Romano d'Ezzelino", - "Lacus LLP" - ], - [ + "red", "France", - "Nancy", - "Nam Company" + "red" ], [ - "France", - "Liévin", - "Sit Amet Ornare Foundation" + "Netherlands", + "yellow", + "Spain", + "orange" ], [ + "Italy", + "yellow", "Germany", - "Greifswald", - "Magna Tellus Faucibus PC" + "orange" ], [ - "Germany", - "Rostock", - "Vulputate Risus Institute" + "Italy", + "orange", + "Belgium", + "yellow" ], [ - "Italy", - "Jerzu", - "Sapien Nunc Corporation" + "Poland", + "green", + "Poland", + "orange" ], [ "Italy", - "Salvirola", - "Suspendisse Sagittis Nullam Limited" + "orange", + "Germany", + "red" ], [ - "France", - "Besançon", - "Adipiscing Foundation" + "Belgium", + "yellow", + "Spain", + "green" ], [ - "Italy", - "Monghidoro", - "Ac Arcu Nunc Limited" + "Spain", + "green", + "Germany", + "orange" ], [ - "Austria", - "Graz", - "Dictum Limited" + "Poland", + "red", + "Poland", + "green" ], [ - "France", - "Brive-la-Gaillarde", - "Ut Company" + "Italy", + "yellow", + "Poland", + "orange" ], [ + "Netherlands", + "yellow", "Italy", - "Melazzo", - "Non Feugiat Institute" + "green" ], [ - "Austria", - "St. Pölten", - "Nunc Quisque Ornare Corp." + "Belgium", + "green", + "Belgium", + "orange" + ], + [ + "Germany", + "yellow", + "Spain", + "orange" ], [ "France", - "Colmar", - "Sed Facilisis Foundation" + "green", + "Italy", + "orange" ], [ - "Germany", - "Karlsruhe", - "In Associates" + "Poland", + "green", + "Poland", + "orange" ], [ "Germany", - "Grimma", - "Suscipit Nonummy Corp." + "yellow", + "Austria", + "orange" ], [ + "Italy", + "orange", "Austria", - "Bad Ischl", - "Adipiscing LLC" + "orange" ], [ - "Italy", - "Romano d'Ezzelino", - "Lacus LLP" + "France", + "orange", + "Netherlands", + "yellow" ] ], "metaData": { From a4cb291cca01d8c197525de84092452aa4f0e586 Mon Sep 17 00:00:00 2001 From: Philip Kueng Date: Tue, 22 Dec 2020 10:58:54 +0100 Subject: [PATCH 28/29] release-3.4.0 --- package-lock.json | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index fe408ce4..e7ec65d5 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "q-table", - "version": "3.2.1", + "version": "3.4.0", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index b1215224..3fc61da1 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "q-table", - "version": "3.2.1", + "version": "3.4.0", "description": "", "main": "index.js", "scripts": { From fb50b34ab52055eaeb575c9dc23ce3f94577ac2e Mon Sep 17 00:00:00 2001 From: Philip Kueng Date: Tue, 22 Dec 2020 11:00:19 +0100 Subject: [PATCH 29/29] npm update --- package-lock.json | 71 +++++++++++++++++++++-------------------------- package.json | 14 +++++----- 2 files changed, 39 insertions(+), 46 deletions(-) diff --git a/package-lock.json b/package-lock.json index e7ec65d5..53e12ab2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -164,18 +164,11 @@ } }, "@hapi/boom": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/@hapi/boom/-/boom-9.1.0.tgz", - "integrity": "sha512-4nZmpp4tXbm162LaZT45P7F7sgiem8dwAh2vHWT6XX24dozNjGMg6BvKCRvtCUcmcXqeMIUqWN8Rc5X8yKuROQ==", + "version": "9.1.1", + "resolved": "https://registry.npmjs.org/@hapi/boom/-/boom-9.1.1.tgz", + "integrity": "sha512-VNR8eDbBrOxBgbkddRYIe7+8DZ+vSbV6qlmaN2x7eWjsUjy2VmQgChkOKcVZIeupEZYj+I0dqNg430OhwzagjA==", "requires": { "@hapi/hoek": "9.x.x" - }, - "dependencies": { - "@hapi/hoek": { - "version": "9.0.4", - "resolved": "https://registry.npmjs.org/@hapi/hoek/-/hoek-9.0.4.tgz", - "integrity": "sha512-EwaJS7RjoXUZ2cXXKZZxZqieGtc7RbvQhUy8FwDoMQtxWVi14tFjeFCYPZAM1mBCpOpiBpyaZbb9NeHc7eGKgw==" - } } }, "@hapi/bossy": { @@ -327,16 +320,16 @@ "integrity": "sha512-EwaJS7RjoXUZ2cXXKZZxZqieGtc7RbvQhUy8FwDoMQtxWVi14tFjeFCYPZAM1mBCpOpiBpyaZbb9NeHc7eGKgw==" }, "@hapi/inert": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/@hapi/inert/-/inert-6.0.2.tgz", - "integrity": "sha512-cq0a8jstkLW1+oJaw4jp52PZBEkVbX9d0YDy5aOs3rOKYSjpzs2nQBahnCHEMchOrOSUffLpE+IDoivYHcx8uA==", + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/@hapi/inert/-/inert-6.0.3.tgz", + "integrity": "sha512-Z6Pi0Wsn2pJex5CmBaq+Dky9q40LGzXLUIUFrYpDtReuMkmfy9UuUeYc4064jQ1Xe9uuw7kbwE6Fq6rqKAdjAg==", "requires": { "@hapi/ammo": "5.x.x", "@hapi/boom": "9.x.x", "@hapi/bounce": "2.x.x", "@hapi/hoek": "9.x.x", "@hapi/validate": "1.x.x", - "lru-cache": "5.x.x" + "lru-cache": "^6.0.0" } }, "@hapi/iron": { @@ -692,9 +685,9 @@ "dev": true }, "ajv": { - "version": "6.12.3", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.3.tgz", - "integrity": "sha512-4K0cK3L1hsqk9xIb2z9vs/XU+PGJZ9PNpJRDS9YLzmNdX6jmVPfamLvTJr0aDAusnHyCHO6MjzlkAsgtqp9teA==", + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", "requires": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", @@ -1385,9 +1378,9 @@ } }, "d3-format": { - "version": "1.4.4", - "resolved": "https://registry.npmjs.org/d3-format/-/d3-format-1.4.4.tgz", - "integrity": "sha512-TWks25e7t8/cqctxCmxpUuzZN11QxIA7YrMbram94zMQ0PXjE4LVIMe/f6a4+xxL8HQ3OsAFULOINQi1pE62Aw==" + "version": "1.4.5", + "resolved": "https://registry.npmjs.org/d3-format/-/d3-format-1.4.5.tgz", + "integrity": "sha512-J0piedu6Z8iB6TbIGfZgDzfXxUFN3qQRMofy2oPdXzQibYGqPB/9iMcxr/TGalU+2RsyDO+U4f33id8tbnSRMQ==" }, "dashdash": { "version": "1.14.1", @@ -2536,11 +2529,11 @@ "dev": true }, "lru-cache": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz", - "integrity": "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", "requires": { - "yallist": "^3.0.2" + "yallist": "^4.0.0" } }, "mdn-data": { @@ -2869,9 +2862,9 @@ "dev": true }, "postcss": { - "version": "7.0.32", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.32.tgz", - "integrity": "sha512-03eXong5NLnNCD05xscnGKGDZ98CyzoqPSMjOe6SuoQY7Z2hIj0Ld1g/O/UQRuOle2aRtiIRDg9tDcTGAkLfKw==", + "version": "7.0.35", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-7.0.35.tgz", + "integrity": "sha512-3QT8bBJeX/S5zKTTjTCIjRF3If4avAT6kqxcASlTWEtAFCb9NH0OUxNDfgZSWdP5fJnBYCMEWkIFfWeugjzYMg==", "dev": true, "requires": { "chalk": "^2.4.2", @@ -3469,9 +3462,9 @@ "dev": true }, "sass": { - "version": "1.26.10", - "resolved": "https://registry.npmjs.org/sass/-/sass-1.26.10.tgz", - "integrity": "sha512-bzN0uvmzfsTvjz0qwccN1sPm2HxxpNI/Xa+7PlUEMS+nQvbyuEK7Y0qFqxlPHhiNHb1Ze8WQJtU31olMObkAMw==", + "version": "1.30.0", + "resolved": "https://registry.npmjs.org/sass/-/sass-1.30.0.tgz", + "integrity": "sha512-26EUhOXRLaUY7+mWuRFqGeGGNmhB1vblpTENO1Z7mAzzIZeVxZr9EZoaY1kyGLFWdSOZxRMAufiN2mkbO6dAlw==", "dev": true, "requires": { "chokidar": ">=2.0.0 <4.0.0" @@ -3865,9 +3858,9 @@ "dev": true }, "uglify-js": { - "version": "3.10.1", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.10.1.tgz", - "integrity": "sha512-RjxApKkrPJB6kjJxQS3iZlf///REXWYxYJxO/MpmlQzVkDWVI3PSnCBWezMecmTU/TRkNxrl8bmsfFQCp+LO+Q==" + "version": "3.12.2", + "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.12.2.tgz", + "integrity": "sha512-rWYleAvfJPjduYCt+ELvzybNah/zIkRteGXIBO8X0lteRZPGladF61hFi8tU7qKTsF7u6DUQCtT9k00VlFOgkg==" }, "uniq": { "version": "1.0.1", @@ -3894,9 +3887,9 @@ "dev": true }, "uri-js": { - "version": "4.2.2", - "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", - "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", + "version": "4.4.0", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.0.tgz", + "integrity": "sha512-B0yRTzYdUCCn9n+F4+Gh4yIDtMQcaJsmYBDsTSG8g/OejKBodLQ2IHfN3bM7jUsRXndopT7OIXWdYqc1fjmV6g==", "requires": { "punycode": "^2.1.0" } @@ -4059,9 +4052,9 @@ "dev": true }, "yallist": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz", - "integrity": "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==" + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" } } } diff --git a/package.json b/package.json index 3fc61da1..8d42ba64 100644 --- a/package.json +++ b/package.json @@ -11,16 +11,16 @@ "author": "Beni Buess ", "license": "MIT", "dependencies": { - "@hapi/boom": "^9.1.0", + "@hapi/boom": "^9.1.1", "@hapi/hapi": "^19.2.0", - "@hapi/inert": "^6.0.2", + "@hapi/inert": "^6.0.3", "@hapi/joi": "^17.1.1", - "ajv": "^6.12.3", + "ajv": "^6.12.6", "array2d": "0.0.5", "clone": "^2.1.2", - "d3-format": "^1.4.4", + "d3-format": "^1.4.5", "nunjucks": "^3.2.2", - "uglify-js": "^3.10.1" + "uglify-js": "^3.12.2" }, "devDependencies": { "@hapi/code": "^8.0.2", @@ -29,8 +29,8 @@ "cssnano": "^4.1.10", "html-minifier": "^4.0.0", "jsdom": "^16.4.0", - "postcss": "^7.0.32", + "postcss": "^7.0.35", "postcss-import": "^12.0.1", - "sass": "^1.26.10" + "sass": "^1.30.0" } }