feat: get html (links/styling/img/...) to work in pivot table (#29724)
This commit is contained in:
parent
c094ac3584
commit
c5829419e3
|
|
@ -154,6 +154,7 @@ export default function PivotTableChart(props: PivotTableProps) {
|
||||||
dateFormatters,
|
dateFormatters,
|
||||||
onContextMenu,
|
onContextMenu,
|
||||||
timeGrainSqla,
|
timeGrainSqla,
|
||||||
|
allowRenderHtml,
|
||||||
} = props;
|
} = props;
|
||||||
|
|
||||||
const theme = useTheme();
|
const theme = useTheme();
|
||||||
|
|
@ -555,6 +556,7 @@ export default function PivotTableChart(props: PivotTableProps) {
|
||||||
subtotalOptions={subtotalOptions}
|
subtotalOptions={subtotalOptions}
|
||||||
namesMapping={verboseMap}
|
namesMapping={verboseMap}
|
||||||
onContextMenu={handleContextMenu}
|
onContextMenu={handleContextMenu}
|
||||||
|
allowRenderHtml={allowRenderHtml}
|
||||||
/>
|
/>
|
||||||
</PivotTableWrapper>
|
</PivotTableWrapper>
|
||||||
</Styles>
|
</Styles>
|
||||||
|
|
|
||||||
|
|
@ -428,6 +428,18 @@ const config: ControlPanelConfig = {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
[
|
||||||
|
{
|
||||||
|
name: 'allow_render_html',
|
||||||
|
config: {
|
||||||
|
type: 'CheckboxControl',
|
||||||
|
label: t('Render columns in HTML format'),
|
||||||
|
renderTrigger: true,
|
||||||
|
default: true,
|
||||||
|
description: t('Render data in HTML format if applicable.'),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
|
|
||||||
|
|
@ -105,6 +105,7 @@ export default function transformProps(chartProps: ChartProps<QueryFormData>) {
|
||||||
conditionalFormatting,
|
conditionalFormatting,
|
||||||
timeGrainSqla,
|
timeGrainSqla,
|
||||||
currencyFormat,
|
currencyFormat,
|
||||||
|
allowRenderHtml,
|
||||||
} = formData;
|
} = formData;
|
||||||
const { selectedFilters } = filterState;
|
const { selectedFilters } = filterState;
|
||||||
const granularity = extractTimegrain(rawFormData);
|
const granularity = extractTimegrain(rawFormData);
|
||||||
|
|
@ -174,5 +175,6 @@ export default function transformProps(chartProps: ChartProps<QueryFormData>) {
|
||||||
dateFormatters,
|
dateFormatters,
|
||||||
onContextMenu,
|
onContextMenu,
|
||||||
timeGrainSqla,
|
timeGrainSqla,
|
||||||
|
allowRenderHtml,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { Component } from 'react';
|
import { Component } from 'react';
|
||||||
import { t } from '@superset-ui/core';
|
import { t, safeHtmlSpan } from '@superset-ui/core';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
import { PivotData, flatKey } from './utilities';
|
import { PivotData, flatKey } from './utilities';
|
||||||
import { Styles } from './Styles';
|
import { Styles } from './Styles';
|
||||||
|
|
@ -40,8 +40,13 @@ function displayHeaderCell(
|
||||||
onArrowClick,
|
onArrowClick,
|
||||||
value,
|
value,
|
||||||
namesMapping,
|
namesMapping,
|
||||||
|
allowRenderHtml,
|
||||||
) {
|
) {
|
||||||
const name = namesMapping[value] || value;
|
const name = namesMapping[value] || value;
|
||||||
|
const parsedLabel = parseLabel(name);
|
||||||
|
const labelContent = allowRenderHtml
|
||||||
|
? safeHtmlSpan(parsedLabel)
|
||||||
|
: parsedLabel;
|
||||||
return needToggle ? (
|
return needToggle ? (
|
||||||
<span className="toggle-wrapper">
|
<span className="toggle-wrapper">
|
||||||
<span
|
<span
|
||||||
|
|
@ -52,10 +57,10 @@ function displayHeaderCell(
|
||||||
>
|
>
|
||||||
{ArrowIcon}
|
{ArrowIcon}
|
||||||
</span>
|
</span>
|
||||||
<span className="toggle-val">{parseLabel(name)}</span>
|
<span className="toggle-val">{labelContent}</span>
|
||||||
</span>
|
</span>
|
||||||
) : (
|
) : (
|
||||||
parseLabel(name)
|
labelContent
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -179,6 +184,7 @@ export class TableRenderer extends Component {
|
||||||
colTotalCallbacks,
|
colTotalCallbacks,
|
||||||
grandTotalCallback,
|
grandTotalCallback,
|
||||||
namesMapping,
|
namesMapping,
|
||||||
|
allowRenderHtml: props.allowRenderHtml,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -351,6 +357,7 @@ export class TableRenderer extends Component {
|
||||||
maxColVisible,
|
maxColVisible,
|
||||||
pivotData,
|
pivotData,
|
||||||
namesMapping,
|
namesMapping,
|
||||||
|
allowRenderHtml,
|
||||||
} = pivotSettings;
|
} = pivotSettings;
|
||||||
const {
|
const {
|
||||||
highlightHeaderCellsOnHover,
|
highlightHeaderCellsOnHover,
|
||||||
|
|
@ -388,6 +395,7 @@ export class TableRenderer extends Component {
|
||||||
arrowClickHandle,
|
arrowClickHandle,
|
||||||
attrName,
|
attrName,
|
||||||
namesMapping,
|
namesMapping,
|
||||||
|
allowRenderHtml,
|
||||||
)}
|
)}
|
||||||
</th>
|
</th>
|
||||||
);
|
);
|
||||||
|
|
@ -453,6 +461,7 @@ export class TableRenderer extends Component {
|
||||||
onArrowClick,
|
onArrowClick,
|
||||||
headerCellFormattedValue,
|
headerCellFormattedValue,
|
||||||
namesMapping,
|
namesMapping,
|
||||||
|
allowRenderHtml,
|
||||||
)}
|
)}
|
||||||
</th>,
|
</th>,
|
||||||
);
|
);
|
||||||
|
|
@ -523,6 +532,7 @@ export class TableRenderer extends Component {
|
||||||
maxRowVisible,
|
maxRowVisible,
|
||||||
pivotData,
|
pivotData,
|
||||||
namesMapping,
|
namesMapping,
|
||||||
|
allowRenderHtml,
|
||||||
} = pivotSettings;
|
} = pivotSettings;
|
||||||
return (
|
return (
|
||||||
<tr key="rowHdr">
|
<tr key="rowHdr">
|
||||||
|
|
@ -546,6 +556,7 @@ export class TableRenderer extends Component {
|
||||||
arrowClickHandle,
|
arrowClickHandle,
|
||||||
r,
|
r,
|
||||||
namesMapping,
|
namesMapping,
|
||||||
|
allowRenderHtml,
|
||||||
)}
|
)}
|
||||||
</th>
|
</th>
|
||||||
);
|
);
|
||||||
|
|
@ -590,6 +601,7 @@ export class TableRenderer extends Component {
|
||||||
cellCallbacks,
|
cellCallbacks,
|
||||||
rowTotalCallbacks,
|
rowTotalCallbacks,
|
||||||
namesMapping,
|
namesMapping,
|
||||||
|
allowRenderHtml,
|
||||||
} = pivotSettings;
|
} = pivotSettings;
|
||||||
|
|
||||||
const {
|
const {
|
||||||
|
|
@ -659,6 +671,7 @@ export class TableRenderer extends Component {
|
||||||
onArrowClick,
|
onArrowClick,
|
||||||
headerCellFormattedValue,
|
headerCellFormattedValue,
|
||||||
namesMapping,
|
namesMapping,
|
||||||
|
allowRenderHtml,
|
||||||
)}
|
)}
|
||||||
</th>
|
</th>
|
||||||
);
|
);
|
||||||
|
|
@ -871,6 +884,7 @@ export class TableRenderer extends Component {
|
||||||
colTotals,
|
colTotals,
|
||||||
rowSubtotalDisplay,
|
rowSubtotalDisplay,
|
||||||
colSubtotalDisplay,
|
colSubtotalDisplay,
|
||||||
|
allowRenderHtml,
|
||||||
} = this.cachedBasePivotSettings;
|
} = this.cachedBasePivotSettings;
|
||||||
|
|
||||||
// Need to account for exclusions to compute the effective row
|
// Need to account for exclusions to compute the effective row
|
||||||
|
|
@ -895,6 +909,7 @@ export class TableRenderer extends Component {
|
||||||
maxColVisible: Math.max(...visibleColKeys.map(k => k.length)),
|
maxColVisible: Math.max(...visibleColKeys.map(k => k.length)),
|
||||||
rowAttrSpans: this.calcAttrSpans(visibleRowKeys, rowAttrs.length),
|
rowAttrSpans: this.calcAttrSpans(visibleRowKeys, rowAttrs.length),
|
||||||
colAttrSpans: this.calcAttrSpans(visibleColKeys, colAttrs.length),
|
colAttrSpans: this.calcAttrSpans(visibleColKeys, colAttrs.length),
|
||||||
|
allowRenderHtml,
|
||||||
...this.cachedBasePivotSettings,
|
...this.cachedBasePivotSettings,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -87,6 +87,7 @@ interface PivotTableCustomizeProps {
|
||||||
timeGrainSqla?: TimeGranularity;
|
timeGrainSqla?: TimeGranularity;
|
||||||
time_grain_sqla?: TimeGranularity;
|
time_grain_sqla?: TimeGranularity;
|
||||||
granularity_sqla?: string;
|
granularity_sqla?: string;
|
||||||
|
allowRenderHtml?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type PivotTableQueryFormData = QueryFormData &
|
export type PivotTableQueryFormData = QueryFormData &
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue