refactor(monorepo): move superset-ui to superset(stage 2) (#17552)

This commit is contained in:
Yongjie Zhao
2021-11-30 08:29:57 +08:00
committed by GitHub
parent bfba4f1689
commit 3c41ff68a4
1315 changed files with 27755 additions and 15167 deletions

View File

@@ -0,0 +1,60 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { DataRecordValue, TimeFormatFunction } from '@superset-ui/core';
const REGEXP_TIMESTAMP_NO_TIMEZONE = /T(\d{2}:){2}\d{2}$/;
/**
* Extended Date object with a custom formatter, and retains the original input
* when the formatter is simple `String(..)`.
*/
export default class DateWithFormatter extends Date {
formatter: TimeFormatFunction;
input: DataRecordValue;
constructor(
input: DataRecordValue,
{
formatter = String,
forceUTC = true,
}: { formatter?: TimeFormatFunction; forceUTC?: boolean } = {},
) {
let value = input;
// assuming timestamps without a timezone is in UTC time
if (
forceUTC &&
typeof value === 'string' &&
REGEXP_TIMESTAMP_NO_TIMEZONE.test(value)
) {
value = `${value}Z`;
}
super(value as string);
this.input = input;
this.formatter = formatter;
this.toString = (): string => {
if (this.formatter === String) {
return String(this.input);
}
return this.formatter ? this.formatter(this) : Date.toString.call(this);
};
}
}

View File

@@ -0,0 +1,45 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
export default function extent<T = number | string | Date | undefined | null>(
values: T[],
) {
let min: T | undefined;
let max: T | undefined;
// eslint-disable-next-line no-restricted-syntax
for (const value of values) {
if (value !== null) {
if (min === undefined) {
if (value !== undefined) {
min = value;
max = value;
}
} else {
if (min > value) {
min = value;
}
if (max !== undefined) {
if (max < value) {
max = value;
}
}
}
}
}
return [min, max];
}

View File

@@ -0,0 +1,94 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { FilterXSS, getDefaultWhiteList } from 'xss';
import {
DataRecordValue,
GenericDataType,
getNumberFormatter,
} from '@superset-ui/core';
import { DataColumnMeta } from '../types';
const xss = new FilterXSS({
whiteList: {
...getDefaultWhiteList(),
span: ['style', 'class', 'title'],
div: ['style', 'class'],
a: ['style', 'class', 'href', 'title', 'target'],
img: ['style', 'class', 'src', 'alt', 'title', 'width', 'height'],
video: [
'autoplay',
'controls',
'loop',
'preload',
'src',
'height',
'width',
'muted',
],
},
stripIgnoreTag: true,
css: false,
});
function isProbablyHTML(text: string) {
return /<[^>]+>/.test(text);
}
/**
* Format text for cell value.
*/
function formatValue(
formatter: DataColumnMeta['formatter'],
value: DataRecordValue,
): [boolean, string] {
// render undefined as empty string
if (value === undefined) {
return [false, ''];
}
// render null as `N/A`
if (value === null) {
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') {
return isProbablyHTML(value) ? [true, xss.process(value)] : [false, value];
}
return [false, value.toString()];
}
export function formatColumnValue(
column: DataColumnMeta,
value: DataRecordValue,
) {
const { dataType, formatter, config = {} } = column;
const isNumber = dataType === GenericDataType.NUMERIC;
const smallNumberFormatter =
config.d3SmallNumberFormat === undefined
? formatter
: getNumberFormatter(config.d3SmallNumberFormat);
return formatValue(
isNumber && typeof value === 'number' && Math.abs(value) < 1
? smallNumberFormatter
: formatter,
value,
);
}

View File

@@ -0,0 +1,31 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
export default function isEqualArray<T extends unknown[] | undefined | null>(
arrA: T,
arrB: T,
) {
return (
arrA === arrB ||
(!arrA && !arrB) ||
(arrA &&
arrB &&
arrA.length === arrB.length &&
arrA.every((x, i) => x === arrB[i]))
);
}

View File

@@ -0,0 +1,43 @@
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import isEqualArray from './isEqualArray';
import { TableChartProps } from '../types';
export default function isEqualColumns(
propsA: TableChartProps[],
propsB: TableChartProps[],
) {
const a = propsA[0];
const b = propsB[0];
return (
a.datasource.columnFormats === b.datasource.columnFormats &&
a.datasource.verboseMap === b.datasource.verboseMap &&
a.formData.tableTimestampFormat === b.formData.tableTimestampFormat &&
a.formData.timeGrainSqla === b.formData.timeGrainSqla &&
JSON.stringify(a.formData.columnConfig || null) ===
JSON.stringify(b.formData.columnConfig || null) &&
isEqualArray(a.formData.metrics, b.formData.metrics) &&
isEqualArray(a.queriesData?.[0]?.colnames, b.queriesData?.[0]?.colnames) &&
isEqualArray(a.queriesData?.[0]?.coltypes, b.queriesData?.[0]?.coltypes) &&
JSON.stringify(a.formData.extraFilters || null) ===
JSON.stringify(b.formData.extraFilters || null) &&
JSON.stringify(a.formData.extraFormData || null) ===
JSON.stringify(b.formData.extraFormData || null)
);
}