Compare commits

..

1 Commits

Author SHA1 Message Date
Albert Backenhof
e26d5fded8 Specifying excel type of excel download 2019-05-20 10:12:22 +02:00
13 changed files with 179 additions and 101 deletions

View File

@@ -1,4 +1,3 @@
import qlik from 'qlik';
import React from 'react';
import PropTypes from 'prop-types';
import Tooltip from '../tooltip/index.jsx';
@@ -10,38 +9,22 @@ class DataCell extends React.PureComponent {
}
handleSelect () {
const {
data: {
headers,
meta: {
dimensionCount,
altState
}
},
general: {
allowFilteringByClick
},
measurement,
component
} = this.props;
const { data: { meta: { dimensionCount } }, general: { allowFilteringByClick }, measurement, qlik } = this.props;
const hasSecondDimension = dimensionCount > 1;
if (!allowFilteringByClick) {
return;
}
const app = qlik.currApp(component);
app.field(headers.dimension1[0].name, altState)
.select([measurement.parents.dimension1.elementNumber], false, false);
qlik.backendApi.selectValues(0, [measurement.parents.dimension1.elementNumber], true);
if (hasSecondDimension) {
app.field(headers.dimension2[0].name, altState)
.select([measurement.parents.dimension2.elementNumber], false, false);
qlik.backendApi.selectValues(1, [measurement.parents.dimension2.elementNumber], true);
}
}
render () {
const {
data,
general,
measurement,
styleBuilder,
@@ -54,12 +37,11 @@ class DataCell extends React.PureComponent {
fontFamily: styling.options.fontFamily,
...styleBuilder.getStyle(),
paddingLeft: '5px',
textAlign: textAlignment,
minWidth: general.cellWidth,
maxWidth: general.cellWidth
textAlign: textAlignment
};
const isEmptyCell = measurement.displayValue === '';
const isColumnPercentageBased = (/%/).test(measurement.format);
let formattedMeasurementValue;
if (isEmptyCell) {
formattedMeasurementValue = '';
@@ -86,9 +68,16 @@ class DataCell extends React.PureComponent {
}
}
let cellClass = 'grid-cells';
const hasTwoDimensions = data.headers.dimension2 && data.headers.dimension2.length > 0;
const shouldUseSmallCells = isColumnPercentageBased && data.headers.measurements.length > 1 && hasTwoDimensions;
if (shouldUseSmallCells) {
cellClass = 'grid-cells-small';
}
return (
<td
className="grid-cells"
className={`${cellClass}${general.cellSuffix}`}
onClick={isEmptyCell ? null : this.handleSelect}
style={cellStyle}
>
@@ -106,23 +95,27 @@ class DataCell extends React.PureComponent {
DataCell.propTypes = {
data: PropTypes.shape({
headers: PropTypes.shape({
dimension1: PropTypes.array.isRequired,
measurements: PropTypes.array.isRequired
}).isRequired,
meta: PropTypes.shape({
altState: PropTypes.string.isRequired,
dimensionCount: PropTypes.number.isRequired
}).isRequired
}).isRequired,
general: PropTypes.shape({
cellWidth: PropTypes.string.isRequired
cellSuffix: PropTypes.string.isRequired
}).isRequired,
measurement: PropTypes.shape({
format: PropTypes.string,
name: PropTypes.string,
value: PropTypes.any
}).isRequired,
component: PropTypes.shape({}).isRequired,
qlik: PropTypes.shape({
backendApi: PropTypes.shape({
selectValues: function (props, propName) {
if (props.isSnapshot || typeof props[propName] === 'function') {
return null;
}
return new Error('Missing implementation of qlik.backendApi.selectValues.');
}
}).isRequired
}).isRequired,
styleBuilder: PropTypes.shape({
hasComments: PropTypes.func.isRequired
}).isRequired,

View File

@@ -5,7 +5,7 @@ import DataCell from './data-cell.jsx';
import RowHeader from './row-header.jsx';
import { injectSeparators } from '../utilities';
const DataTable = ({ data, general, component, renderData, styling }) => {
const DataTable = ({ data, general, qlik, renderData, styling }) => {
const {
headers: {
dimension1,
@@ -42,9 +42,8 @@ const DataTable = ({ data, general, component, renderData, styling }) => {
<tr key={dimensionEntry.displayValue}>
{!renderData ?
<RowHeader
altState={data.meta.altState}
entry={dimensionEntry}
component={component}
qlik={qlik}
rowStyle={rowStyle}
styleBuilder={styleBuilder}
styling={styling}
@@ -81,7 +80,7 @@ const DataTable = ({ data, general, component, renderData, styling }) => {
general={general}
key={`${dimensionEntry.displayValue}-${id}`}
measurement={measurementData}
component={component}
qlik={qlik}
styleBuilder={styleBuilder}
styling={styling}
/>
@@ -108,7 +107,7 @@ DataTable.propTypes = {
matrix: PropTypes.arrayOf(PropTypes.array.isRequired).isRequired
}).isRequired,
general: PropTypes.shape({}).isRequired,
component: PropTypes.shape({}).isRequired,
qlik: PropTypes.shape({}).isRequired,
renderData: PropTypes.bool,
styling: PropTypes.shape({
hasCustomFileStyle: PropTypes.bool.isRequired

View File

@@ -1,4 +1,3 @@
import qlik from 'qlik';
import React from 'react';
import PropTypes from 'prop-types';
import HeaderPadding from './header-padding.jsx';
@@ -12,14 +11,13 @@ class RowHeader extends React.PureComponent {
}
handleSelect () {
const { entry, altState, component } = this.props;
const app = qlik.currApp(component);
app.field(entry.name, altState).select([entry.elementNumber], false, false);
const { entry, qlik } = this.props;
qlik.backendApi.selectValues(0, [entry.elementNumber], true);
}
render () {
const { entry, rowStyle, styleBuilder, styling, component } = this.props;
const inEditState = component.inEditState();
const { entry, rowStyle, styleBuilder, styling, qlik } = this.props;
const inEditState = qlik.inEditState();
return (
<td
@@ -45,12 +43,18 @@ class RowHeader extends React.PureComponent {
RowHeader.propTypes = {
entry: PropTypes.shape({
displayValue: PropTypes.string.isRequired,
elementNumber: PropTypes.number.isRequired,
name: PropTypes.string.isRequired
displayValue: PropTypes.string.isRequired
}).isRequired,
qlik: PropTypes.shape({
backendApi: PropTypes.shape({
selectValues: function (props, propName) {
if (props.isSnapshot || typeof props[propName] === 'function') {
return null;
}
return new Error('Missing implementation of qlik.backendApi.selectValues.');
}
}).isRequired
}).isRequired,
altState: PropTypes.string.isRequired,
component: PropTypes.shape({}).isRequired,
rowStyle: PropTypes.shape({}).isRequired,
styleBuilder: PropTypes.shape({}).isRequired,
styling: PropTypes.shape({}).isRequired

View File

@@ -22,9 +22,7 @@ async function buildDataCube (originCubeDefinition, hasTwoDimensions, app) {
cubeDefinition.qDimensions.push(originCubeDefinition.qDimensions[1]);
}
const cube = await createCube(cubeDefinition, app);
const cubeMatrix = cube.qHyperCube.qDataPages[0].qMatrix;
app.destroySessionObject(cube.qInfo.qId);
return cubeMatrix;
return cube.qHyperCube.qDataPages[0].qMatrix;
}
export async function initializeDataCube (component, layout) {
@@ -39,7 +37,6 @@ export async function initializeDataCube (component, layout) {
const hyperCubeDef = properties.qExtendsId
? (await app.getObjectProperties(properties.qExtendsId)).properties.qHyperCubeDef
: properties.qHyperCubeDef;
hyperCubeDef.qStateName = layout.qStateName || "";
return buildDataCube(hyperCubeDef, layout.qHyperCube.qDimensionInfo.length === 2, app);
}

View File

@@ -214,10 +214,10 @@ const tableFormat = {
component: 'slider',
label: 'Column width',
ref: 'columnwidthslider',
min: 20,
max: 250,
step: 10,
defaultValue: 50
min: 1,
max: 3,
step: 1,
defaultValue: 2
},
SymbolForNulls: {
ref: 'symbolfornulls',

View File

@@ -83,7 +83,7 @@ function buildTableHTML (id, title, subtitle, footnote) {
function downloadXLS (html) {
const filename = 'analysis.xls';
const blobObject = new Blob([html]);
const blobObject = new Blob([html], { type: 'application/vnd.ms-excel' });
// IE/Edge
if (window.navigator.msSaveOrOpenBlob) {

View File

@@ -1,4 +1,3 @@
import qlik from 'qlik';
import React from 'react';
import PropTypes from 'prop-types';
import { HEADER_FONT_SIZE } from '../initialize-transformed';
@@ -11,28 +10,25 @@ class ColumnHeader extends React.PureComponent {
}
handleSelect () {
const { entry, altState, component } = this.props;
const app = qlik.currApp(component);
app.field(entry.name, altState).select([entry.elementNumber], false, false);
const { entry, qlik } = this.props;
qlik.backendApi.selectValues(1, [entry.elementNumber], true);
}
render () {
const { baseCSS, cellWidth, colSpan, entry, styling, component } = this.props;
const inEditState = component.inEditState();
const { baseCSS, cellSuffix, colSpan, entry, styling, qlik } = this.props;
const inEditState = qlik.inEditState();
const isMediumFontSize = styling.headerOptions.fontSizeAdjustment === HEADER_FONT_SIZE.MEDIUM;
const style = {
...baseCSS,
fontSize: `${14 + styling.headerOptions.fontSizeAdjustment}px`,
height: isMediumFontSize ? '43px' : '33px',
verticalAlign: 'middle',
minWidth: cellWidth,
maxWidth: cellWidth
verticalAlign: 'middle'
};
return (
<th
className="grid-cells"
className={`grid-cells2${cellSuffix}`}
colSpan={colSpan}
onClick={this.handleSelect}
style={style}
@@ -50,20 +46,28 @@ class ColumnHeader extends React.PureComponent {
}
ColumnHeader.defaultProps = {
cellSuffix: '',
colSpan: 1
};
ColumnHeader.propTypes = {
baseCSS: PropTypes.shape({}).isRequired,
cellWidth: PropTypes.string,
cellSuffix: PropTypes.string,
colSpan: PropTypes.number,
entry: PropTypes.shape({
displayValue: PropTypes.string.isRequired,
elementNumber: PropTypes.number.isRequired,
name: PropTypes.string.isRequired
}).isRequired,
altState: PropTypes.string.isRequired,
component: PropTypes.shape({}).isRequired,
qlik: PropTypes.shape({
backendApi: PropTypes.shape({
selectValues: function (props, propName) {
if (props.isSnapshot || typeof props[propName] === 'function') {
return null;
}
return new Error('Missing implementation of qlik.backendApi.selectValues.');
}
}).isRequired
}).isRequired,
styling: PropTypes.shape({
headerOptions: PropTypes.shape({
fontSizeAdjustment: PropTypes.number.isRequired

View File

@@ -5,7 +5,7 @@ import ColumnHeader from './column-header.jsx';
import MeasurementColumnHeader from './measurement-column-header.jsx';
import { injectSeparators } from '../utilities';
const HeadersTable = ({ data, general, component, styling, isKpi }) => {
const HeadersTable = ({ data, general, qlik, styling, isKpi }) => {
const baseCSS = {
backgroundColor: styling.headerOptions.colorSchema,
color: styling.headerOptions.textColor,
@@ -28,7 +28,7 @@ const HeadersTable = ({ data, general, component, styling, isKpi }) => {
<tr>
{isKpi ?
<ExportColumnHeader
id={component.$scope.layout.qInfo.qId}
id={qlik.options.id}
allowExcelExport={general.allowExcelExport}
baseCSS={baseCSS}
general={general}
@@ -67,13 +67,12 @@ const HeadersTable = ({ data, general, component, styling, isKpi }) => {
}
return (
<ColumnHeader
altState={data.meta.altState}
baseCSS={baseCSS}
cellWidth={general.cellWidth}
cellSuffix={general.cellSuffix}
colSpan={measurements.length}
entry={entry}
key={entry.displayValue}
component={component}
qlik={qlik}
styling={styling}
/>
);
@@ -125,13 +124,19 @@ HeadersTable.propTypes = {
dimension1: PropTypes.array,
dimension2: PropTypes.array,
measurements: PropTypes.array
}),
meta: PropTypes.shape({
altState: PropTypes.string.isRequired
})
}).isRequired,
general: PropTypes.shape({}).isRequired,
component: PropTypes.shape({}).isRequired,
qlik: PropTypes.shape({
backendApi: PropTypes.shape({
selectValues: function (props, propName) {
if (props.isSnapshot || typeof props[propName] === 'function') {
return null;
}
return new Error('Missing implementation of qlik.backendApi.selectValues.');
}
}).isRequired
}).isRequired,
styling: PropTypes.shape({
headerOptions: PropTypes.shape({}),
options: PropTypes.shape({})

View File

@@ -11,20 +11,20 @@ const MeasurementColumnHeader = ({ baseCSS, general, hasSecondDimension, measure
if (hasSecondDimension) {
const isPercentageFormat = measurement.format.substring(measurement.format.length - 1) === '%';
let baseFontSize = 14;
let cellClass = 'grid-cells2';
if (isPercentageFormat) {
baseFontSize = 13;
cellClass = 'grid-cells2-small';
}
const cellStyle = {
...baseCSS,
fontSize: `${baseFontSize + fontSizeAdjustment}px`,
height: isMediumFontSize ? '45px' : '35px',
verticalAlign: 'middle',
minWidth: general.cellWidth,
maxWidth: general.cellWidth
verticalAlign: 'middle'
};
return (
<th
className="grid-cells"
className={`${cellClass}${general.cellSuffix}`}
style={cellStyle}
>
<Tooltip
@@ -41,13 +41,11 @@ const MeasurementColumnHeader = ({ baseCSS, general, hasSecondDimension, measure
...baseCSS,
fontSize: `${15 + fontSizeAdjustment}px`,
height: isMediumFontSize ? '90px' : '70px',
verticalAlign: 'middle',
minWidth: general.cellWidth,
maxWidth: general.cellWidth
verticalAlign: 'middle'
};
return (
<th
className="grid-cells"
className={`grid-cells2${general.cellSuffix}`}
style={style}
>
<Tooltip
@@ -67,7 +65,7 @@ MeasurementColumnHeader.defaultProps = {
MeasurementColumnHeader.propTypes = {
baseCSS: PropTypes.shape({}).isRequired,
general: PropTypes.shape({
cellWidth: PropTypes.string.isRequired
cellSuffix: PropTypes.string.isRequired
}).isRequired,
hasSecondDimension: PropTypes.bool,
measurement: PropTypes.shape({

View File

@@ -71,7 +71,7 @@ export default {
const jsx = (
<Root
editmodeClass={editmodeClass}
component={this}
qlik={this}
state={state}
/>
);

View File

@@ -24,6 +24,15 @@ function getFontSizeAdjustment (option) {
return fontSizeAdjustmentOptions[option] || 0;
}
function getCellSuffix (option) {
const cellSuffixOptions = {
1: '-s',
3: '-l'
};
return cellSuffixOptions[option] || '';
}
function generateMeasurements (information) {
return information.map(measurement => {
const transformedMeasurement = {
@@ -238,15 +247,13 @@ function initializeTransformed ({ $element, component, dataCube, designList, lay
},
matrix, // 2d array of all rows/cells to render in body of datatable
meta: {
dimensionCount: dimensionsInformation.length,
altState: layout.qStateName || ""
dimensionCount: dimensionsInformation.length
}
},
general: {
allowExcelExport: layout.allowexportxls,
allowFilteringByClick: layout.filteroncellclick,
// If using the previous solution just set 60px
cellWidth: `${layout.columnwidthslider > 10 ? layout.columnwidthslider : 60}px`,
cellSuffix: getCellSuffix(layout.columnwidthslider), // TOOD: move to matrix cells or is it headers.measurements?
errorMessage: layout.errormessage,
footnote: layout.footnote,
maxLoops,

View File

@@ -12,7 +12,9 @@
pointer-events: none;
}
.grid-cells {
._cell(@Width: 50px) {
min-width: @Width !important;
max-width: @Width !important;
cursor: pointer;
line-height: 1em !important;
}
@@ -72,6 +74,67 @@
text-align: right;
}
// *****************
// Medium column size
// *****************
.grid-cells {
position: relative;
._cell(70px);
}
.grid-cells2 {
._cell(70px);
}
.grid-cells-small {
._cell(52px);
}
.grid-cells2-small {
._cell(52px);
}
// *****************
// Small column size
// *****************
.grid-cells-s {
._cell(67px);
}
.grid-cells2-s {
._cell(67px);
}
.grid-cells-small-s {
._cell(52px);
}
.grid-cells2-small-s {
._cell(52px);
}
// *****************
// Large column size
// *****************
.grid-cells-l {
._cell(82px);
}
.grid-cells2-l {
._cell(82px);
}
.grid-cells-small-l {
._cell(66px);
}
.grid-cells2-small-l {
._cell(66px);
}
// END OF GRID CELLS
// First Column
.fdim-cells {
min-width: 230px !Important;
@@ -86,6 +149,14 @@
color: #fff;
}
.grid-cells-header {
padding: 0;
}
.grid-cells-title {
min-width: 522px;
}
.grid {
height: 50px;
width: 350px;

View File

@@ -4,7 +4,7 @@ import HeadersTable from './headers-table/index.jsx';
import DataTable from './data-table/index.jsx';
import { LinkedScrollWrapper, LinkedScrollSection } from './linked-scroll';
const Root = ({ state, component, editmodeClass }) => (
const Root = ({ state, qlik, editmodeClass }) => (
<div className="root">
<LinkedScrollWrapper>
<div className={`kpi-table ${editmodeClass}`}>
@@ -12,14 +12,14 @@ const Root = ({ state, component, editmodeClass }) => (
data={state.data}
general={state.general}
isKpi
component={component}
qlik={qlik}
styling={state.styling}
/>
<LinkedScrollSection linkVertical>
<DataTable
data={state.data}
general={state.general}
component={component}
qlik={qlik}
renderData={false}
styling={state.styling}
/>
@@ -31,7 +31,7 @@ const Root = ({ state, component, editmodeClass }) => (
data={state.data}
general={state.general}
isKpi={false}
component={component}
qlik={qlik}
styling={state.styling}
/>
</LinkedScrollSection>
@@ -42,7 +42,7 @@ const Root = ({ state, component, editmodeClass }) => (
<DataTable
data={state.data}
general={state.general}
component={component}
qlik={qlik}
styling={state.styling}
/>
</LinkedScrollSection>
@@ -52,7 +52,7 @@ const Root = ({ state, component, editmodeClass }) => (
);
Root.propTypes = {
component: PropTypes.shape({}).isRequired,
qlik: PropTypes.shape({}).isRequired,
state: PropTypes.shape({
data: PropTypes.object.isRequired,
general: PropTypes.object.isRequired,