From c367f24dd9b46d3a0b54a891f31bcb38c557e62f Mon Sep 17 00:00:00 2001 From: Kristoffer Lind Date: Thu, 21 Feb 2019 17:32:16 +0100 Subject: [PATCH 1/2] replace jquery scroll linking with components (fixing some bugs and getting rid of jquery) --- package-lock.json | 108 +++++++++++++ package.json | 1 + src/data-table/index.jsx | 165 ++++++++++---------- src/headers-table/index.jsx | 163 +++++++++---------- src/linked-scroll/index.js | 2 + src/linked-scroll/linked-scroll-section.jsx | 29 ++++ src/linked-scroll/linked-scroll-wrapper.jsx | 82 ++++++++++ src/main.less | 58 ++++--- src/paint.jsx | 63 ++++---- webpack.config.js | 43 ++--- 10 files changed, 480 insertions(+), 234 deletions(-) create mode 100644 src/linked-scroll/index.js create mode 100644 src/linked-scroll/linked-scroll-section.jsx create mode 100644 src/linked-scroll/linked-scroll-wrapper.jsx diff --git a/package-lock.json b/package-lock.json index 565fea0..dacfa21 100644 --- a/package-lock.json +++ b/package-lock.json @@ -101,6 +101,104 @@ "@babel/types": "^7.0.0" } }, + "@babel/helper-create-class-features-plugin": { + "version": "7.3.2", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.3.2.tgz", + "integrity": "sha512-tdW8+V8ceh2US4GsYdNVNoohq5uVwOf9k6krjwW4E1lINcHgttnWcNqgdoessn12dAy8QkbezlbQh2nXISNY+A==", + "dev": true, + "requires": { + "@babel/helper-function-name": "^7.1.0", + "@babel/helper-member-expression-to-functions": "^7.0.0", + "@babel/helper-optimise-call-expression": "^7.0.0", + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/helper-replace-supers": "^7.2.3" + }, + "dependencies": { + "@babel/generator": { + "version": "7.3.3", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.3.3.tgz", + "integrity": "sha512-aEADYwRRZjJyMnKN7llGIlircxTCofm3dtV5pmY6ob18MSIuipHpA2yZWkPlycwu5HJcx/pADS3zssd8eY7/6A==", + "dev": true, + "requires": { + "@babel/types": "^7.3.3", + "jsesc": "^2.5.1", + "lodash": "^4.17.11", + "source-map": "^0.5.0", + "trim-right": "^1.0.1" + }, + "dependencies": { + "@babel/types": { + "version": "7.3.3", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.3.3.tgz", + "integrity": "sha512-2tACZ80Wg09UnPg5uGAOUvvInaqLk3l/IAhQzlxLQOIXacr6bMsra5SH6AWw/hIDRCSbCdHP2KzSOD+cT7TzMQ==", + "dev": true, + "requires": { + "esutils": "^2.0.2", + "lodash": "^4.17.11", + "to-fast-properties": "^2.0.0" + } + } + } + }, + "@babel/helper-replace-supers": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.2.3.tgz", + "integrity": "sha512-GyieIznGUfPXPWu0yLS6U55Mz67AZD9cUk0BfirOWlPrXlBcan9Gz+vHGz+cPfuoweZSnPzPIm67VtQM0OWZbA==", + "dev": true, + "requires": { + "@babel/helper-member-expression-to-functions": "^7.0.0", + "@babel/helper-optimise-call-expression": "^7.0.0", + "@babel/traverse": "^7.2.3", + "@babel/types": "^7.0.0" + } + }, + "@babel/parser": { + "version": "7.3.3", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.3.3.tgz", + "integrity": "sha512-xsH1CJoln2r74hR+y7cg2B5JCPaTh+Hd+EbBRk9nWGSNspuo6krjhX0Om6RnRQuIvFq8wVXCLKH3kwKDYhanSg==", + "dev": true + }, + "@babel/traverse": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.2.3.tgz", + "integrity": "sha512-Z31oUD/fJvEWVR0lNZtfgvVt512ForCTNKYcJBGbPb1QZfve4WGH8Wsy7+Mev33/45fhP/hwQtvgusNdcCMgSw==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "@babel/generator": "^7.2.2", + "@babel/helper-function-name": "^7.1.0", + "@babel/helper-split-export-declaration": "^7.0.0", + "@babel/parser": "^7.2.3", + "@babel/types": "^7.2.2", + "debug": "^4.1.0", + "globals": "^11.1.0", + "lodash": "^4.17.10" + }, + "dependencies": { + "@babel/types": { + "version": "7.3.3", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.3.3.tgz", + "integrity": "sha512-2tACZ80Wg09UnPg5uGAOUvvInaqLk3l/IAhQzlxLQOIXacr6bMsra5SH6AWw/hIDRCSbCdHP2KzSOD+cT7TzMQ==", + "dev": true, + "requires": { + "esutils": "^2.0.2", + "lodash": "^4.17.11", + "to-fast-properties": "^2.0.0" + } + } + } + }, + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + } + } + }, "@babel/helper-define-map": { "version": "7.1.0", "resolved": "https://registry.npmjs.org/@babel/helper-define-map/-/helper-define-map-7.1.0.tgz", @@ -302,6 +400,16 @@ "@babel/plugin-syntax-async-generators": "^7.2.0" } }, + "@babel/plugin-proposal-class-properties": { + "version": "7.3.3", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.3.3.tgz", + "integrity": "sha512-XO9eeU1/UwGPM8L+TjnQCykuVcXqaO5J1bkRPIygqZ/A2L1xVMJ9aZXrY31c0U4H2/LHKL4lbFQLsxktSrc/Ng==", + "dev": true, + "requires": { + "@babel/helper-create-class-features-plugin": "^7.3.0", + "@babel/helper-plugin-utils": "^7.0.0" + } + }, "@babel/plugin-proposal-json-strings": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.2.0.tgz", diff --git a/package.json b/package.json index 4584c2b..999ea52 100644 --- a/package.json +++ b/package.json @@ -16,6 +16,7 @@ }, "devDependencies": { "@babel/core": "7.1.2", + "@babel/plugin-proposal-class-properties": "7.3.3", "@babel/plugin-transform-async-to-generator": "7.1.0", "@babel/polyfill": "7.0.0", "@babel/preset-env": "7.1.0", diff --git a/src/data-table/index.jsx b/src/data-table/index.jsx index 5da451c..c3bef4f 100644 --- a/src/data-table/index.jsx +++ b/src/data-table/index.jsx @@ -6,92 +6,95 @@ import HeaderPadding from './header-padding.jsx'; import RowHeader from './row-header.jsx'; import { injectSeparators } from '../utilities'; -const DataTable = ({ data, general, qlik, renderData, styling }) => { - const { - headers: { - dimension1, - measurements - }, - matrix - } = data; +class DataTable extends React.PureComponent { + render () { + const { data, general, qlik, renderData, styling } = this.props; + const { + headers: { + dimension1, + measurements + }, + matrix + } = data; - return ( -
- - - {dimension1.map((dimensionEntry, dimensionIndex) => { - const rowHeaderText = dimensionEntry.displayValue || ''; - if (rowHeaderText === '-') { - return null; - } - const styleBuilder = new StyleBuilder(styling); - if (styling.hasCustomFileStyle) { - styleBuilder.parseCustomFileStyle(rowHeaderText); - } else { - styleBuilder.applyStandardAttributes(dimensionIndex); - styleBuilder.applyCustomStyle({ - fontSize: `${14 + styling.options.fontSizeAdjustment}px` - }); - } - const rowStyle = { - fontFamily: styling.options.fontFamily, - width: '230px', - ...styleBuilder.getStyle() - }; + return ( +
+
+ + {dimension1.map((dimensionEntry, dimensionIndex) => { + const rowHeaderText = dimensionEntry.displayValue || ''; + if (rowHeaderText === '-') { + return null; + } + const styleBuilder = new StyleBuilder(styling); + if (styling.hasCustomFileStyle) { + styleBuilder.parseCustomFileStyle(rowHeaderText); + } else { + styleBuilder.applyStandardAttributes(dimensionIndex); + styleBuilder.applyCustomStyle({ + fontSize: `${14 + styling.options.fontSizeAdjustment}px` + }); + } + const rowStyle = { + fontFamily: styling.options.fontFamily, + width: '230px', + ...styleBuilder.getStyle() + }; - return ( - - - {renderData && injectSeparators( - matrix[dimensionIndex], - styling.useSeparatorColumns, - { atEvery: measurements.length } - ).map((measurementData, index) => { - if (measurementData.isSeparator) { - const separatorStyle = { - color: 'white', - fontFamily: styling.options.fontFamily, - fontSize: `${12 + styling.options.fontSizeAdjustment}px` - }; + return ( + + + {renderData && injectSeparators( + matrix[dimensionIndex], + styling.useSeparatorColumns, + { atEvery: measurements.length } + ).map((measurementData, index) => { + if (measurementData.isSeparator) { + const separatorStyle = { + color: 'white', + fontFamily: styling.options.fontFamily, + fontSize: `${12 + styling.options.fontSizeAdjustment}px` + }; + return ( + + ); + } + const { dimension1: dimension1Info, dimension2, measurement } = measurementData.parents; + const id = `${dimension1Info.elementNumber}-${dimension2 && dimension2.elementNumber}-${measurement.header}`; return ( - + ); - } - const { dimension1: dimension1Info, dimension2, measurement } = measurementData.parents; - const id = `${dimension1Info.elementNumber}-${dimension2 && dimension2.elementNumber}-${measurement.header}`; - return ( - - ); - })} - - ); - })} - -
+ * + - * -
-
- ); -}; + })} + + ); + })} + + + + ); + } +} DataTable.defaultProps = { renderData: true diff --git a/src/headers-table/index.jsx b/src/headers-table/index.jsx index 8ca4bb4..3ed75bb 100644 --- a/src/headers-table/index.jsx +++ b/src/headers-table/index.jsx @@ -5,84 +5,52 @@ import ColumnHeader from './column-header.jsx'; import MeasurementColumnHeader from './measurement-column-header.jsx'; import { injectSeparators } from '../utilities'; -const HeadersTable = ({ data, general, qlik, styling }) => { - const baseCSS = { - backgroundColor: styling.headerOptions.colorSchema, - color: styling.headerOptions.textColor, - fontFamily: styling.options.fontFamily, - textAlign: styling.headerOptions.alignment - }; +class HeadersTable extends React.Component { + render () { + const { data, general, qlik, styling } = this.props; + const baseCSS = { + backgroundColor: styling.headerOptions.colorSchema, + color: styling.headerOptions.textColor, + fontFamily: styling.options.fontFamily, + textAlign: styling.headerOptions.alignment + }; - const { - dimension1, - dimension2, - measurements - } = data.headers; + const { + dimension1, + dimension2, + measurements + } = data.headers; - const hasSecondDimension = dimension2.length > 0; + const hasSecondDimension = dimension2.length > 0; - return ( -
- - - - - {!hasSecondDimension && measurements.map(measurementEntry => ( - +
+ + + - ))} - {hasSecondDimension && injectSeparators(dimension2, styling.useSeparatorColumns).map((entry, index) => { - if (entry.isSeparator) { - const separatorStyle = { - color: 'white', - fontFamily: styling.options.fontFamily, - fontSize: `${13 + styling.headerOptions.fontSizeAdjustment}px` - }; - - return ( - - ); - } - return ( - ( + - ); - })} - - {hasSecondDimension && ( - - {injectSeparators(dimension2, styling.useSeparatorColumns).map((dimensionEntry, index) => { - if (dimensionEntry.isSeparator) { + ))} + {hasSecondDimension && injectSeparators(dimension2, styling.useSeparatorColumns).map((entry, index) => { + if (entry.isSeparator) { const separatorStyle = { color: 'white', fontFamily: styling.options.fontFamily, - fontSize: `${12 + styling.headerOptions.fontSizeAdjustment}px` + fontSize: `${13 + styling.headerOptions.fontSizeAdjustment}px` }; return ( @@ -95,25 +63,62 @@ const HeadersTable = ({ data, general, qlik, styling }) => { ); } - return measurements.map(measurementEntry => ( - - )); + ); })} - )} - -
- * -
-
- ); -}; + {hasSecondDimension && ( + + {injectSeparators(dimension2, styling.useSeparatorColumns).map((dimensionEntry, index) => { + if (dimensionEntry.isSeparator) { + const separatorStyle = { + color: 'white', + fontFamily: styling.options.fontFamily, + fontSize: `${12 + styling.headerOptions.fontSizeAdjustment}px` + }; + + return ( + + * + + ); + } + return measurements.map(measurementEntry => ( + + )); + })} + + )} + + + + ); + } +} + +// const HeadersTable = ({ data, general, qlik, styling }) => { +// }; HeadersTable.propTypes = { data: PropTypes.shape({ diff --git a/src/linked-scroll/index.js b/src/linked-scroll/index.js new file mode 100644 index 0000000..5e5ded1 --- /dev/null +++ b/src/linked-scroll/index.js @@ -0,0 +1,2 @@ +export { default as LinkedScrollWrapper } from './linked-scroll-wrapper.jsx'; +export { default as LinkedScrollSection } from './linked-scroll-section.jsx'; diff --git a/src/linked-scroll/linked-scroll-section.jsx b/src/linked-scroll/linked-scroll-section.jsx new file mode 100644 index 0000000..e77aaeb --- /dev/null +++ b/src/linked-scroll/linked-scroll-section.jsx @@ -0,0 +1,29 @@ +import React from 'react'; +import PropTypes from 'prop-types'; +import { LinkedScrollContext } from './linked-scroll-wrapper.jsx'; + +class LinkedScrollSection extends React.PureComponent { + static contextType = LinkedScrollContext; + + componentDidMount () { + const { link } = this.context; + link(this); + } + + componentWillUnmount () { + const { unlink } = this.context; + unlink(this); + } + + render () { + const { children } = this.props; + + return children; + } +} + +LinkedScrollSection.propTypes = { + children: PropTypes.any +}; + +export default LinkedScrollSection; diff --git a/src/linked-scroll/linked-scroll-wrapper.jsx b/src/linked-scroll/linked-scroll-wrapper.jsx new file mode 100644 index 0000000..be95b55 --- /dev/null +++ b/src/linked-scroll/linked-scroll-wrapper.jsx @@ -0,0 +1,82 @@ +import React from 'react'; +import ReactDOM from 'react-dom'; +import PropTypes from 'prop-types'; + +export const LinkedScrollContext = React.createContext(); + +class LinkedScrollWrapper extends React.PureComponent { + constructor (props) { + super(props); + + this.linkComponent = this.linkComponent.bind(this); + this.unlinkComponent = this.unlinkComponent.bind(this); + this.handleScroll = this.handleScroll.bind(this); + this.scrollElements = []; + + this.linkActions = { + link: this.linkComponent, + unlink: this.unlinkComponent + }; + } + + linkComponent (component) { + // eslint-disable-next-line react/no-find-dom-node + const node = ReactDOM.findDOMNode(component); + const element = { + component, + node + }; + this.scrollElements.push(element); + node.onscroll = this.handleScroll.bind(this, element); + } + + unlinkComponent (component) { + const componentIndex = this.scrollElements.map(element => element.component).indexOf(component); + if (componentIndex !== -1) { + this.scrollElements.removeAt(componentIndex); + // eslint-disable-next-line react/no-find-dom-node + const node = ReactDOM.findDOMNode(component); + node.onscroll = null; + } + } + + handleScroll (element) { + window.requestAnimationFrame(() => { + this.sync(element); + }); + } + + sync (scrollElement) { + this.scrollElements.forEach(element => { + if (scrollElement === element) { + return; + } + element.node.onscroll = null; + if (element.component.props.linkHorizontal) { + element.node.scrollLeft = scrollElement.node.scrollLeft; + } + + if (element.component.props.linkVertical) { + element.node.scrollTop = scrollElement.node.scrollTop; + } + window.requestAnimationFrame(() => { + element.node.onscroll = this.handleScroll.bind(this, element); + }); + }); + } + + render () { + const { children } = this.props; + return ( + + {children} + + ); + } +} + +LinkedScrollWrapper.propTypes = { + children: PropTypes.any +}; + +export default LinkedScrollWrapper; diff --git a/src/main.less b/src/main.less index 9f96728..6f584cc 100644 --- a/src/main.less +++ b/src/main.less @@ -10,8 +10,6 @@ } div.qv-object-content-container { - overflow-x: scroll; - overflow-y: hidden; z-index: 110; } @@ -149,12 +147,6 @@ width: 350px; } - .header-wrapper { - position: absolute; - top: 0; - z-index: 1; - } - /*popups for headers*/ .tooltip { position: fixed !important; @@ -166,11 +158,7 @@ /*end popups*/ .row-wrapper { - position: absolute; - top: 97px; height: calc(~"100% - 97px"); - overflow-x: hidden; - overflow-y: scroll; padding: 0; margin-top: 0; } @@ -186,30 +174,54 @@ .kpi-table { width: @KpiTableWidth !important; overflow: hidden !important; - display: table; - height: 100%; + height: 100%; margin: 0; padding: 0; - z-index: 100; position: absolute; top: 0; left: 0; border-right: 1px solid white; box-shadow: 4px 2px 8px #e1e1e1; - } - .kpi-table .row-wrapper { - overflow: hidden; + .row-wrapper { + height: calc(~"100% - 97px"); + overflow: scroll; + position: absolute; + padding: 0; + margin-top: 0; + } } .data-table { - width: 272px !important; - float: left; - display: table; height: 100%; - z-index: 90; + width: calc(100% - 243px); position: absolute; margin-left: @KpiTableWidth + 13px; - -ms-overflow-style: none; + + .header-wrapper { + overflow: scroll; + width: 100%; + } + + .row-wrapper { + height: calc(~"100% - 97px"); + width: 100%; + overflow: scroll; + padding: 0; + margin-top: 0; + } + } + + // hide scrollbars + .kpi-table .header-wrapper, + .kpi-table .row-wrapper, + .data-table .header-wrapper, + .data-table .row-wrapper { + -ms-overflow-style: none; // IE 10+ + -moz-overflow: -moz-scrollbars-none; // Firefox + + &::-webkit-scrollbar { + display: none; // Safari and Chrome + } } } diff --git a/src/paint.jsx b/src/paint.jsx index e2bef20..d81e5c8 100644 --- a/src/paint.jsx +++ b/src/paint.jsx @@ -4,6 +4,7 @@ import React from 'react'; import ReactDOM from 'react-dom'; import HeadersTable from './headers-table/index.jsx'; import DataTable from './data-table/index.jsx'; +import { LinkedScrollWrapper, LinkedScrollSection } from './linked-scroll'; export default async function paint ($element, layout, component) { const state = await initializeStore({ @@ -13,7 +14,7 @@ export default async function paint ($element, layout, component) { }); const jsx = ( - +
- + + +
- - + + + + + +
-
+ ); ReactDOM.render(jsx, $element[0]); - // TODO: skipped the following as they weren't blockers for letting react handle rendering, - // they are however the only reason we still depend on jQuery and should be removed as part of unnecessary dependencies issue - $(`[tid="${layout.qInfo.qId}"] .data-table .row-wrapper`).on('scroll', function () { - $(`[tid="${layout.qInfo.qId}"] .kpi-table .row-wrapper`).scrollTop($(this).scrollTop()); - }); - - // freeze first column - $(`[tid="${layout.qInfo.qId}"] .qv-object-content-container`).on('scroll', (t) => { - $(`[tid="${layout.qInfo.qId}"] .kpi-table`).css('left', `${Math.round(t.target.scrollLeft)}px`); - }); - // TODO: fixing tooltips has a seperate issue, make sure to remove this as part of that issue $(`[tid="${layout.qInfo.qId}"] .header-wrapper th`).hover(function () { $(`[tid="${layout.qInfo.qId}"] .tooltip`).delay(500) diff --git a/webpack.config.js b/webpack.config.js index a70a9b1..83f5ec2 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -6,23 +6,16 @@ console.log('Webpack mode:', settings.mode); // eslint-disable-line no-console const config = { devtool: 'source-map', - entry: [ - './src/index.js' - ], - mode: settings.mode, - output: { - path: settings.buildDestination, - filename: settings.name + '.js', - libraryTarget: 'amd' - }, + entry: ['./src/index.js'], externals: { jquery: { amd: 'jquery', commonjs: 'jquery', commonjs2: 'jquery', root: '_' - }, + } }, + mode: settings.mode, // TODO: breaks core-js for some reason // resolve: { // extensions: ['js', 'jsx'] @@ -31,20 +24,23 @@ const config = { rules: [ { enforce: 'pre', - test: /\.(js|jsx)$/, exclude: /(node_modules|Library)/, loader: 'eslint-loader', options: { failOnError: true - } + }, + test: /\.(js|jsx)$/ }, { - test: /\.(js|jsx)$/, exclude: /node_modules/, + test: /\.(js|jsx)$/, use: { loader: 'babel-loader', options: { - plugins: ['@babel/plugin-transform-async-to-generator'], + plugins: [ + '@babel/plugin-transform-async-to-generator', + '@babel/plugin-proposal-class-properties' + ], presets: [ '@babel/preset-env', '@babel/preset-react' @@ -54,21 +50,30 @@ const config = { }, { test: /.less$/, - use: ['style-loader', 'css-loader', 'less-loader'] + use: [ + 'style-loader', + 'css-loader', + 'less-loader' + ] } ] }, + output: { + filename: `${settings.name}.js`, + libraryTarget: 'amd', + path: settings.buildDestination + }, plugins: [ new CopyWebpackPlugin([ - 'assets/' + settings.name + '.qext', - 'assets/' + settings.name + '.png', + `assets/${settings.name}.qext`, + `assets/${settings.name}.png`, 'assets/wbfolder.wbl', + 'resources/Excel.png', // TODO: remove entries below this line 'resources/Accounts.csv', 'resources/Accounts2.csv', - 'resources/QlikLook.csv', - 'resources/Excel.png', + 'resources/QlikLook.csv' ], {}), new StyleLintPlugin() ] From 555000be547aea85eee9945ff3c4369950c6d6dd Mon Sep 17 00:00:00 2001 From: Kristoffer Lind Date: Thu, 21 Feb 2019 17:49:05 +0100 Subject: [PATCH 2/2] fix rebase issues --- src/data-table/index.jsx | 165 ++++++++++++++++++------------------ src/headers-table/index.jsx | 163 +++++++++++++++++------------------ 2 files changed, 160 insertions(+), 168 deletions(-) diff --git a/src/data-table/index.jsx b/src/data-table/index.jsx index c3bef4f..5da451c 100644 --- a/src/data-table/index.jsx +++ b/src/data-table/index.jsx @@ -6,95 +6,92 @@ import HeaderPadding from './header-padding.jsx'; import RowHeader from './row-header.jsx'; import { injectSeparators } from '../utilities'; -class DataTable extends React.PureComponent { - render () { - const { data, general, qlik, renderData, styling } = this.props; - const { - headers: { - dimension1, - measurements - }, - matrix - } = data; +const DataTable = ({ data, general, qlik, renderData, styling }) => { + const { + headers: { + dimension1, + measurements + }, + matrix + } = data; - return ( -
- - - {dimension1.map((dimensionEntry, dimensionIndex) => { - const rowHeaderText = dimensionEntry.displayValue || ''; - if (rowHeaderText === '-') { - return null; - } - const styleBuilder = new StyleBuilder(styling); - if (styling.hasCustomFileStyle) { - styleBuilder.parseCustomFileStyle(rowHeaderText); - } else { - styleBuilder.applyStandardAttributes(dimensionIndex); - styleBuilder.applyCustomStyle({ - fontSize: `${14 + styling.options.fontSizeAdjustment}px` - }); - } - const rowStyle = { - fontFamily: styling.options.fontFamily, - width: '230px', - ...styleBuilder.getStyle() - }; + return ( +
+
+ + {dimension1.map((dimensionEntry, dimensionIndex) => { + const rowHeaderText = dimensionEntry.displayValue || ''; + if (rowHeaderText === '-') { + return null; + } + const styleBuilder = new StyleBuilder(styling); + if (styling.hasCustomFileStyle) { + styleBuilder.parseCustomFileStyle(rowHeaderText); + } else { + styleBuilder.applyStandardAttributes(dimensionIndex); + styleBuilder.applyCustomStyle({ + fontSize: `${14 + styling.options.fontSizeAdjustment}px` + }); + } + const rowStyle = { + fontFamily: styling.options.fontFamily, + width: '230px', + ...styleBuilder.getStyle() + }; - return ( - - - {renderData && injectSeparators( - matrix[dimensionIndex], - styling.useSeparatorColumns, - { atEvery: measurements.length } - ).map((measurementData, index) => { - if (measurementData.isSeparator) { - const separatorStyle = { - color: 'white', - fontFamily: styling.options.fontFamily, - fontSize: `${12 + styling.options.fontSizeAdjustment}px` - }; + return ( + + + {renderData && injectSeparators( + matrix[dimensionIndex], + styling.useSeparatorColumns, + { atEvery: measurements.length } + ).map((measurementData, index) => { + if (measurementData.isSeparator) { + const separatorStyle = { + color: 'white', + fontFamily: styling.options.fontFamily, + fontSize: `${12 + styling.options.fontSizeAdjustment}px` + }; - return ( - - ); - } - const { dimension1: dimension1Info, dimension2, measurement } = measurementData.parents; - const id = `${dimension1Info.elementNumber}-${dimension2 && dimension2.elementNumber}-${measurement.header}`; return ( - + ); - })} - - ); - })} - -
- * - + * +
-
- ); - } -} + } + const { dimension1: dimension1Info, dimension2, measurement } = measurementData.parents; + const id = `${dimension1Info.elementNumber}-${dimension2 && dimension2.elementNumber}-${measurement.header}`; + return ( + + ); + })} + + ); + })} + + + + ); +}; DataTable.defaultProps = { renderData: true diff --git a/src/headers-table/index.jsx b/src/headers-table/index.jsx index 3ed75bb..8ca4bb4 100644 --- a/src/headers-table/index.jsx +++ b/src/headers-table/index.jsx @@ -5,52 +5,84 @@ import ColumnHeader from './column-header.jsx'; import MeasurementColumnHeader from './measurement-column-header.jsx'; import { injectSeparators } from '../utilities'; -class HeadersTable extends React.Component { - render () { - const { data, general, qlik, styling } = this.props; - const baseCSS = { - backgroundColor: styling.headerOptions.colorSchema, - color: styling.headerOptions.textColor, - fontFamily: styling.options.fontFamily, - textAlign: styling.headerOptions.alignment - }; +const HeadersTable = ({ data, general, qlik, styling }) => { + const baseCSS = { + backgroundColor: styling.headerOptions.colorSchema, + color: styling.headerOptions.textColor, + fontFamily: styling.options.fontFamily, + textAlign: styling.headerOptions.alignment + }; - const { - dimension1, - dimension2, - measurements - } = data.headers; + const { + dimension1, + dimension2, + measurements + } = data.headers; - const hasSecondDimension = dimension2.length > 0; + const hasSecondDimension = dimension2.length > 0; - return ( -
- - - - +
+ + + + {!hasSecondDimension && measurements.map(measurementEntry => ( + - {!hasSecondDimension && measurements.map(measurementEntry => ( - { + if (entry.isSeparator) { + const separatorStyle = { + color: 'white', + fontFamily: styling.options.fontFamily, + fontSize: `${13 + styling.headerOptions.fontSizeAdjustment}px` + }; + + return ( + + ); + } + return ( + - ))} - {hasSecondDimension && injectSeparators(dimension2, styling.useSeparatorColumns).map((entry, index) => { - if (entry.isSeparator) { + ); + })} + + {hasSecondDimension && ( + + {injectSeparators(dimension2, styling.useSeparatorColumns).map((dimensionEntry, index) => { + if (dimensionEntry.isSeparator) { const separatorStyle = { color: 'white', fontFamily: styling.options.fontFamily, - fontSize: `${13 + styling.headerOptions.fontSizeAdjustment}px` + fontSize: `${12 + styling.headerOptions.fontSizeAdjustment}px` }; return ( @@ -63,62 +95,25 @@ class HeadersTable extends React.Component { ); } - return ( - ( + - ); + )); })} - {hasSecondDimension && ( - - {injectSeparators(dimension2, styling.useSeparatorColumns).map((dimensionEntry, index) => { - if (dimensionEntry.isSeparator) { - const separatorStyle = { - color: 'white', - fontFamily: styling.options.fontFamily, - fontSize: `${12 + styling.headerOptions.fontSizeAdjustment}px` - }; - - return ( - - ); - } - return measurements.map(measurementEntry => ( - - )); - })} - - )} - -
+ * +
- * -
-
- ); - } -} - -// const HeadersTable = ({ data, general, qlik, styling }) => { -// }; + )} + + + + ); +}; HeadersTable.propTypes = { data: PropTypes.shape({