mirror of
https://github.com/apache/superset.git
synced 2026-04-30 13:34:20 +00:00
Compare commits
13 Commits
fix-webpac
...
no-console
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
0f3f4e36d6 | ||
|
|
646b67faa0 | ||
|
|
7a59c256ed | ||
|
|
4bc9c844c3 | ||
|
|
0216548e5d | ||
|
|
fee6ab61d7 | ||
|
|
49a3966104 | ||
|
|
df6975ecbd | ||
|
|
00da9b8c10 | ||
|
|
9a5f7779f1 | ||
|
|
99ac6822ae | ||
|
|
991a928c92 | ||
|
|
6da0aa8b51 |
@@ -143,6 +143,7 @@ module.exports = {
|
|||||||
],
|
],
|
||||||
plugins: ['@typescript-eslint/eslint-plugin', 'react', 'prettier'],
|
plugins: ['@typescript-eslint/eslint-plugin', 'react', 'prettier'],
|
||||||
rules: {
|
rules: {
|
||||||
|
'no-console': 'error',
|
||||||
'@typescript-eslint/ban-ts-ignore': 0,
|
'@typescript-eslint/ban-ts-ignore': 0,
|
||||||
'@typescript-eslint/ban-ts-comment': 0, // disabled temporarily
|
'@typescript-eslint/ban-ts-comment': 0, // disabled temporarily
|
||||||
'@typescript-eslint/ban-types': 0, // disabled temporarily
|
'@typescript-eslint/ban-types': 0, // disabled temporarily
|
||||||
@@ -340,6 +341,20 @@ module.exports = {
|
|||||||
'plugin:testing-library/react',
|
'plugin:testing-library/react',
|
||||||
],
|
],
|
||||||
rules: {
|
rules: {
|
||||||
|
'no-console': 'off', // Allow console usage in test files
|
||||||
|
'no-restricted-imports': [
|
||||||
|
'error',
|
||||||
|
{
|
||||||
|
paths: [
|
||||||
|
{
|
||||||
|
name: '@superset-ui/core',
|
||||||
|
importNames: ['logging'],
|
||||||
|
message:
|
||||||
|
'Do not use logging in test files. Use console statements instead for testing.',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
'import/no-extraneous-dependencies': [
|
'import/no-extraneous-dependencies': [
|
||||||
'error',
|
'error',
|
||||||
{
|
{
|
||||||
@@ -373,7 +388,6 @@ module.exports = {
|
|||||||
'Default React import is not required due to automatic JSX runtime in React 16.4',
|
'Default React import is not required due to automatic JSX runtime in React 16.4',
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
'no-restricted-imports': 0,
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -397,9 +411,16 @@ module.exports = {
|
|||||||
'react/no-void-elements': 0,
|
'react/no-void-elements': 0,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
files: ['scripts/**/*'],
|
||||||
|
rules: {
|
||||||
|
'no-console': 'off', // Allow console usage in scripts directory
|
||||||
|
},
|
||||||
|
},
|
||||||
],
|
],
|
||||||
// eslint-disable-next-line no-dupe-keys
|
// eslint-disable-next-line no-dupe-keys
|
||||||
rules: {
|
rules: {
|
||||||
|
'no-console': 'error',
|
||||||
'theme-colors/no-literal-colors': 'error',
|
'theme-colors/no-literal-colors': 'error',
|
||||||
'icons/no-fa-icons-usage': 'error',
|
'icons/no-fa-icons-usage': 'error',
|
||||||
'i18n-strings/no-template-vars': ['error', true],
|
'i18n-strings/no-template-vars': ['error', true],
|
||||||
|
|||||||
5
superset-frontend/package-lock.json
generated
5
superset-frontend/package-lock.json
generated
@@ -62354,7 +62354,10 @@
|
|||||||
"packages/superset-ui-switchboard": {
|
"packages/superset-ui-switchboard": {
|
||||||
"name": "@superset-ui/switchboard",
|
"name": "@superset-ui/switchboard",
|
||||||
"version": "0.20.3",
|
"version": "0.20.3",
|
||||||
"license": "Apache-2.0"
|
"license": "Apache-2.0",
|
||||||
|
"dependencies": {
|
||||||
|
"@superset-ui/core": "^0.20.4"
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"plugins/legacy-plugin-chart-calendar": {
|
"plugins/legacy-plugin-chart-calendar": {
|
||||||
"name": "@superset-ui/legacy-plugin-chart-calendar",
|
"name": "@superset-ui/legacy-plugin-chart-calendar",
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ import { useEffect, useState } from 'react';
|
|||||||
import SyntaxHighlighterBase from 'react-syntax-highlighter/dist/cjs/light';
|
import SyntaxHighlighterBase from 'react-syntax-highlighter/dist/cjs/light';
|
||||||
import github from 'react-syntax-highlighter/dist/cjs/styles/hljs/github';
|
import github from 'react-syntax-highlighter/dist/cjs/styles/hljs/github';
|
||||||
import tomorrow from 'react-syntax-highlighter/dist/cjs/styles/hljs/tomorrow-night';
|
import tomorrow from 'react-syntax-highlighter/dist/cjs/styles/hljs/tomorrow-night';
|
||||||
import { useTheme, isThemeDark } from '@superset-ui/core';
|
import { useTheme, isThemeDark, logging } from '@superset-ui/core';
|
||||||
|
|
||||||
export type SupportedLanguage = 'sql' | 'htmlbars' | 'markdown' | 'json';
|
export type SupportedLanguage = 'sql' | 'htmlbars' | 'markdown' | 'json';
|
||||||
|
|
||||||
@@ -59,7 +59,7 @@ const registerLanguage = async (language: SupportedLanguage): Promise<void> => {
|
|||||||
SyntaxHighlighterBase.registerLanguage(language, languageModule.default);
|
SyntaxHighlighterBase.registerLanguage(language, languageModule.default);
|
||||||
registeredLanguages.add(language);
|
registeredLanguages.add(language);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.warn(`Failed to load language ${language}:`, error);
|
logging.warn(`Failed to load language ${language}:`, error);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
* under the License.
|
* under the License.
|
||||||
*/
|
*/
|
||||||
import { useState, useCallback } from 'react';
|
import { useState, useCallback } from 'react';
|
||||||
import { t } from '@superset-ui/core';
|
import { logging, t } from '@superset-ui/core';
|
||||||
import { Button } from '../Button';
|
import { Button } from '../Button';
|
||||||
import { Form } from '../Form';
|
import { Form } from '../Form';
|
||||||
import { Modal } from './Modal';
|
import { Modal } from './Modal';
|
||||||
@@ -60,7 +60,7 @@ export function FormModal({
|
|||||||
await formSubmitHandler(values);
|
await formSubmitHandler(values);
|
||||||
handleSave();
|
handleSave();
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error(err);
|
logging.error(err);
|
||||||
} finally {
|
} finally {
|
||||||
setIsSaving(false);
|
setIsSaving(false);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,6 +17,7 @@
|
|||||||
* under the License.
|
* under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import { logging } from '@superset-ui/core';
|
||||||
import fetchRetry from 'fetch-retry';
|
import fetchRetry from 'fetch-retry';
|
||||||
import { CallApi, Payload, JsonValue, JsonObject } from '../types';
|
import { CallApi, Payload, JsonValue, JsonObject } from '../types';
|
||||||
import {
|
import {
|
||||||
@@ -152,8 +153,7 @@ export default async function callApi({
|
|||||||
// while logging error to console for any attribute that fails the cast to String
|
// while logging error to console for any attribute that fails the cast to String
|
||||||
valueString = stringify ? JSON.stringify(value) : String(value);
|
valueString = stringify ? JSON.stringify(value) : String(value);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
// eslint-disable-next-line no-console
|
logging.error(
|
||||||
console.error(
|
|
||||||
`Unable to convert attribute '${key}' to a String(). '${key}' was not added to the formData in request.body for call to ${url}`,
|
`Unable to convert attribute '${key}' to a String(). '${key}' was not added to the formData in request.body for call to ${url}`,
|
||||||
value,
|
value,
|
||||||
e,
|
e,
|
||||||
|
|||||||
@@ -16,6 +16,8 @@
|
|||||||
* specific language governing permissions and limitations
|
* specific language governing permissions and limitations
|
||||||
* under the License.
|
* under the License.
|
||||||
*/
|
*/
|
||||||
|
import { logging } from '@superset-ui/core';
|
||||||
|
|
||||||
export enum OverwritePolicy {
|
export enum OverwritePolicy {
|
||||||
Allow = 'ALLOW',
|
Allow = 'ALLOW',
|
||||||
Prohibit = 'PROHIBIT',
|
Prohibit = 'PROHIBIT',
|
||||||
@@ -120,8 +122,7 @@ export default class Registry<
|
|||||||
(('value' in item && item.value !== value) || 'loader' in item);
|
(('value' in item && item.value !== value) || 'loader' in item);
|
||||||
if (willOverwrite) {
|
if (willOverwrite) {
|
||||||
if (this.overwritePolicy === OverwritePolicy.Warn) {
|
if (this.overwritePolicy === OverwritePolicy.Warn) {
|
||||||
// eslint-disable-next-line no-console
|
logging.warn(
|
||||||
console.warn(
|
|
||||||
`Item with key "${key}" already exists. You are assigning a new value.`,
|
`Item with key "${key}" already exists. You are assigning a new value.`,
|
||||||
);
|
);
|
||||||
} else if (this.overwritePolicy === OverwritePolicy.Prohibit) {
|
} else if (this.overwritePolicy === OverwritePolicy.Prohibit) {
|
||||||
@@ -146,8 +147,7 @@ export default class Registry<
|
|||||||
(('loader' in item && item.loader !== loader) || 'value' in item);
|
(('loader' in item && item.loader !== loader) || 'value' in item);
|
||||||
if (willOverwrite) {
|
if (willOverwrite) {
|
||||||
if (this.overwritePolicy === OverwritePolicy.Warn) {
|
if (this.overwritePolicy === OverwritePolicy.Warn) {
|
||||||
// eslint-disable-next-line no-console
|
logging.warn(
|
||||||
console.warn(
|
|
||||||
`Item with key "${key}" already exists. You are assigning a new value.`,
|
`Item with key "${key}" already exists. You are assigning a new value.`,
|
||||||
);
|
);
|
||||||
} else if (this.overwritePolicy === OverwritePolicy.Prohibit) {
|
} else if (this.overwritePolicy === OverwritePolicy.Prohibit) {
|
||||||
@@ -278,7 +278,7 @@ export default class Registry<
|
|||||||
listener(keys);
|
listener(keys);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
// eslint-disable-next-line no-console
|
// eslint-disable-next-line no-console
|
||||||
console.error('Exception thrown from a registry listener:', e);
|
logging.error('Exception thrown from a registry listener:', e);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ import {
|
|||||||
COMMON_ERR_MESSAGES,
|
COMMON_ERR_MESSAGES,
|
||||||
JsonObject,
|
JsonObject,
|
||||||
SupersetClientResponse,
|
SupersetClientResponse,
|
||||||
|
logging,
|
||||||
t,
|
t,
|
||||||
SupersetError,
|
SupersetError,
|
||||||
ErrorTypeEnum,
|
ErrorTypeEnum,
|
||||||
@@ -256,8 +257,7 @@ export function getClientErrorObject(
|
|||||||
// fall back to Response.statusText or generic error of we cannot read the response
|
// fall back to Response.statusText or generic error of we cannot read the response
|
||||||
let error = (response as any).statusText || (response as any).message;
|
let error = (response as any).statusText || (response as any).message;
|
||||||
if (!error) {
|
if (!error) {
|
||||||
// eslint-disable-next-line no-console
|
logging.error('non-standard error:', response);
|
||||||
console.error('non-standard error:', response);
|
|
||||||
error = t('An error occurred');
|
error = t('An error occurred');
|
||||||
}
|
}
|
||||||
resolve({
|
resolve({
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
* under the License.
|
* under the License.
|
||||||
*/
|
*/
|
||||||
import UntypedJed from 'jed';
|
import UntypedJed from 'jed';
|
||||||
import logging from '../utils/logging';
|
import { logging } from '@superset-ui/core';
|
||||||
import {
|
import {
|
||||||
Jed,
|
Jed,
|
||||||
TranslatorConfig,
|
TranslatorConfig,
|
||||||
|
|||||||
@@ -17,8 +17,7 @@
|
|||||||
* under the License.
|
* under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* eslint no-console: 0 */
|
import { logging } from '@superset-ui/core';
|
||||||
|
|
||||||
import Translator from './Translator';
|
import Translator from './Translator';
|
||||||
import { TranslatorConfig, Translations, LocaleData } from './types';
|
import { TranslatorConfig, Translations, LocaleData } from './types';
|
||||||
|
|
||||||
@@ -34,7 +33,7 @@ function configure(config?: TranslatorConfig) {
|
|||||||
|
|
||||||
function getInstance() {
|
function getInstance() {
|
||||||
if (!isConfigured) {
|
if (!isConfigured) {
|
||||||
console.warn('You should call configure(...) before calling other methods');
|
logging.warn('You should call configure(...) before calling other methods');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (typeof singleton === 'undefined') {
|
if (typeof singleton === 'undefined') {
|
||||||
|
|||||||
@@ -30,5 +30,8 @@
|
|||||||
"homepage": "https://github.com/apache/superset#readme",
|
"homepage": "https://github.com/apache/superset#readme",
|
||||||
"publishConfig": {
|
"publishConfig": {
|
||||||
"access": "public"
|
"access": "public"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@superset-ui/core": "^0.20.4"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,6 +17,8 @@
|
|||||||
* under the License.
|
* under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import { logging } from '@superset-ui/core';
|
||||||
|
|
||||||
export type Params = {
|
export type Params = {
|
||||||
port: MessagePort;
|
port: MessagePort;
|
||||||
name?: string;
|
name?: string;
|
||||||
@@ -262,12 +264,12 @@ export class Switchboard {
|
|||||||
|
|
||||||
private log(...args: unknown[]) {
|
private log(...args: unknown[]) {
|
||||||
if (this.debugMode) {
|
if (this.debugMode) {
|
||||||
console.debug(`[${this.name}]`, ...args);
|
logging.debug(`[${this.name}]`, ...args);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private logError(...args: unknown[]) {
|
private logError(...args: unknown[]) {
|
||||||
console.error(`[${this.name}]`, ...args);
|
logging.error(`[${this.name}]`, ...args);
|
||||||
}
|
}
|
||||||
|
|
||||||
private getNewMessageId() {
|
private getNewMessageId() {
|
||||||
|
|||||||
@@ -1,8 +1,7 @@
|
|||||||
{
|
{
|
||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"declarationDir": "lib",
|
"declarationDir": "lib",
|
||||||
"outDir": "lib",
|
"outDir": "lib"
|
||||||
"rootDir": "src"
|
|
||||||
},
|
},
|
||||||
"exclude": [
|
"exclude": [
|
||||||
"lib",
|
"lib",
|
||||||
@@ -14,5 +13,7 @@
|
|||||||
"types/**/*",
|
"types/**/*",
|
||||||
"../../types/**/*"
|
"../../types/**/*"
|
||||||
],
|
],
|
||||||
"references": []
|
"references": [
|
||||||
|
{ "path": "../superset-ui-core" },
|
||||||
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ import {
|
|||||||
isDefined,
|
isDefined,
|
||||||
JsonObject,
|
JsonObject,
|
||||||
JsonValue,
|
JsonValue,
|
||||||
|
logging,
|
||||||
QueryFormData,
|
QueryFormData,
|
||||||
QueryObjectFilterClause,
|
QueryObjectFilterClause,
|
||||||
SupersetClient,
|
SupersetClient,
|
||||||
@@ -254,7 +255,7 @@ const DeckMulti = (props: DeckMultiProps) => {
|
|||||||
}));
|
}));
|
||||||
})
|
})
|
||||||
.catch(error => {
|
.catch(error => {
|
||||||
console.error(
|
logging.error(
|
||||||
`Error loading layer for slice ${subsliceCopy.slice_id}:`,
|
`Error loading layer for slice ${subsliceCopy.slice_id}:`,
|
||||||
error,
|
error,
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ import BaseEvent from 'ol/events/Event';
|
|||||||
import { unByKey } from 'ol/Observable';
|
import { unByKey } from 'ol/Observable';
|
||||||
import { toLonLat } from 'ol/proj';
|
import { toLonLat } from 'ol/proj';
|
||||||
import { debounce } from 'lodash';
|
import { debounce } from 'lodash';
|
||||||
|
import { logging } from '@superset-ui/core';
|
||||||
import { fitMapToCharts } from '../util/mapUtil';
|
import { fitMapToCharts } from '../util/mapUtil';
|
||||||
import { ChartLayer } from './ChartLayer';
|
import { ChartLayer } from './ChartLayer';
|
||||||
import { createLayer } from '../util/layerUtil';
|
import { createLayer } from '../util/layerUtil';
|
||||||
@@ -188,7 +189,7 @@ export const OlChartMap = (props: OlChartMapProps) => {
|
|||||||
if (createdLayer.status === 'fulfilled' && createdLayer.value) {
|
if (createdLayer.status === 'fulfilled' && createdLayer.value) {
|
||||||
olMap.getLayers().insertAt(0, createdLayer.value);
|
olMap.getLayers().insertAt(0, createdLayer.value);
|
||||||
} else {
|
} else {
|
||||||
console.warn(`Layer could not be created: ${configs[idx]}`);
|
logging.warn(`Layer could not be created: ${configs[idx]}`);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -21,6 +21,7 @@
|
|||||||
* Util for layer related operations.
|
* Util for layer related operations.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import { logging } from '@superset-ui/core';
|
||||||
import OlParser from 'geostyler-openlayers-parser';
|
import OlParser from 'geostyler-openlayers-parser';
|
||||||
import TileLayer from 'ol/layer/Tile';
|
import TileLayer from 'ol/layer/Tile';
|
||||||
import TileWMS from 'ol/source/TileWMS';
|
import TileWMS from 'ol/source/TileWMS';
|
||||||
@@ -126,7 +127,7 @@ export const createWfsLayer = async (wfsLayerConf: WfsLayerConf) => {
|
|||||||
const olParser = new OlParser();
|
const olParser = new OlParser();
|
||||||
writeStyleResult = await olParser.writeStyle(style);
|
writeStyleResult = await olParser.writeStyle(style);
|
||||||
if (writeStyleResult.errors) {
|
if (writeStyleResult.errors) {
|
||||||
console.warn('Could not create ol-style', writeStyleResult.errors);
|
logging.warn('Could not create ol-style', writeStyleResult.errors);
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -154,7 +155,7 @@ export const createLayer = async (layerConf: LayerConf) => {
|
|||||||
} else if (isXyzLayerConf(layerConf)) {
|
} else if (isXyzLayerConf(layerConf)) {
|
||||||
layer = createXyzLayer(layerConf);
|
layer = createXyzLayer(layerConf);
|
||||||
} else {
|
} else {
|
||||||
console.warn('Provided layerconfig is not recognized');
|
logging.warn('Provided layerconfig is not recognized');
|
||||||
}
|
}
|
||||||
return layer;
|
return layer;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ import {
|
|||||||
ChartProps,
|
ChartProps,
|
||||||
convertKeysToCamelCase,
|
convertKeysToCamelCase,
|
||||||
DataRecord,
|
DataRecord,
|
||||||
|
logging,
|
||||||
} from '@superset-ui/core';
|
} from '@superset-ui/core';
|
||||||
import { isObject } from 'lodash';
|
import { isObject } from 'lodash';
|
||||||
import {
|
import {
|
||||||
@@ -89,7 +90,7 @@ export const groupByLocationGenericX = (
|
|||||||
const labelMap: string[] = queryData.label_map?.[k];
|
const labelMap: string[] = queryData.label_map?.[k];
|
||||||
|
|
||||||
if (!labelMap) {
|
if (!labelMap) {
|
||||||
console.log(
|
logging.debug(
|
||||||
'Cannot extract location from queryData. label_map not defined',
|
'Cannot extract location from queryData. label_map not defined',
|
||||||
);
|
);
|
||||||
return;
|
return;
|
||||||
@@ -99,7 +100,7 @@ export const groupByLocationGenericX = (
|
|||||||
|
|
||||||
if (geojsonCols.length > 1) {
|
if (geojsonCols.length > 1) {
|
||||||
// TODO what should we do, if there is more than one geom column?
|
// TODO what should we do, if there is more than one geom column?
|
||||||
console.log(
|
logging.debug(
|
||||||
'More than one geometry column detected. Using first found.',
|
'More than one geometry column detected. Using first found.',
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ import { merge } from 'lodash';
|
|||||||
|
|
||||||
import { useSelector } from 'react-redux';
|
import { useSelector } from 'react-redux';
|
||||||
|
|
||||||
import { styled, useTheme } from '@superset-ui/core';
|
import { styled, useTheme, logging } from '@superset-ui/core';
|
||||||
import { use, init, EChartsType, registerLocale } from 'echarts/core';
|
import { use, init, EChartsType, registerLocale } from 'echarts/core';
|
||||||
import {
|
import {
|
||||||
SankeyChart,
|
SankeyChart,
|
||||||
@@ -117,7 +117,7 @@ const loadLocale = async (locale: string) => {
|
|||||||
try {
|
try {
|
||||||
lang = await import(`echarts/lib/i18n/lang${locale}`);
|
lang = await import(`echarts/lib/i18n/lang${locale}`);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error(`Locale ${locale} not supported in ECharts`, e);
|
logging.error(`Locale ${locale} not supported in ECharts`, e);
|
||||||
}
|
}
|
||||||
return lang?.default;
|
return lang?.default;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -22,12 +22,13 @@ import React from 'react';
|
|||||||
// eslint-disable-next-line no-restricted-imports
|
// eslint-disable-next-line no-restricted-imports
|
||||||
import { configure as configureTestingLibrary } from '@testing-library/react';
|
import { configure as configureTestingLibrary } from '@testing-library/react';
|
||||||
import { matchers } from '@emotion/jest';
|
import { matchers } from '@emotion/jest';
|
||||||
|
import { DEFAULT_BOOTSTRAP_DATA } from 'src/constants';
|
||||||
|
|
||||||
configureTestingLibrary({
|
configureTestingLibrary({
|
||||||
testIdAttribute: 'data-test',
|
testIdAttribute: 'data-test',
|
||||||
});
|
});
|
||||||
|
|
||||||
document.body.innerHTML = '<div id="app" data-bootstrap=""></div>';
|
document.body.innerHTML = `<div id="app" data-bootstrap="${JSON.stringify(DEFAULT_BOOTSTRAP_DATA).replace(/"/g, '"')}"></div>`;
|
||||||
expect.extend(matchers);
|
expect.extend(matchers);
|
||||||
|
|
||||||
// Allow JSX tests to have React import readily available
|
// Allow JSX tests to have React import readily available
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ import {
|
|||||||
isFeatureEnabled,
|
isFeatureEnabled,
|
||||||
COMMON_ERR_MESSAGES,
|
COMMON_ERR_MESSAGES,
|
||||||
getClientErrorObject,
|
getClientErrorObject,
|
||||||
|
logging,
|
||||||
} from '@superset-ui/core';
|
} from '@superset-ui/core';
|
||||||
import { invert, mapKeys } from 'lodash';
|
import { invert, mapKeys } from 'lodash';
|
||||||
|
|
||||||
@@ -869,8 +870,7 @@ export function updateSavedQuery(query, clientId) {
|
|||||||
})
|
})
|
||||||
.catch(e => {
|
.catch(e => {
|
||||||
const message = t('Your query could not be updated');
|
const message = t('Your query could not be updated');
|
||||||
// eslint-disable-next-line no-console
|
logging.error(message, e);
|
||||||
console.error(message, e);
|
|
||||||
dispatch(addDangerToast(message));
|
dispatch(addDangerToast(message));
|
||||||
})
|
})
|
||||||
.then(() => dispatch(updateQueryEditor(query)));
|
.then(() => dispatch(updateQueryEditor(query)));
|
||||||
|
|||||||
@@ -29,6 +29,7 @@ import {
|
|||||||
getClientErrorObject,
|
getClientErrorObject,
|
||||||
getCategoricalSchemeRegistry,
|
getCategoricalSchemeRegistry,
|
||||||
promiseTimeout,
|
promiseTimeout,
|
||||||
|
logging,
|
||||||
} from '@superset-ui/core';
|
} from '@superset-ui/core';
|
||||||
import {
|
import {
|
||||||
addChart,
|
addChart,
|
||||||
@@ -887,7 +888,7 @@ export const applyDashboardLabelsColorOnLoad = metadata => async dispatch => {
|
|||||||
dispatch(setDashboardLabelsColorMapSync());
|
dispatch(setDashboardLabelsColorMapSync());
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error('Failed to update dashboard color on load:', e);
|
logging.error('Failed to update dashboard color on load:', e);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -1054,6 +1055,6 @@ export const updateDashboardLabelsColor = renderedChartIds => (_, getState) => {
|
|||||||
// re-apply the color map first to get fresh maps accordingly
|
// re-apply the color map first to get fresh maps accordingly
|
||||||
applyColors(metadata, shouldGoFresh, shouldMerge);
|
applyColors(metadata, shouldGoFresh, shouldMerge);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error('Failed to update colors for new charts and labels:', e);
|
logging.error('Failed to update colors for new charts and labels:', e);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ import {
|
|||||||
t,
|
t,
|
||||||
css,
|
css,
|
||||||
getExtensionsRegistry,
|
getExtensionsRegistry,
|
||||||
|
logging,
|
||||||
} from '@superset-ui/core';
|
} from '@superset-ui/core';
|
||||||
import {
|
import {
|
||||||
Button,
|
Button,
|
||||||
@@ -86,7 +87,7 @@ export const DashboardEmbedControls = ({ dashboardId, onHide }: Props) => {
|
|||||||
addInfoToast(t('Changes saved.'));
|
addInfoToast(t('Changes saved.'));
|
||||||
},
|
},
|
||||||
err => {
|
err => {
|
||||||
console.error(err);
|
logging.error(err);
|
||||||
addDangerToast(
|
addDangerToast(
|
||||||
t(
|
t(
|
||||||
t('Sorry, something went wrong. The changes could not be saved.'),
|
t('Sorry, something went wrong. The changes could not be saved.'),
|
||||||
@@ -115,7 +116,7 @@ export const DashboardEmbedControls = ({ dashboardId, onHide }: Props) => {
|
|||||||
onHide();
|
onHide();
|
||||||
},
|
},
|
||||||
err => {
|
err => {
|
||||||
console.error(err);
|
logging.error(err);
|
||||||
addDangerToast(
|
addDangerToast(
|
||||||
t(
|
t(
|
||||||
'Sorry, something went wrong. Embedding could not be deactivated.',
|
'Sorry, something went wrong. Embedding could not be deactivated.',
|
||||||
|
|||||||
@@ -18,7 +18,7 @@
|
|||||||
*/
|
*/
|
||||||
import { useMemo } from 'react';
|
import { useMemo } from 'react';
|
||||||
import { useSelector } from 'react-redux';
|
import { useSelector } from 'react-redux';
|
||||||
import { t } from '@superset-ui/core';
|
import { t, logging } from '@superset-ui/core';
|
||||||
import { Charts, Layout, RootState, Slice } from 'src/dashboard/types';
|
import { Charts, Layout, RootState, Slice } from 'src/dashboard/types';
|
||||||
import { DASHBOARD_ROOT_ID } from 'src/dashboard/util/constants';
|
import { DASHBOARD_ROOT_ID } from 'src/dashboard/util/constants';
|
||||||
import {
|
import {
|
||||||
@@ -46,7 +46,7 @@ export function useFilterScopeTree(
|
|||||||
|
|
||||||
const sliceEntities = useSelector<RootState, Slice>(state => {
|
const sliceEntities = useSelector<RootState, Slice>(state => {
|
||||||
if (!state.sliceEntities) {
|
if (!state.sliceEntities) {
|
||||||
console.warn('sliceEntities not found in state');
|
logging.warn('sliceEntities not found in state');
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
return state.sliceEntities.slices || {};
|
return state.sliceEntities.slices || {};
|
||||||
|
|||||||
@@ -30,6 +30,7 @@ import {
|
|||||||
ExtraFormDataOverride,
|
ExtraFormDataOverride,
|
||||||
TimeGranularity,
|
TimeGranularity,
|
||||||
ExtraFormDataAppend,
|
ExtraFormDataAppend,
|
||||||
|
logging,
|
||||||
} from '@superset-ui/core';
|
} from '@superset-ui/core';
|
||||||
import { LayoutItem } from 'src/dashboard/types';
|
import { LayoutItem } from 'src/dashboard/types';
|
||||||
import extractUrlParams from 'src/dashboard/util/extractUrlParams';
|
import extractUrlParams from 'src/dashboard/util/extractUrlParams';
|
||||||
@@ -242,7 +243,7 @@ export function getFilterScope(
|
|||||||
if (target) {
|
if (target) {
|
||||||
targets.push(target);
|
targets.push(target);
|
||||||
} else {
|
} else {
|
||||||
console.warn(`Invalid filter scope key format: ${scopeKey}`);
|
logging.warn(`Invalid filter scope key format: ${scopeKey}`);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ import {
|
|||||||
JsonValue,
|
JsonValue,
|
||||||
QueryFormData,
|
QueryFormData,
|
||||||
usePrevious,
|
usePrevious,
|
||||||
|
logging,
|
||||||
} from '@superset-ui/core';
|
} from '@superset-ui/core';
|
||||||
import { ErrorBoundary } from 'src/components';
|
import { ErrorBoundary } from 'src/components';
|
||||||
import { ExploreActions } from 'src/explore/actions/exploreActions';
|
import { ExploreActions } from 'src/explore/actions/exploreActions';
|
||||||
@@ -107,8 +108,7 @@ export default function Control(props: ControlProps) {
|
|||||||
? controlMap[type as keyof typeof controlMap]
|
? controlMap[type as keyof typeof controlMap]
|
||||||
: type;
|
: type;
|
||||||
if (!ControlComponent) {
|
if (!ControlComponent) {
|
||||||
// eslint-disable-next-line no-console
|
logging.warn(`Unknown controlType: ${type}`);
|
||||||
console.warn(`Unknown controlType: ${type}`);
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -16,7 +16,7 @@
|
|||||||
* specific language governing permissions and limitations
|
* specific language governing permissions and limitations
|
||||||
* under the License.
|
* under the License.
|
||||||
*/
|
*/
|
||||||
import { css, JsonValue, styled, t } from '@superset-ui/core';
|
import { css, JsonValue, styled, t, logging } from '@superset-ui/core';
|
||||||
// eslint-disable-next-line no-restricted-imports
|
// eslint-disable-next-line no-restricted-imports
|
||||||
import { Button } from '@superset-ui/core/components/Button';
|
import { Button } from '@superset-ui/core/components/Button';
|
||||||
import { Form } from '@superset-ui/core/components/Form';
|
import { Form } from '@superset-ui/core/components/Form';
|
||||||
@@ -331,7 +331,7 @@ export const LayerConfigsPopoverContent: FC<
|
|||||||
});
|
});
|
||||||
setGeoStylerData(gsData);
|
setGeoStylerData(gsData);
|
||||||
} catch {
|
} catch {
|
||||||
console.warn('Could not read geostyler data');
|
logging.warn('Could not read geostyler data');
|
||||||
setGeoStylerData(undefined);
|
setGeoStylerData(undefined);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
* under the License.
|
* under the License.
|
||||||
*/
|
*/
|
||||||
import { ControlHeader } from '@superset-ui/chart-controls';
|
import { ControlHeader } from '@superset-ui/chart-controls';
|
||||||
import { css, styled, t } from '@superset-ui/core';
|
import { css, styled, t, logging } from '@superset-ui/core';
|
||||||
import { Form } from '@superset-ui/core/components';
|
import { Form } from '@superset-ui/core/components';
|
||||||
import { Tag } from 'src/components';
|
import { Tag } from 'src/components';
|
||||||
import { FC, useState } from 'react';
|
import { FC, useState } from 'react';
|
||||||
@@ -65,7 +65,7 @@ export const ZoomConfigControl: FC<ZoomConfigsControlProps> = ({
|
|||||||
};
|
};
|
||||||
|
|
||||||
const onBaseWidthChange = (width: number) => {
|
const onBaseWidthChange = (width: number) => {
|
||||||
console.log('now in onbasewidthcahnge');
|
logging.log('now in onbasewidthcahnge');
|
||||||
setBaseWidth(width);
|
setBaseWidth(width);
|
||||||
if (!value) {
|
if (!value) {
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -17,6 +17,8 @@
|
|||||||
* under the License.
|
* under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
import { logging } from '@superset-ui/core';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Interface for table columns dataset
|
* Interface for table columns dataset
|
||||||
*/
|
*/
|
||||||
@@ -42,15 +44,13 @@ export const isITableColumn = (item: any): boolean => {
|
|||||||
'The object provided to isITableColumn does match the interface.';
|
'The object provided to isITableColumn does match the interface.';
|
||||||
if (typeof item?.name !== 'string') {
|
if (typeof item?.name !== 'string') {
|
||||||
match = false;
|
match = false;
|
||||||
// eslint-disable-next-line no-console
|
logging.error(
|
||||||
console.error(
|
|
||||||
`${BASE_ERROR} The property 'name' is required and must be a string`,
|
`${BASE_ERROR} The property 'name' is required and must be a string`,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if (match && typeof item?.type !== 'string') {
|
if (match && typeof item?.type !== 'string') {
|
||||||
match = false;
|
match = false;
|
||||||
// eslint-disable-next-line no-console
|
logging.error(
|
||||||
console.error(
|
|
||||||
`${BASE_ERROR} The property 'type' is required and must be a string`,
|
`${BASE_ERROR} The property 'type' is required and must be a string`,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ import {
|
|||||||
initFeatureFlags,
|
initFeatureFlags,
|
||||||
SupersetClient,
|
SupersetClient,
|
||||||
LanguagePack,
|
LanguagePack,
|
||||||
|
logging,
|
||||||
} from '@superset-ui/core';
|
} from '@superset-ui/core';
|
||||||
import setupClient from './setup/setupClient';
|
import setupClient from './setup/setupClient';
|
||||||
import setupColors from './setup/setupColors';
|
import setupColors from './setup/setupColors';
|
||||||
@@ -58,7 +59,7 @@ setupClient({ appRoot: applicationRoot() });
|
|||||||
configure({ languagePack: json as LanguagePack });
|
configure({ languagePack: json as LanguagePack });
|
||||||
dayjs.locale(lang);
|
dayjs.locale(lang);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.warn(
|
logging.warn(
|
||||||
'Failed to fetch language pack, falling back to default.',
|
'Failed to fetch language pack, falling back to default.',
|
||||||
err,
|
err,
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ import {
|
|||||||
Theme,
|
Theme,
|
||||||
ThemeMode,
|
ThemeMode,
|
||||||
themeObject as supersetThemeObject,
|
themeObject as supersetThemeObject,
|
||||||
|
logging,
|
||||||
} from '@superset-ui/core';
|
} from '@superset-ui/core';
|
||||||
import {
|
import {
|
||||||
getAntdConfig,
|
getAntdConfig,
|
||||||
@@ -56,7 +57,7 @@ export class LocalStorageAdapter implements ThemeStorage {
|
|||||||
try {
|
try {
|
||||||
return localStorage.getItem(key);
|
return localStorage.getItem(key);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.warn('Failed to read from localStorage:', error);
|
logging.warn('Failed to read from localStorage:', error);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -65,7 +66,7 @@ export class LocalStorageAdapter implements ThemeStorage {
|
|||||||
try {
|
try {
|
||||||
localStorage.setItem(key, value);
|
localStorage.setItem(key, value);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.warn('Failed to write to localStorage:', error);
|
logging.warn('Failed to write to localStorage:', error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -73,7 +74,7 @@ export class LocalStorageAdapter implements ThemeStorage {
|
|||||||
try {
|
try {
|
||||||
localStorage.removeItem(key);
|
localStorage.removeItem(key);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.warn('Failed to remove from localStorage:', error);
|
logging.warn('Failed to remove from localStorage:', error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -320,7 +321,7 @@ export class ThemeController {
|
|||||||
|
|
||||||
const theme: AnyThemeConfig | null = this.getThemeForMode(mode);
|
const theme: AnyThemeConfig | null = this.getThemeForMode(mode);
|
||||||
if (!theme) {
|
if (!theme) {
|
||||||
console.warn(`Theme for mode ${mode} not found, falling back to default`);
|
logging.warn(`Theme for mode ${mode} not found, falling back to default`);
|
||||||
this.fallbackToDefaultMode();
|
this.fallbackToDefaultMode();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -484,7 +485,7 @@ export class ThemeController {
|
|||||||
if (newTheme) this.updateTheme(newTheme);
|
if (newTheme) this.updateTheme(newTheme);
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Failed to handle system theme change:', error);
|
logging.error('Failed to handle system theme change:', error);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -505,7 +506,7 @@ export class ThemeController {
|
|||||||
this.persistMode();
|
this.persistMode();
|
||||||
this.notifyListeners();
|
this.notifyListeners();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Failed to update theme:', error);
|
logging.error('Failed to update theme:', error);
|
||||||
this.fallbackToDefaultMode();
|
this.fallbackToDefaultMode();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -557,7 +558,7 @@ export class ThemeController {
|
|||||||
this.mediaQuery = window.matchMedia(MEDIA_QUERY_DARK_SCHEME);
|
this.mediaQuery = window.matchMedia(MEDIA_QUERY_DARK_SCHEME);
|
||||||
this.mediaQuery.addEventListener('change', this.handleSystemThemeChange);
|
this.mediaQuery.addEventListener('change', this.handleSystemThemeChange);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.warn('Failed to initialize media query listener:', error);
|
logging.warn('Failed to initialize media query listener:', error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -703,7 +704,7 @@ export class ThemeController {
|
|||||||
|
|
||||||
return null;
|
return null;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.warn('Failed to load saved theme mode:', error);
|
logging.warn('Failed to load saved theme mode:', error);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -777,7 +778,7 @@ export class ThemeController {
|
|||||||
const normalizedConfig = normalizeThemeConfig(theme);
|
const normalizedConfig = normalizeThemeConfig(theme);
|
||||||
this.globalTheme.setConfig(normalizedConfig);
|
this.globalTheme.setConfig(normalizedConfig);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Failed to apply theme:', error);
|
logging.error('Failed to apply theme:', error);
|
||||||
this.fallbackToDefaultMode();
|
this.fallbackToDefaultMode();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -789,7 +790,7 @@ export class ThemeController {
|
|||||||
try {
|
try {
|
||||||
this.storage.setItem(this.modeStorageKey, this.currentMode);
|
this.storage.setItem(this.modeStorageKey, this.currentMode);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.warn('Failed to persist theme mode:', error);
|
logging.warn('Failed to persist theme mode:', error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -801,7 +802,7 @@ export class ThemeController {
|
|||||||
try {
|
try {
|
||||||
callback(this.globalTheme);
|
callback(this.globalTheme);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error in theme change callback:', error);
|
logging.error('Error in theme change callback:', error);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -816,7 +817,7 @@ export class ThemeController {
|
|||||||
? ThemeMode.DARK
|
? ThemeMode.DARK
|
||||||
: ThemeMode.DEFAULT;
|
: ThemeMode.DEFAULT;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.warn('Failed to detect system theme preference:', error);
|
logging.warn('Failed to detect system theme preference:', error);
|
||||||
return ThemeMode.DEFAULT;
|
return ThemeMode.DEFAULT;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ import { SyntheticEvent } from 'react';
|
|||||||
import domToImage from 'dom-to-image-more';
|
import domToImage from 'dom-to-image-more';
|
||||||
import { kebabCase } from 'lodash';
|
import { kebabCase } from 'lodash';
|
||||||
// eslint-disable-next-line no-restricted-imports
|
// eslint-disable-next-line no-restricted-imports
|
||||||
import { SupersetTheme, t } from '@superset-ui/core';
|
import { SupersetTheme, t, logging } from '@superset-ui/core';
|
||||||
import { addWarningToast } from 'src/components/MessageToasts/actions';
|
import { addWarningToast } from 'src/components/MessageToasts/actions';
|
||||||
|
|
||||||
const IMAGE_DOWNLOAD_QUALITY = 0.95;
|
const IMAGE_DOWNLOAD_QUALITY = 0.95;
|
||||||
@@ -282,7 +282,7 @@ export default function downloadAsImageOptimized(
|
|||||||
link.href = dataUrl;
|
link.href = dataUrl;
|
||||||
link.click();
|
link.click();
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Creating image failed', error);
|
logging.error('Creating image failed', error);
|
||||||
addWarningToast(
|
addWarningToast(
|
||||||
t('Image download failed, please refresh and try again.'),
|
t('Image download failed, please refresh and try again.'),
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -16,7 +16,7 @@
|
|||||||
* specific language governing permissions and limitations
|
* specific language governing permissions and limitations
|
||||||
* under the License.
|
* under the License.
|
||||||
*/
|
*/
|
||||||
import { JsonObject } from '@superset-ui/core';
|
import { JsonObject, logging } from '@superset-ui/core';
|
||||||
|
|
||||||
type TestWithIdType<T> = T extends string ? string : { 'data-test': string };
|
type TestWithIdType<T> = T extends string ? string : { 'data-test': string };
|
||||||
|
|
||||||
@@ -37,7 +37,7 @@ export const testWithId =
|
|||||||
return (resultIdOnly ? id : { 'data-test': id }) as TestWithIdType<T>;
|
return (resultIdOnly ? id : { 'data-test': id }) as TestWithIdType<T>;
|
||||||
}
|
}
|
||||||
if (!id && !prefix) {
|
if (!id && !prefix) {
|
||||||
console.warn('testWithId function has missed "prefix" and "id" params');
|
logging.warn('testWithId function has missed "prefix" and "id" params');
|
||||||
return (resultIdOnly ? '' : { 'data-test': '' }) as TestWithIdType<T>;
|
return (resultIdOnly ? '' : { 'data-test': '' }) as TestWithIdType<T>;
|
||||||
}
|
}
|
||||||
const newId = `${prefix}__${id}`;
|
const newId = `${prefix}__${id}`;
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ import {
|
|||||||
t,
|
t,
|
||||||
JsonObject,
|
JsonObject,
|
||||||
getClientErrorObject,
|
getClientErrorObject,
|
||||||
|
logging,
|
||||||
} from '@superset-ui/core';
|
} from '@superset-ui/core';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
@@ -835,7 +836,7 @@ export function useDatabaseValidation() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
console.error('Unexpected error during validation:', error);
|
logging.error('Unexpected error during validation:', error);
|
||||||
setIsValidating(false);
|
setIsValidating(false);
|
||||||
setHasValidated(true);
|
setHasValidated(true);
|
||||||
return {};
|
return {};
|
||||||
|
|||||||
Reference in New Issue
Block a user