mirror of
https://github.com/apache/superset.git
synced 2026-04-23 10:04:45 +00:00
feat: Implement currencies formatter for saved metrics (#24517)
This commit is contained in:
committed by
GitHub
parent
e402c94a9f
commit
83ff4cd86a
@@ -2,30 +2,27 @@
|
||||
"name": "@superset-ui/plugin-chart-table",
|
||||
"version": "0.18.25",
|
||||
"description": "Superset Chart - Table",
|
||||
"main": "lib/index.js",
|
||||
"module": "esm/index.js",
|
||||
"sideEffects": false,
|
||||
"files": [
|
||||
"esm",
|
||||
"lib"
|
||||
"keywords": [
|
||||
"superset"
|
||||
],
|
||||
"homepage": "https://github.com/apache/superset/tree/master/superset-frontend/plugins/plugin-chart-table#readme",
|
||||
"bugs": {
|
||||
"url": "https://github.com/apache/superset/issues"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/apache/superset.git",
|
||||
"directory": "superset-frontend/plugins/plugin-chart-table"
|
||||
},
|
||||
"keywords": [
|
||||
"superset"
|
||||
],
|
||||
"author": "Superset",
|
||||
"license": "Apache-2.0",
|
||||
"bugs": {
|
||||
"url": "https://github.com/apache/superset/issues"
|
||||
},
|
||||
"homepage": "https://github.com/apache/superset/tree/master/superset-frontend/plugins/plugin-chart-table#readme",
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
},
|
||||
"author": "Superset",
|
||||
"sideEffects": false,
|
||||
"main": "lib/index.js",
|
||||
"module": "esm/index.js",
|
||||
"files": [
|
||||
"esm",
|
||||
"lib"
|
||||
],
|
||||
"dependencies": {
|
||||
"@react-icons/all-files": "^4.1.0",
|
||||
"@types/d3-array": "^2.9.0",
|
||||
@@ -40,15 +37,20 @@
|
||||
"regenerator-runtime": "^0.13.7",
|
||||
"xss": "^1.0.10"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@testing-library/react": "^11.2.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@superset-ui/chart-controls": "*",
|
||||
"@superset-ui/core": "*",
|
||||
"@testing-library/dom": "^7.29.4",
|
||||
"@testing-library/jest-dom": "^5.11.6",
|
||||
"@testing-library/react": "^11.2.0",
|
||||
"@testing-library/react-hooks": "^5.0.3",
|
||||
"@testing-library/user-event": "^12.7.0",
|
||||
"@types/classnames": "*",
|
||||
"@types/react": "*",
|
||||
"react": "^16.13.1",
|
||||
"react-dom": "^16.13.1"
|
||||
},
|
||||
"publishConfig": {
|
||||
"access": "public"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
*/
|
||||
import memoizeOne from 'memoize-one';
|
||||
import {
|
||||
CurrencyFormatter,
|
||||
DataRecord,
|
||||
extractTimegrain,
|
||||
GenericDataType,
|
||||
@@ -84,7 +85,7 @@ const processColumns = memoizeOne(function processColumns(
|
||||
props: TableChartProps,
|
||||
) {
|
||||
const {
|
||||
datasource: { columnFormats, verboseMap },
|
||||
datasource: { columnFormats, currencyFormats, verboseMap },
|
||||
rawFormData: {
|
||||
table_timestamp_format: tableTimestampFormat,
|
||||
metrics: metrics_,
|
||||
@@ -123,6 +124,7 @@ const processColumns = memoizeOne(function processColumns(
|
||||
const isTime = dataType === GenericDataType.TEMPORAL;
|
||||
const isNumber = dataType === GenericDataType.NUMERIC;
|
||||
const savedFormat = columnFormats?.[key];
|
||||
const currency = currencyFormats?.[key];
|
||||
const numberFormat = config.d3NumberFormat || savedFormat;
|
||||
|
||||
let formatter;
|
||||
@@ -155,7 +157,9 @@ const processColumns = memoizeOne(function processColumns(
|
||||
// percent metrics have a default format
|
||||
formatter = getNumberFormatter(numberFormat || PERCENT_3_POINT);
|
||||
} else if (isMetric || (isNumber && numberFormat)) {
|
||||
formatter = getNumberFormatter(numberFormat);
|
||||
formatter = currency
|
||||
? new CurrencyFormatter({ d3Format: numberFormat, currency })
|
||||
: getNumberFormatter(numberFormat);
|
||||
}
|
||||
return {
|
||||
key,
|
||||
|
||||
@@ -31,6 +31,7 @@ import {
|
||||
QueryFormData,
|
||||
SetDataMaskHook,
|
||||
ContextMenuFilters,
|
||||
CurrencyFormatter,
|
||||
} from '@superset-ui/core';
|
||||
import { ColorFormatters, ColumnConfig } from '@superset-ui/chart-controls';
|
||||
|
||||
@@ -42,7 +43,11 @@ export interface DataColumnMeta {
|
||||
// `label` is verbose column name used for rendering
|
||||
label: string;
|
||||
dataType: GenericDataType;
|
||||
formatter?: TimeFormatter | NumberFormatter | CustomFormatter;
|
||||
formatter?:
|
||||
| TimeFormatter
|
||||
| NumberFormatter
|
||||
| CustomFormatter
|
||||
| CurrencyFormatter;
|
||||
isMetric?: boolean;
|
||||
isPercentMetric?: boolean;
|
||||
isNumeric?: boolean;
|
||||
|
||||
@@ -47,7 +47,6 @@ function formatValue(
|
||||
return [false, 'N/A'];
|
||||
}
|
||||
if (formatter) {
|
||||
// in case percent metric can specify percent format in the future
|
||||
return [false, formatter(value as number)];
|
||||
}
|
||||
if (typeof value === 'string') {
|
||||
|
||||
@@ -27,6 +27,7 @@ export default function isEqualColumns(
|
||||
const b = propsB[0];
|
||||
return (
|
||||
a.datasource.columnFormats === b.datasource.columnFormats &&
|
||||
a.datasource.currencyFormats === b.datasource.currencyFormats &&
|
||||
a.datasource.verboseMap === b.datasource.verboseMap &&
|
||||
a.formData.tableTimestampFormat === b.formData.tableTimestampFormat &&
|
||||
a.formData.timeGrainSqla === b.formData.timeGrainSqla &&
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
import React from 'react';
|
||||
import { CommonWrapper } from 'enzyme';
|
||||
import { render, screen } from '@testing-library/react';
|
||||
import '@testing-library/jest-dom';
|
||||
import TableChart from '../src/TableChart';
|
||||
import transformProps from '../src/transformProps';
|
||||
import DateWithFormatter from '../src/utils/DateWithFormatter';
|
||||
@@ -102,6 +103,26 @@ describe('plugin-chart-table', () => {
|
||||
expect(cells.eq(4).text()).toEqual('2.47k');
|
||||
});
|
||||
|
||||
it('render advanced data with currencies', () => {
|
||||
render(
|
||||
ProviderWrapper({
|
||||
children: (
|
||||
<TableChart
|
||||
{...transformProps(testData.advancedWithCurrency)}
|
||||
sticky={false}
|
||||
/>
|
||||
),
|
||||
}),
|
||||
);
|
||||
const cells = document.querySelectorAll('td');
|
||||
expect(document.querySelectorAll('th')[1]).toHaveTextContent(
|
||||
'Sum of Num',
|
||||
);
|
||||
expect(cells[0]).toHaveTextContent('Michael');
|
||||
expect(cells[2]).toHaveTextContent('12.346%');
|
||||
expect(cells[4]).toHaveTextContent('$ 2.47k');
|
||||
});
|
||||
|
||||
it('render empty data', () => {
|
||||
wrap.setProps({ ...transformProps(testData.empty), sticky: false });
|
||||
tree = wrap.render();
|
||||
|
||||
@@ -173,6 +173,16 @@ const advanced: TableChartProps = {
|
||||
],
|
||||
};
|
||||
|
||||
const advancedWithCurrency = {
|
||||
...advanced,
|
||||
datasource: {
|
||||
...advanced.datasource,
|
||||
currencyFormats: {
|
||||
sum__num: { symbol: 'USD', symbolPosition: 'prefix' },
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const empty = {
|
||||
...advanced,
|
||||
queriesData: [
|
||||
@@ -186,5 +196,6 @@ const empty = {
|
||||
export default {
|
||||
basic,
|
||||
advanced,
|
||||
advancedWithCurrency,
|
||||
empty,
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user