chore: Expose widget configuration to define properties that can set … (#16573)
This commit is contained in:
parent
0970389143
commit
9bc5a5e076
|
|
@ -48,6 +48,7 @@ class WidgetFactory {
|
||||||
WidgetType,
|
WidgetType,
|
||||||
readonly PropertyPaneConfig[]
|
readonly PropertyPaneConfig[]
|
||||||
> = new Map();
|
> = new Map();
|
||||||
|
static loadingProperties: Map<WidgetType, Array<RegExp>> = new Map();
|
||||||
|
|
||||||
static widgetConfigMap: Map<
|
static widgetConfigMap: Map<
|
||||||
WidgetType,
|
WidgetType,
|
||||||
|
|
@ -64,6 +65,7 @@ class WidgetFactory {
|
||||||
propertyPaneContentConfig?: PropertyPaneConfig[],
|
propertyPaneContentConfig?: PropertyPaneConfig[],
|
||||||
propertyPaneStyleConfig?: PropertyPaneConfig[],
|
propertyPaneStyleConfig?: PropertyPaneConfig[],
|
||||||
features?: WidgetFeatures,
|
features?: WidgetFeatures,
|
||||||
|
loadingProperties?: Array<RegExp>,
|
||||||
) {
|
) {
|
||||||
if (!this.widgetTypes[widgetType]) {
|
if (!this.widgetTypes[widgetType]) {
|
||||||
this.widgetTypes[widgetType] = widgetType;
|
this.widgetTypes[widgetType] = widgetType;
|
||||||
|
|
@ -71,6 +73,8 @@ class WidgetFactory {
|
||||||
this.derivedPropertiesMap.set(widgetType, derivedPropertiesMap);
|
this.derivedPropertiesMap.set(widgetType, derivedPropertiesMap);
|
||||||
this.defaultPropertiesMap.set(widgetType, defaultPropertiesMap);
|
this.defaultPropertiesMap.set(widgetType, defaultPropertiesMap);
|
||||||
this.metaPropertiesMap.set(widgetType, metaPropertiesMap);
|
this.metaPropertiesMap.set(widgetType, metaPropertiesMap);
|
||||||
|
loadingProperties &&
|
||||||
|
this.loadingProperties.set(widgetType, loadingProperties);
|
||||||
|
|
||||||
if (propertyPaneConfig) {
|
if (propertyPaneConfig) {
|
||||||
const enhancedPropertyPaneConfig = enhancePropertyPaneConfig(
|
const enhancedPropertyPaneConfig = enhancePropertyPaneConfig(
|
||||||
|
|
@ -244,6 +248,10 @@ class WidgetFactory {
|
||||||
});
|
});
|
||||||
return typeConfigMap;
|
return typeConfigMap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static getLoadingProperties(type: WidgetType): Array<RegExp> | undefined {
|
||||||
|
return this.loadingProperties.get(type);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export type WidgetTypeConfigMap = Record<
|
export type WidgetTypeConfigMap = Record<
|
||||||
|
|
|
||||||
|
|
@ -7,9 +7,10 @@ import {
|
||||||
} from "entities/DataTree/dataTreeFactory";
|
} from "entities/DataTree/dataTreeFactory";
|
||||||
import {
|
import {
|
||||||
findLoadingEntities,
|
findLoadingEntities,
|
||||||
getEntityDependants,
|
getEntityDependantPaths,
|
||||||
groupAndFilterDependantsMap,
|
groupAndFilterDependantsMap,
|
||||||
} from "utils/WidgetLoadingStateUtils";
|
} from "utils/WidgetLoadingStateUtils";
|
||||||
|
import WidgetFactory from "./WidgetFactory";
|
||||||
|
|
||||||
const JS_object_tree: DataTreeJSAction = {
|
const JS_object_tree: DataTreeJSAction = {
|
||||||
pluginType: PluginType.JS,
|
pluginType: PluginType.JS,
|
||||||
|
|
@ -72,14 +73,64 @@ const Query_tree: DataTreeAction = {
|
||||||
isLoading: false,
|
isLoading: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const Api_tree: DataTreeAction = {
|
||||||
|
data: {},
|
||||||
|
actionId: "",
|
||||||
|
config: {},
|
||||||
|
pluginType: PluginType.API,
|
||||||
|
pluginId: "",
|
||||||
|
name: "",
|
||||||
|
run: {},
|
||||||
|
clear: {},
|
||||||
|
dynamicBindingPathList: [],
|
||||||
|
bindingPaths: {},
|
||||||
|
ENTITY_TYPE: ENTITY_TYPE.ACTION,
|
||||||
|
dependencyMap: {},
|
||||||
|
logBlackList: {},
|
||||||
|
datasourceUrl: "",
|
||||||
|
responseMeta: {
|
||||||
|
isExecutionSuccess: true,
|
||||||
|
},
|
||||||
|
isLoading: false,
|
||||||
|
reactivePaths: {},
|
||||||
|
};
|
||||||
|
|
||||||
|
const Table_tree: DataTreeWidget = {
|
||||||
|
ENTITY_TYPE: ENTITY_TYPE.WIDGET,
|
||||||
|
bindingPaths: {},
|
||||||
|
triggerPaths: {},
|
||||||
|
validationPaths: {},
|
||||||
|
logBlackList: {},
|
||||||
|
propertyOverrideDependency: {},
|
||||||
|
overridingPropertyPaths: {},
|
||||||
|
privateWidgets: {},
|
||||||
|
widgetId: "",
|
||||||
|
type: "TABLE_WIDGET",
|
||||||
|
widgetName: "",
|
||||||
|
renderMode: "CANVAS",
|
||||||
|
version: 0,
|
||||||
|
parentColumnSpace: 0,
|
||||||
|
parentRowSpace: 0,
|
||||||
|
leftColumn: 0,
|
||||||
|
rightColumn: 0,
|
||||||
|
topRow: 0,
|
||||||
|
bottomRow: 0,
|
||||||
|
isLoading: false,
|
||||||
|
animateLoading: true,
|
||||||
|
reactivePaths: {},
|
||||||
|
meta: {},
|
||||||
|
};
|
||||||
|
|
||||||
const baseDataTree = {
|
const baseDataTree = {
|
||||||
JS_file: { ...JS_object_tree, name: "JS_file" },
|
JS_file: { ...JS_object_tree, name: "JS_file" },
|
||||||
Select1: { ...Select_tree, name: "Select1" },
|
Select1: { ...Select_tree, name: "Select1" },
|
||||||
Select2: { ...Select_tree, name: "Select2" },
|
Select2: { ...Select_tree, name: "Select2" },
|
||||||
Select3: { ...Select_tree, name: "Select3" },
|
Select3: { ...Select_tree, name: "Select3" },
|
||||||
|
Table1: { ...Table_tree, name: "Table1" },
|
||||||
Query1: { ...Query_tree, name: "Query1" },
|
Query1: { ...Query_tree, name: "Query1" },
|
||||||
Query2: { ...Query_tree, name: "Query2" },
|
Query2: { ...Query_tree, name: "Query2" },
|
||||||
Query3: { ...Query_tree, name: "Query3" },
|
Query3: { ...Query_tree, name: "Query3" },
|
||||||
|
Api1: { ...Api_tree, name: "Api1" },
|
||||||
};
|
};
|
||||||
|
|
||||||
describe("Widget loading state utils", () => {
|
describe("Widget loading state utils", () => {
|
||||||
|
|
@ -120,6 +171,22 @@ describe("Widget loading state utils", () => {
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
|
||||||
|
beforeAll(() => {
|
||||||
|
// mock WidgetFactory.getLoadingProperties
|
||||||
|
const loadingPropertiesMap = new Map<string, RegExp[]>();
|
||||||
|
loadingPropertiesMap.set("TABLE_WIDGET", [/.tableData$/]);
|
||||||
|
|
||||||
|
jest
|
||||||
|
.spyOn(WidgetFactory, "getLoadingProperties")
|
||||||
|
.mockImplementation((widgetType) =>
|
||||||
|
loadingPropertiesMap.get(widgetType),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
afterAll(() => {
|
||||||
|
jest.restoreAllMocks();
|
||||||
|
});
|
||||||
|
|
||||||
// Select1.options -> JS_file.func1 -> Query1.data
|
// Select1.options -> JS_file.func1 -> Query1.data
|
||||||
it("handles linear dependencies", () => {
|
it("handles linear dependencies", () => {
|
||||||
const loadingEntites = findLoadingEntities(
|
const loadingEntites = findLoadingEntities(
|
||||||
|
|
@ -251,6 +318,20 @@ describe("Widget loading state utils", () => {
|
||||||
});
|
});
|
||||||
expect(loadingEntites).toStrictEqual(new Set(["Select2"]));
|
expect(loadingEntites).toStrictEqual(new Set(["Select2"]));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("includes loading properties", () => {
|
||||||
|
const loadingEntites = findLoadingEntities(["Api1"], baseDataTree, {
|
||||||
|
"Api1.data": ["Table1.tableData"],
|
||||||
|
});
|
||||||
|
expect(loadingEntites).toStrictEqual(new Set(["Table1"]));
|
||||||
|
});
|
||||||
|
|
||||||
|
it("ignores non-loading properties", () => {
|
||||||
|
const loadingEntites = findLoadingEntities(["Api1"], baseDataTree, {
|
||||||
|
"Api1.run": ["Table1.primaryColumns.action.onClick"],
|
||||||
|
});
|
||||||
|
expect(loadingEntites).toStrictEqual(new Set());
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("groupAndFilterDependantsMap", () => {
|
describe("groupAndFilterDependantsMap", () => {
|
||||||
|
|
@ -331,10 +412,10 @@ describe("Widget loading state utils", () => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe("getEntityDependants", () => {
|
describe("getEntityDependantPaths", () => {
|
||||||
// Select1.options -> JS_file.func1 -> Query1.data
|
// Select1.options -> JS_file.func1 -> Query1.data
|
||||||
it("handles simple dependency", () => {
|
it("handles simple dependency", () => {
|
||||||
const dependants = getEntityDependants(
|
const dependants = getEntityDependantPaths(
|
||||||
["Query1"],
|
["Query1"],
|
||||||
{
|
{
|
||||||
Query1: {
|
Query1: {
|
||||||
|
|
@ -346,16 +427,15 @@ describe("Widget loading state utils", () => {
|
||||||
},
|
},
|
||||||
new Set<string>(),
|
new Set<string>(),
|
||||||
);
|
);
|
||||||
expect(dependants).toStrictEqual({
|
expect(dependants).toStrictEqual(
|
||||||
names: new Set(["JS_file", "Select1"]),
|
new Set(["JS_file.func1", "Select1.options"]),
|
||||||
fullPaths: new Set(["JS_file.func1", "Select1.options"]),
|
);
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// Select1.options -> JS_file.func1 -> Query1.data
|
// Select1.options -> JS_file.func1 -> Query1.data
|
||||||
// Select2.options -> JS_file.func2 -> Query1.data
|
// Select2.options -> JS_file.func2 -> Query1.data
|
||||||
it("handles multiple dependencies", () => {
|
it("handles multiple dependencies", () => {
|
||||||
const dependants = getEntityDependants(
|
const dependants = getEntityDependantPaths(
|
||||||
["Query1"],
|
["Query1"],
|
||||||
{
|
{
|
||||||
Query1: {
|
Query1: {
|
||||||
|
|
@ -368,19 +448,18 @@ describe("Widget loading state utils", () => {
|
||||||
},
|
},
|
||||||
new Set<string>(),
|
new Set<string>(),
|
||||||
);
|
);
|
||||||
expect(dependants).toStrictEqual({
|
expect(dependants).toStrictEqual(
|
||||||
names: new Set(["JS_file", "Select1", "Select2"]),
|
new Set([
|
||||||
fullPaths: new Set([
|
|
||||||
"JS_file.func1",
|
"JS_file.func1",
|
||||||
"Select1.options",
|
"Select1.options",
|
||||||
"JS_file.func2",
|
"JS_file.func2",
|
||||||
"Select2.options",
|
"Select2.options",
|
||||||
]),
|
]),
|
||||||
});
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("handles specific entity paths", () => {
|
it("handles specific entity paths", () => {
|
||||||
const dependants = getEntityDependants(
|
const dependants = getEntityDependantPaths(
|
||||||
["JS_file.func2"], // specific path
|
["JS_file.func2"], // specific path
|
||||||
{
|
{
|
||||||
Query1: {
|
Query1: {
|
||||||
|
|
@ -396,15 +475,12 @@ describe("Widget loading state utils", () => {
|
||||||
},
|
},
|
||||||
new Set<string>(),
|
new Set<string>(),
|
||||||
);
|
);
|
||||||
expect(dependants).toStrictEqual({
|
expect(dependants).toStrictEqual(new Set(["Select2.options"]));
|
||||||
names: new Set(["Select2"]),
|
|
||||||
fullPaths: new Set(["Select2.options"]),
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// Select1.options -> JS_file.func1 -> JS_file.internalFunc -> Query1.data
|
// Select1.options -> JS_file.func1 -> JS_file.internalFunc -> Query1.data
|
||||||
it("handles JS self-dependencies", () => {
|
it("handles JS self-dependencies", () => {
|
||||||
const dependants = getEntityDependants(
|
const dependants = getEntityDependantPaths(
|
||||||
["Query1"],
|
["Query1"],
|
||||||
{
|
{
|
||||||
Query1: {
|
Query1: {
|
||||||
|
|
@ -417,19 +493,14 @@ describe("Widget loading state utils", () => {
|
||||||
},
|
},
|
||||||
new Set<string>(),
|
new Set<string>(),
|
||||||
);
|
);
|
||||||
expect(dependants).toStrictEqual({
|
expect(dependants).toStrictEqual(
|
||||||
names: new Set(["JS_file", "Select1"]),
|
new Set(["JS_file.internalFunc", "JS_file.func1", "Select1.options"]),
|
||||||
fullPaths: new Set([
|
);
|
||||||
"JS_file.internalFunc",
|
|
||||||
"JS_file.func1",
|
|
||||||
"Select1.options",
|
|
||||||
]),
|
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
// Select1.options -> JS_file.func -> JS_file.internalFunc1 -> JS_file.internalFunc2 -> Query1.data
|
// Select1.options -> JS_file.func -> JS_file.internalFunc1 -> JS_file.internalFunc2 -> Query1.data
|
||||||
it("handles nested JS self-dependencies", () => {
|
it("handles nested JS self-dependencies", () => {
|
||||||
const dependants = getEntityDependants(
|
const dependants = getEntityDependantPaths(
|
||||||
["Query1"],
|
["Query1"],
|
||||||
{
|
{
|
||||||
Query1: {
|
Query1: {
|
||||||
|
|
@ -443,15 +514,14 @@ describe("Widget loading state utils", () => {
|
||||||
},
|
},
|
||||||
new Set<string>(),
|
new Set<string>(),
|
||||||
);
|
);
|
||||||
expect(dependants).toStrictEqual({
|
expect(dependants).toStrictEqual(
|
||||||
names: new Set(["JS_file", "Select1"]),
|
new Set([
|
||||||
fullPaths: new Set([
|
|
||||||
"JS_file.internalFunc1",
|
"JS_file.internalFunc1",
|
||||||
"JS_file.internalFunc2",
|
"JS_file.internalFunc2",
|
||||||
"JS_file.func",
|
"JS_file.func",
|
||||||
"Select1.options",
|
"Select1.options",
|
||||||
]),
|
]),
|
||||||
});
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
/* Select1.options -> JS.func1 -> Query1.data,
|
/* Select1.options -> JS.func1 -> Query1.data,
|
||||||
|
|
@ -462,7 +532,7 @@ describe("Widget loading state utils", () => {
|
||||||
Only Select2 should be listed, not Select1.
|
Only Select2 should be listed, not Select1.
|
||||||
*/
|
*/
|
||||||
it("handles selective dependencies in same JS file", () => {
|
it("handles selective dependencies in same JS file", () => {
|
||||||
const dependants = getEntityDependants(
|
const dependants = getEntityDependantPaths(
|
||||||
["Query2"],
|
["Query2"],
|
||||||
{
|
{
|
||||||
Query1: {
|
Query1: {
|
||||||
|
|
@ -478,10 +548,9 @@ describe("Widget loading state utils", () => {
|
||||||
},
|
},
|
||||||
new Set<string>(),
|
new Set<string>(),
|
||||||
);
|
);
|
||||||
expect(dependants).toStrictEqual({
|
expect(dependants).toStrictEqual(
|
||||||
names: new Set(["JS_file", "Select2"]),
|
new Set(["JS_file.func2", "Select2.options"]),
|
||||||
fullPaths: new Set(["JS_file.func2", "Select2.options"]),
|
);
|
||||||
});
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,8 @@
|
||||||
import { DataTree } from "entities/DataTree/dataTreeFactory";
|
import { DataTree } from "entities/DataTree/dataTreeFactory";
|
||||||
import { get, set } from "lodash";
|
import { get, set } from "lodash";
|
||||||
import { isJSObject } from "workers/evaluationUtils";
|
import { isJSObject, isWidget } from "workers/evaluationUtils";
|
||||||
import { DependencyMap } from "./DynamicBindingUtils";
|
import { DependencyMap } from "./DynamicBindingUtils";
|
||||||
|
import WidgetFactory from "./WidgetFactory";
|
||||||
|
|
||||||
type GroupedDependencyMap = Record<string, DependencyMap>;
|
type GroupedDependencyMap = Record<string, DependencyMap>;
|
||||||
|
|
||||||
|
|
@ -57,13 +58,13 @@ export const groupAndFilterDependantsMap = (
|
||||||
return entitiesDepMap;
|
return entitiesDepMap;
|
||||||
};
|
};
|
||||||
|
|
||||||
// get entities that depend on a given list of entites
|
// get entity paths that depend on a given list of entites
|
||||||
// e.g. widgets that depend on a list of actions
|
// e.g. widget paths that depend on a list of actions
|
||||||
export const getEntityDependants = (
|
export const getEntityDependantPaths = (
|
||||||
fullEntityPaths: string[],
|
fullEntityPaths: string[],
|
||||||
allEntitiesDependantsmap: GroupedDependencyMap,
|
allEntitiesDependantsmap: GroupedDependencyMap,
|
||||||
visitedPaths: Set<string>,
|
visitedPaths: Set<string>,
|
||||||
): { names: Set<string>; fullPaths: Set<string> } => {
|
): Set<string> => {
|
||||||
const dependantEntityNames = new Set<string>();
|
const dependantEntityNames = new Set<string>();
|
||||||
const dependantEntityFullPaths = new Set<string>();
|
const dependantEntityFullPaths = new Set<string>();
|
||||||
|
|
||||||
|
|
@ -97,15 +98,13 @@ export const getEntityDependants = (
|
||||||
dependantEntityNames.add(dependantEntityName);
|
dependantEntityNames.add(dependantEntityName);
|
||||||
dependantEntityFullPaths.add(dependantPath);
|
dependantEntityFullPaths.add(dependantPath);
|
||||||
|
|
||||||
const childDependants = getEntityDependants(
|
const childDependants = getEntityDependantPaths(
|
||||||
[dependantPath],
|
[dependantPath],
|
||||||
allEntitiesDependantsmap,
|
allEntitiesDependantsmap,
|
||||||
visitedPaths,
|
visitedPaths,
|
||||||
);
|
);
|
||||||
childDependants.names.forEach((childDependantName) => {
|
|
||||||
dependantEntityNames.add(childDependantName);
|
childDependants.forEach((childDependantPath) => {
|
||||||
});
|
|
||||||
childDependants.fullPaths.forEach((childDependantPath) => {
|
|
||||||
dependantEntityFullPaths.add(childDependantPath);
|
dependantEntityFullPaths.add(childDependantPath);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
@ -113,11 +112,11 @@ export const getEntityDependants = (
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
return { names: dependantEntityNames, fullPaths: dependantEntityFullPaths };
|
return dependantEntityFullPaths;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const findLoadingEntities = (
|
export const findLoadingEntities = (
|
||||||
isLoadingActions: string[],
|
loadingActions: string[],
|
||||||
dataTree: DataTree,
|
dataTree: DataTree,
|
||||||
inverseMap: DependencyMap,
|
inverseMap: DependencyMap,
|
||||||
): Set<string> => {
|
): Set<string> => {
|
||||||
|
|
@ -125,15 +124,33 @@ export const findLoadingEntities = (
|
||||||
inverseMap,
|
inverseMap,
|
||||||
dataTree,
|
dataTree,
|
||||||
);
|
);
|
||||||
const loadingEntitiesDetails = getEntityDependants(
|
const loadingEntityPaths = getEntityDependantPaths(
|
||||||
isLoadingActions,
|
loadingActions,
|
||||||
entitiesDependantsMap,
|
entitiesDependantsMap,
|
||||||
new Set<string>(),
|
new Set<string>(),
|
||||||
);
|
);
|
||||||
|
|
||||||
// check animateLoading is active on current widgets and set
|
// check animateLoading is active on current widgets and set
|
||||||
const filteredLoadingEntityNames = new Set<string>();
|
const filteredLoadingEntityNames = new Set<string>();
|
||||||
loadingEntitiesDetails.names.forEach((entityName) => {
|
|
||||||
|
loadingEntityPaths.forEach((entityPath) => {
|
||||||
|
const entityPathArray = entityPath.split(".");
|
||||||
|
const entityName = entityPathArray[0];
|
||||||
|
const widget = get(dataTree, [entityName]);
|
||||||
|
if (isWidget(widget)) {
|
||||||
|
const loadingProperties = WidgetFactory.getLoadingProperties(widget.type);
|
||||||
|
|
||||||
|
// check if propertyPath is listed in widgetConfig
|
||||||
|
if (
|
||||||
|
entityPathArray.length > 1 &&
|
||||||
|
loadingProperties &&
|
||||||
|
!loadingProperties.some((propRegExp) => propRegExp.test(entityPath))
|
||||||
|
) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// check animateLoading is active on current widgets and set
|
||||||
get(dataTree, [entityName, "animateLoading"]) === true &&
|
get(dataTree, [entityName, "animateLoading"]) === true &&
|
||||||
filteredLoadingEntityNames.add(entityName);
|
filteredLoadingEntityNames.add(entityName);
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -44,6 +44,7 @@ export const registerWidget = (Widget: any, config: WidgetConfiguration) => {
|
||||||
config.properties.contentConfig,
|
config.properties.contentConfig,
|
||||||
config.properties.styleConfig,
|
config.properties.styleConfig,
|
||||||
config.features,
|
config.features,
|
||||||
|
config.properties.loadingProperties,
|
||||||
);
|
);
|
||||||
configureWidget(config);
|
configureWidget(config);
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -77,6 +77,20 @@ abstract class BaseWidget<
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* getLoadingProperties returns a list of regexp's used to specify bindingPaths,
|
||||||
|
* which can set the isLoading prop of the widget.
|
||||||
|
* When:
|
||||||
|
* 1. the path is bound to an action (API/Query)
|
||||||
|
* 2. the action is currently in-progress
|
||||||
|
*
|
||||||
|
* if undefined, all paths can set the isLoading state
|
||||||
|
* if empty array, no paths can set the isLoading state
|
||||||
|
*/
|
||||||
|
static getLoadingProperties(): Array<RegExp> | undefined {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Widget abstraction to register the widget type
|
* Widget abstraction to register the widget type
|
||||||
* ```javascript
|
* ```javascript
|
||||||
|
|
|
||||||
|
|
@ -229,6 +229,7 @@ export const CONFIG = {
|
||||||
config: Widget.getPropertyPaneConfig(),
|
config: Widget.getPropertyPaneConfig(),
|
||||||
contentConfig: Widget.getPropertyPaneContentConfig(),
|
contentConfig: Widget.getPropertyPaneContentConfig(),
|
||||||
styleConfig: Widget.getPropertyPaneStyleConfig(),
|
styleConfig: Widget.getPropertyPaneStyleConfig(),
|
||||||
|
loadingProperties: Widget.getLoadingProperties(),
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -140,6 +140,10 @@ class TableWidgetV2 extends BaseWidget<TableWidgetProps, WidgetState> {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static getLoadingProperties(): Array<RegExp> | undefined {
|
||||||
|
return [/\.tableData$/];
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Function to get the table columns with appropriate render functions
|
* Function to get the table columns with appropriate render functions
|
||||||
* based on columnType
|
* based on columnType
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,7 @@ export interface WidgetConfiguration {
|
||||||
default: Record<string, string>;
|
default: Record<string, string>;
|
||||||
meta: Record<string, any>;
|
meta: Record<string, any>;
|
||||||
derived: DerivedPropertiesMap;
|
derived: DerivedPropertiesMap;
|
||||||
|
loadingProperties?: Array<RegExp>;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user