From acf6eb7b265ce4c36508b951fd69d427c65c945f Mon Sep 17 00:00:00 2001 From: caele Date: Wed, 13 Jan 2021 16:09:38 +0100 Subject: [PATCH 1/2] fix: remove infinite loop --- .eslintrc.js | 75 +++++++++------- src/initialize-transformed.js | 161 +++++++++++++++++++++------------- src/root.jsx | 31 +------ 3 files changed, 146 insertions(+), 121 deletions(-) diff --git a/.eslintrc.js b/.eslintrc.js index d51b712..48f8574 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -3,15 +3,15 @@ module.exports = { ecmaVersion: 6, ecmaFeatures: { jsx: true, - modules: true + modules: true, }, - sourceType: "module" + sourceType: "module", }, parser: "babel-eslint", env: { browser: true, es6: true, - node: true + node: true, }, globals: { angular: false, @@ -21,49 +21,63 @@ module.exports = { document: false, expect: false, it: false, - require: false + require: false, }, rules: { - "indent": ["error", 2, { "SwitchCase": 1 }], + indent: ["warn", 2, { SwitchCase: 1 }], "linebreak-style": ["error", "unix"], "object-curly-spacing": ["error", "always"], "max-lines": ["warn", 300], - "max-len": ["warn", { "code": 120, "ignoreComments": true, "ignoreTrailingComments": false }], + "max-len": [ + "warn", + { code: 120, ignoreComments: true, ignoreTrailingComments: false }, + ], "no-console": ["warn"], - "no-mixed-operators": ["warn", { - "groups": [ - ["==", "!=", "===", "!==", ">", ">=", "<", "<="], - ["&&", "||"], - ["in", "instanceof"] - ], - "allowSamePrecedence": true - }], + "no-mixed-operators": [ + "warn", + { + groups: [ + ["==", "!=", "===", "!==", ">", ">=", "<", "<="], + ["&&", "||"], + ["in", "instanceof"], + ], + allowSamePrecedence: true, + }, + ], + "comma-dangle": ["off"], + "space-before-function-paren": ["off"], "no-multi-spaces": ["error"], "no-cond-assign": ["warn"], "no-fallthrough": ["warn"], "no-undef": ["error"], "no-unused-vars": ["error"], - "no-use-before-define": ["error", { "functions": false, "classes": false, "variables": false }], + "no-use-before-define": [ + "error", + { functions: false, classes: false, variables: false }, + ], "no-useless-escape": ["warn"], "no-useless-return": ["warn"], - "no-underscore-dangle": ["warn", { "allow": ["_id"] }], + "no-underscore-dangle": ["warn", { allow: ["_id"] }], "no-redeclare": ["error"], "no-restricted-syntax": ["warn"], "operator-linebreak": ["warn", "before"], "prefer-promise-reject-errors": ["warn"], - "padded-blocks": ["warn", { "blocks": "never", "switches": "never", "classes": "never" }], - "semi": ["error", "always"], + "padded-blocks": [ + "warn", + { blocks: "never", switches: "never", classes: "never" }, + ], + semi: ["error", "always"], "valid-typeof": ["warn"], "no-eval": ["error"], "no-implied-eval": ["error"], "no-debugger": ["warn"], "no-unreachable": ["warn"], - "quotes": ["warn", "single", { "avoidEscape": true }], + quotes: ["warn", "single", { avoidEscape: true }], "sort-imports": ["off"], "max-lines-per-function": ["off"], // marks the entire functions, a bit too noisy - "complexity": ["warn"], - "camelcase": ["warn"], - "max-statements": ["off"], // marks the entire functions, a bit too noisy + complexity: ["warn"], + camelcase: ["warn"], + "max-statements": ["off"], // marks the entire functions, a bit too noisy "sort-vars": ["off"], // not much value for the work "init-declarations": ["off"], "capitalized-comments": ["off"], @@ -99,13 +113,13 @@ module.exports = { "array-bracket-newline": ["warn"], "array-element-newline": ["warn"], "object-shorthand": ["warn"], - "eqeqeq": ["warn"], + eqeqeq: ["warn"], "no-empty-function": ["off"], "function-paren-newline": ["warn"], "no-invalid-this": ["warn"], "newline-per-chained-call": ["warn"], "no-unused-expressions": ["warn"], - "strict": ["warn"], + strict: ["warn"], "no-ternary": ["off"], "multiline-ternary": ["off"], "no-param-reassign": ["error"], @@ -115,9 +129,9 @@ module.exports = { "default-case": ["warn"], "no-alert": ["warn"], "max-params": ["warn"], - "brace-style": ["warn", "1tbs", { "allowSingleLine": true }], + "brace-style": ["warn", "1tbs", { allowSingleLine: true }], "prefer-const": ["warn"], - "class-methods-use-this":["warn"], + "class-methods-use-this": ["warn"], // plugin:react "react/jsx-indent": ["warn", 2], "react/jsx-indent-props": ["warn", 2], @@ -131,10 +145,7 @@ module.exports = { "react/jsx-max-depth": ["off"], // rule throws exception in single-dimension-measure "react/jsx-filename-extension": ["warn"], "react/prefer-stateless-function": ["warn"], - "react/no-set-state": ["warn"] + "react/no-set-state": ["warn"], }, - extends: [ - "eslint:all", - "plugin:react/all" - ] -} + extends: ["eslint:all", "plugin:react/all"], +}; diff --git a/src/initialize-transformed.js b/src/initialize-transformed.js index d89880b..f3ec191 100644 --- a/src/initialize-transformed.js +++ b/src/initialize-transformed.js @@ -1,50 +1,55 @@ -import { distinctArray } from './utilities'; +import { distinctArray } from "./utilities"; export const HEADER_FONT_SIZE = { SMALL: -1, - MEDIUM: 1 + MEDIUM: 1, }; -function getAlignment (option) { +function getAlignment(option) { const alignmentOptions = { - 1: 'left', - 2: 'center', - 3: 'right' + 1: "left", + 2: "center", + 3: "right", }; - return alignmentOptions[option] || 'left'; + return alignmentOptions[option] || "left"; } -function getFontSizeAdjustment (option) { +function getFontSizeAdjustment(option) { const fontSizeAdjustmentOptions = { 1: HEADER_FONT_SIZE.SMALL, - 2: HEADER_FONT_SIZE.MEDIUM + 2: HEADER_FONT_SIZE.MEDIUM, }; return fontSizeAdjustmentOptions[option] || 0; } -function generateMeasurements (information) { - return information.map(measurement => { +function generateMeasurements(information) { + return information.map((measurement) => { const transformedMeasurement = { - format: measurement.qNumFormat.qFmt || '#.##0', - name: measurement.qFallbackTitle + format: measurement.qNumFormat.qFmt || "#.##0", + name: measurement.qFallbackTitle, }; return transformedMeasurement; }); } -function generateDimensionEntry (information, data) { +function generateDimensionEntry(information, data) { return { displayValue: data.qText || data.qNum, elementNumber: data.qElemNumber, name: information.qFallbackTitle, - value: data.qNum + value: data.qNum, }; } -function generateMatrixCell ({ cell, dimension1Information, dimension2Information, measurementInformation }) { +function generateMatrixCell({ + cell, + dimension1Information, + dimension2Information, + measurementInformation, +}) { const matrixCell = { displayValue: cell.qText, format: measurementInformation.format, @@ -52,28 +57,32 @@ function generateMatrixCell ({ cell, dimension1Information, dimension2Informatio parents: { dimension1: { elementNumber: dimension1Information.qElemNumber, - header: dimension1Information.qText + header: dimension1Information.qText, }, measurement: { header: measurementInformation.name, - index: measurementInformation.index - } + index: measurementInformation.index, + }, }, - value: cell.qNum + value: cell.qNum, }; if (dimension2Information) { matrixCell.parents.dimension2 = { elementNumber: dimension2Information.qElemNumber, - header: dimension2Information.qText + header: dimension2Information.qText, }; } return matrixCell; } - -function generateDataSet (component, dimensionsInformation, measurementsInformation, dataCube) { +function generateDataSet( + component, + dimensionsInformation, + measurementsInformation, + dataCube +) { const measurements = generateMeasurements(measurementsInformation); let dimension1 = []; let dimension2 = []; @@ -83,13 +92,19 @@ function generateDataSet (component, dimensionsInformation, measurementsInformat // eslint-disable-next-line no-undefined for (let index = 0; dataCube[index] !== undefined; index++) { // eslint-disable-next-line no-loop-func - dataCube[index].forEach(row => { - const dimension1Entry = generateDimensionEntry(dimensionsInformation[0], row[0]); + dataCube[index].forEach((row) => { + const dimension1Entry = generateDimensionEntry( + dimensionsInformation[0], + row[0] + ); dimension1.push(dimension1Entry); let dimension2Entry; let firstDataCell = 1; if (hasSecondDimension) { - dimension2Entry = generateDimensionEntry(dimensionsInformation[1], row[1]); + dimension2Entry = generateDimensionEntry( + dimensionsInformation[1], + row[1] + ); dimension2.push(dimension2Entry); firstDataCell = 2; } @@ -104,16 +119,19 @@ function generateDataSet (component, dimensionsInformation, measurementsInformat cell, dimension1Information, dimension2Information, - measurementInformation + measurementInformation, }); return generatedCell; }); let appendToRowIndex = matrix.length; if (hasSecondDimension) { - // See if there already is a row for the current dim1 + // See if there already is a row for the current dim1 for (let i = 0; i < matrix.length; i++) { - if (matrix[i][0].parents.dimension1.header === matrixRow[0].parents.dimension1.header) { + if ( + matrix[i][0].parents.dimension1.header === + matrixRow[0].parents.dimension1.header + ) { appendToRowIndex = i; matrixRow = matrix[i].concat(matrixRow); } @@ -131,34 +149,44 @@ function generateDataSet (component, dimensionsInformation, measurementsInformat dimension1: dimension1, dimension2: dimension2, matrix, - measurements + measurements, }; } -function initializeTransformed ({ component, dataCube, designList, layout }) { +function initializeTransformed({ + $element, + component, + dataCube, + designList, + layout, +}) { const dimensionsInformation = component.backendApi.getDimensionInfos(); const measurementsInformation = component.backendApi.getMeasureInfos(); const dimensionCount = layout.qHyperCube.qDimensionInfo.length; - const { - dimension1, - dimension2, - measurements, - matrix - } = generateDataSet(component, dimensionsInformation, measurementsInformation, dataCube); + const { dimension1, dimension2, measurements, matrix } = generateDataSet( + component, + dimensionsInformation, + measurementsInformation, + dataCube + ); const customSchemaBasic = []; const customSchemaFull = []; let customHeadersCount = 0; if (designList && designList.length > 0) { - const headers = designList[0].split(';'); + const headers = designList[0].split(";"); customHeadersCount = headers.length; for (let lineNumber = 0; lineNumber < designList.length; lineNumber += 1) { customSchemaFull[lineNumber] = new Array(headers.length); - const data = designList[lineNumber].split(';'); + const data = designList[lineNumber].split(";"); if (data.length === headers.length) { - for (let headerIndex = 0; headerIndex < headers.length; headerIndex += 1) { + for ( + let headerIndex = 0; + headerIndex < headers.length; + headerIndex += 1 + ) { [customSchemaBasic[lineNumber]] = data; customSchemaFull[lineNumber][headerIndex] = data[headerIndex]; } @@ -172,25 +200,28 @@ function initializeTransformed ({ component, dataCube, designList, layout }) { // the widths as percentages of the available width. However, this often results in random // columns getting 1px wider than the others because of rounding necessary to fill the width. // This 1px causes missalignment between the data- and header tables. - cellWidth = ''; + cellWidth = ""; } else { // If using the previous solution just set 60px - cellWidth = `${layout.columnwidthslider > 10 ? layout.columnwidthslider : 60}px`; + cellWidth = `${ + layout.columnwidthslider > 10 ? layout.columnwidthslider : 60 + }px`; } // top level properties could be reducers and then components connect to grab what they want, // possibly with reselect for some presentational transforms (moving some of the presentational logic like formatting and such) const transformedProperties = { + element: $element[0], data: { headers: { dimension1, // column headers dimension2, // parent row headers if exists - measurements // row headers, looped for each dimension2 if exists + measurements, // row headers, looped for each dimension2 if exists }, matrix, // 2d array of all rows/cells to render in body of datatable meta: { - dimensionCount: dimensionsInformation.length - } + dimensionCount: dimensionsInformation.length, + }, }, general: { allowExcelExport: layout.allowexportxls, @@ -200,23 +231,25 @@ function initializeTransformed ({ component, dataCube, designList, layout }) { footnote: layout.footnote, subtitle: layout.subtitle, title: layout.title, - useColumnSeparator: layout.separatorcols && dimensionCount > 1 + useColumnSeparator: layout.separatorcols && dimensionCount > 1, }, selection: { - dimensionSelectionCounts: dimensionsInformation.map(dimensionInfo => dimensionInfo.qStateCounts.qSelected) + dimensionSelectionCounts: dimensionsInformation.map( + (dimensionInfo) => dimensionInfo.qStateCounts.qSelected + ), }, styling: { customCSV: { basic: customSchemaBasic, count: customHeadersCount, - full: customSchemaFull + full: customSchemaFull, }, hasCustomFileStyle: Boolean(designList), headerOptions: { alignment: getAlignment(layout.HeaderAlign), colorSchema: layout.HeaderColorSchema.color, fontSizeAdjustment: getFontSizeAdjustment(layout.lettersizeheader), - textColor: layout.HeaderTextColorSchema.color + textColor: layout.HeaderTextColorSchema.color, }, options: { backgroundColor: layout.rowEvenBGColor, @@ -224,38 +257,42 @@ function initializeTransformed ({ component, dataCube, designList, layout }) { color: layout.BodyTextColorSchema, fontFamily: layout.FontFamily, fontSizeAdjustment: getFontSizeAdjustment(layout.lettersize), - textAlignment: layout.cellTextAlignment + textAlignment: layout.cellTextAlignment, }, conditionalColoring: { enabled: layout.conditionalcoloring.enabled, colorAllRows: layout.conditionalcoloring.colorall, - rows: layout.conditionalcoloring.rows.map(row => row.rowname), - colorAllMeasures: typeof layout.conditionalcoloring.colorallmeasures === 'undefined' - || layout.conditionalcoloring.colorallmeasures, + rows: layout.conditionalcoloring.rows.map((row) => row.rowname), + colorAllMeasures: + typeof layout.conditionalcoloring.colorallmeasures === "undefined" || + layout.conditionalcoloring.colorallmeasures, measures: !layout.conditionalcoloring.measures - ? [] : layout.conditionalcoloring.measures.split(',').map(index => Number(index)), + ? [] + : layout.conditionalcoloring.measures + .split(",") + .map((index) => Number(index)), threshold: { poor: layout.conditionalcoloring.threshold_poor, - fair: layout.conditionalcoloring.threshold_fair + fair: layout.conditionalcoloring.threshold_fair, }, colors: { poor: { color: layout.conditionalcoloring.color_poor, - textColor: layout.conditionalcoloring.textcolor_poor + textColor: layout.conditionalcoloring.textcolor_poor, }, fair: { color: layout.conditionalcoloring.color_fair, - textColor: layout.conditionalcoloring.textcolor_fair + textColor: layout.conditionalcoloring.textcolor_fair, }, good: { color: layout.conditionalcoloring.color_good, - textColor: layout.conditionalcoloring.textcolor_good - } - } + textColor: layout.conditionalcoloring.textcolor_good, + }, + }, }, symbolForNulls: layout.symbolfornulls, - usePadding: layout.indentbool - } + usePadding: layout.indentbool, + }, }; return transformedProperties; diff --git a/src/root.jsx b/src/root.jsx index b205726..e767511 100644 --- a/src/root.jsx +++ b/src/root.jsx @@ -5,37 +5,15 @@ import DataTable from "./data-table/index.jsx"; import { LinkedScrollWrapper, LinkedScrollSection } from "./linked-scroll"; class Root extends React.PureComponent { - constructor (props) { - super(props); - this.onDataTableRefSet = this.onDataTableRefSet.bind(this); - this.renderedTableWidth = 0; - } - - componentDidUpdate () { - let tableWidth; - if (this.dataTableRef) { - tableWidth = this.dataTableRef.getBoundingClientRect().width; - if (this.renderedTableWidth !== tableWidth) { - this.forceUpdate(); - } - } - } - - onDataTableRefSet (element) { - this.dataTableRef = element; - this.forceUpdate(); - } - render () { const { editmodeClass, component, state } = this.props; - const { data, general, styling, error } = state; + const { data, general, styling, error, element } = state; // Determine cell- and column separator width let cellWidth = '0px'; let columnSeparatorWidth = ''; - if (this.dataTableRef && !error) { - const tableWidth = this.dataTableRef.getBoundingClientRect().width; - this.renderedTableWidth = tableWidth; + if (!error && element) { + const tableWidth = element.getBoundingClientRect().width; if (general.cellWidth) { cellWidth = general.cellWidth; @@ -43,7 +21,7 @@ class Root extends React.PureComponent { columnSeparatorWidth = '8px'; } } else { - const headerMarginRight = 8; + const headerMarginRight = 8 + 230 + 20; const borderWidth = 1; const rowCellCount = data.matrix[0].length; @@ -99,7 +77,6 @@ class Root extends React.PureComponent {
Date: Thu, 14 Jan 2021 10:23:22 +0100 Subject: [PATCH 2/2] chore: add comment --- src/root.jsx | 1 + 1 file changed, 1 insertion(+) diff --git a/src/root.jsx b/src/root.jsx index e767511..1619b44 100644 --- a/src/root.jsx +++ b/src/root.jsx @@ -21,6 +21,7 @@ class Root extends React.PureComponent { columnSeparatorWidth = '8px'; } } else { + // 230 is the left "header", rest is magic margins const headerMarginRight = 8 + 230 + 20; const borderWidth = 1; const rowCellCount = data.matrix[0].length;