@openg2p/registry-widgets 1.1.2-dev.0 → 1.1.2-dev.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/hooks/useBaseWidget.d.ts.map +1 -1
- package/dist/hooks/useGeoWidgetCascade.d.ts.map +1 -1
- package/dist/index.d.ts +30 -2
- package/dist/index.esm.js +503 -304
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +511 -303
- package/dist/index.js.map +1 -1
- package/dist/utils/dataSource.d.ts.map +1 -1
- package/dist/utils/geoHierarchy.d.ts +23 -0
- package/dist/utils/geoHierarchy.d.ts.map +1 -1
- package/dist/utils/pathUtils.d.ts +5 -0
- package/dist/utils/pathUtils.d.ts.map +1 -1
- package/dist/widgets/TableWidget.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -174,15 +174,33 @@ const parseDataPath = (dataPath) => {
|
|
|
174
174
|
/**
|
|
175
175
|
* Get value from widget state using data path
|
|
176
176
|
*/
|
|
177
|
+
/**
|
|
178
|
+
* Resolve a widget-id reference in Redux values.
|
|
179
|
+
* Supports namespaced ids (e.g. "rv-section-0__region_code" when ref is "region_code").
|
|
180
|
+
*/
|
|
181
|
+
const resolveWidgetIdValue = (values, ref) => {
|
|
182
|
+
if (!ref) {
|
|
183
|
+
return undefined;
|
|
184
|
+
}
|
|
185
|
+
if (ref.includes('.')) {
|
|
186
|
+
return getValueByPath(values, ref);
|
|
187
|
+
}
|
|
188
|
+
if (Object.prototype.hasOwnProperty.call(values, ref)) {
|
|
189
|
+
return values[ref];
|
|
190
|
+
}
|
|
191
|
+
const suffix = `__${ref}`;
|
|
192
|
+
for (const [key, val] of Object.entries(values)) {
|
|
193
|
+
if (key.endsWith(suffix)) {
|
|
194
|
+
return val;
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
return undefined;
|
|
198
|
+
};
|
|
177
199
|
const getWidgetValue = (values, dataPath, widgetId) => {
|
|
178
200
|
if (!dataPath) {
|
|
179
201
|
// Fallback to widget-id if no data path
|
|
180
202
|
return values[widgetId];
|
|
181
203
|
}
|
|
182
|
-
if (widgetId == "user-profile") {
|
|
183
|
-
console.log('values', values);
|
|
184
|
-
console.log('dataPath', dataPath);
|
|
185
|
-
}
|
|
186
204
|
if (typeof dataPath === 'string') {
|
|
187
205
|
return getValueByPath(values, dataPath);
|
|
188
206
|
}
|
|
@@ -1046,24 +1064,11 @@ const getApiDataSource = async (dataSource, allValues, dataSourceRequestHandler,
|
|
|
1046
1064
|
// dependsOn can be either a data path (e.g., "person.address") or a widget-id
|
|
1047
1065
|
let depValue = null;
|
|
1048
1066
|
if (dataSource.dependsOn) {
|
|
1049
|
-
|
|
1050
|
-
|
|
1051
|
-
|
|
1052
|
-
|
|
1053
|
-
depValue = allValues
|
|
1054
|
-
// Smart resolution: If not found at top level, try to find the dependency in the same nested object
|
|
1055
|
-
// by looking for other keys in allValues that might contain the dependency.
|
|
1056
|
-
// We look for objects that contain both the current widget's path (if we can guess it) and the dependency.
|
|
1057
|
-
// But since we don't know the current widget's path here, we search for any object that has this dependency key.
|
|
1058
|
-
if (depValue === null || depValue === undefined || depValue === '') {
|
|
1059
|
-
for (const val of Object.values(allValues)) {
|
|
1060
|
-
if (val && typeof val === 'object' && !Array.isArray(val) && dataSource.dependsOn in val) {
|
|
1061
|
-
depValue = val[dataSource.dependsOn];
|
|
1062
|
-
if (depValue !== null && depValue !== undefined && depValue !== '')
|
|
1063
|
-
break;
|
|
1064
|
-
}
|
|
1065
|
-
}
|
|
1066
|
-
}
|
|
1067
|
+
if (dataSource.dependsOn.includes('.')) {
|
|
1068
|
+
depValue = getValueByPath(allValues, dataSource.dependsOn);
|
|
1069
|
+
}
|
|
1070
|
+
else {
|
|
1071
|
+
depValue = resolveWidgetIdValue(allValues, dataSource.dependsOn);
|
|
1067
1072
|
}
|
|
1068
1073
|
if (depValue === null || depValue === undefined || depValue === '') {
|
|
1069
1074
|
// If dependency is empty, return empty array
|
|
@@ -1932,6 +1937,247 @@ const WidgetProvider = ({ store, dataSourceRequestHandler, schemaData, translate
|
|
|
1932
1937
|
return content;
|
|
1933
1938
|
};
|
|
1934
1939
|
|
|
1940
|
+
/**
|
|
1941
|
+
* Geo Hierarchy Builder
|
|
1942
|
+
* Manages geo hierarchy state and builds hierarchy JSON structure
|
|
1943
|
+
*/
|
|
1944
|
+
function extractLevelValueFromStored(value, geoConfig) {
|
|
1945
|
+
if (!value || typeof value !== 'object' || Array.isArray(value)) {
|
|
1946
|
+
return value;
|
|
1947
|
+
}
|
|
1948
|
+
const hierarchy = value.hierarchy || value.geo_code_hierarchy_json?.hierarchy;
|
|
1949
|
+
if (Array.isArray(hierarchy)) {
|
|
1950
|
+
const levelData = hierarchy.find((l) => l.level === geoConfig.level);
|
|
1951
|
+
if (levelData) {
|
|
1952
|
+
return levelData.level_value_id;
|
|
1953
|
+
}
|
|
1954
|
+
// Level absent from hierarchy (e.g. cleared by upstream cascade) — do not use lowest-level fallback
|
|
1955
|
+
return undefined;
|
|
1956
|
+
}
|
|
1957
|
+
if ('geo_lowest_level_value_id' in value) {
|
|
1958
|
+
return value.geo_lowest_level_value_id;
|
|
1959
|
+
}
|
|
1960
|
+
if ('lowest_level_value_id' in value) {
|
|
1961
|
+
return value.lowest_level_value_id;
|
|
1962
|
+
}
|
|
1963
|
+
if (value.geo_code_hierarchy_json?.lowest_level_value_id) {
|
|
1964
|
+
return value.geo_code_hierarchy_json.lowest_level_value_id;
|
|
1965
|
+
}
|
|
1966
|
+
if (value.geo_code_hierarchy_json?.geo_lowest_level_value_id) {
|
|
1967
|
+
return value.geo_code_hierarchy_json.geo_lowest_level_value_id;
|
|
1968
|
+
}
|
|
1969
|
+
return undefined;
|
|
1970
|
+
}
|
|
1971
|
+
/**
|
|
1972
|
+
* Resolve the display value for a geo level widget.
|
|
1973
|
+
* When widgetId is explicitly set in Redux (including cleared undefined/null), do not
|
|
1974
|
+
* fall back to shared hierarchy dataPath — that stale path was keeping grandchildren visible.
|
|
1975
|
+
*/
|
|
1976
|
+
function resolveGeoWidgetLevelValue(values, widgetId, dataPath, geoConfig) {
|
|
1977
|
+
if (Object.prototype.hasOwnProperty.call(values, widgetId)) {
|
|
1978
|
+
let value = values[widgetId];
|
|
1979
|
+
if (value === undefined || value === null || value === '') {
|
|
1980
|
+
return value;
|
|
1981
|
+
}
|
|
1982
|
+
if (typeof value === 'object' && !Array.isArray(value)) {
|
|
1983
|
+
return extractLevelValueFromStored(value, geoConfig);
|
|
1984
|
+
}
|
|
1985
|
+
return value;
|
|
1986
|
+
}
|
|
1987
|
+
if (!dataPath) {
|
|
1988
|
+
return undefined;
|
|
1989
|
+
}
|
|
1990
|
+
let value = getWidgetValue(values, dataPath, widgetId);
|
|
1991
|
+
if (value !== null && value !== undefined && typeof value === 'object' && !Array.isArray(value)) {
|
|
1992
|
+
value = extractLevelValueFromStored(value, geoConfig);
|
|
1993
|
+
}
|
|
1994
|
+
return value;
|
|
1995
|
+
}
|
|
1996
|
+
/**
|
|
1997
|
+
* Write the in-memory geo hierarchy builder state into Redux at the shared dataPath.
|
|
1998
|
+
*/
|
|
1999
|
+
function applySharedGeoHierarchyToValues(baseValues, groupId, dataPath, widgetId) {
|
|
2000
|
+
const hierarchyJson = geoHierarchyBuilder.buildHierarchyJson(groupId);
|
|
2001
|
+
if (!dataPath || typeof dataPath !== 'string') {
|
|
2002
|
+
return baseValues;
|
|
2003
|
+
}
|
|
2004
|
+
const inner = hierarchyJson?.geo_code_hierarchy_json;
|
|
2005
|
+
const lowestId = hierarchyJson?.geo_lowest_level_value_id;
|
|
2006
|
+
if (dataPath.endsWith('.geo_code_hierarchy_json')) {
|
|
2007
|
+
const prefix = dataPath.substring(0, dataPath.lastIndexOf('.'));
|
|
2008
|
+
let finalUpdatedValues = setWidgetValue(baseValues, dataPath, widgetId, inner);
|
|
2009
|
+
finalUpdatedValues = setWidgetValue(finalUpdatedValues, `${prefix}.geo_lowest_level_value_id`, widgetId, lowestId);
|
|
2010
|
+
return finalUpdatedValues;
|
|
2011
|
+
}
|
|
2012
|
+
return setWidgetValue(baseValues, dataPath, widgetId, inner);
|
|
2013
|
+
}
|
|
2014
|
+
class GeoHierarchyBuilder {
|
|
2015
|
+
constructor() {
|
|
2016
|
+
this.hierarchies = new Map();
|
|
2017
|
+
}
|
|
2018
|
+
/**
|
|
2019
|
+
* Get or create hierarchy state for a group
|
|
2020
|
+
*/
|
|
2021
|
+
getHierarchy(groupId = 'default') {
|
|
2022
|
+
if (!this.hierarchies.has(groupId)) {
|
|
2023
|
+
this.hierarchies.set(groupId, {
|
|
2024
|
+
levels: new Map(),
|
|
2025
|
+
order: [],
|
|
2026
|
+
});
|
|
2027
|
+
}
|
|
2028
|
+
return this.hierarchies.get(groupId);
|
|
2029
|
+
}
|
|
2030
|
+
/**
|
|
2031
|
+
* Add a level to the hierarchy
|
|
2032
|
+
*/
|
|
2033
|
+
addLevel(level, level_value_id, level_value_mnemonic, groupId = 'default') {
|
|
2034
|
+
const hierarchy = this.getHierarchy(groupId);
|
|
2035
|
+
// If level already exists, remove it and everything after it
|
|
2036
|
+
const existingIndex = hierarchy.order.indexOf(level);
|
|
2037
|
+
if (existingIndex >= 0) {
|
|
2038
|
+
// Remove this level and all subsequent levels
|
|
2039
|
+
const levelsToRemove = hierarchy.order.slice(existingIndex);
|
|
2040
|
+
levelsToRemove.forEach((l) => {
|
|
2041
|
+
hierarchy.levels.delete(l);
|
|
2042
|
+
hierarchy.order = hierarchy.order.filter((o) => o !== l);
|
|
2043
|
+
});
|
|
2044
|
+
}
|
|
2045
|
+
// Add new level
|
|
2046
|
+
hierarchy.levels.set(level, {
|
|
2047
|
+
level,
|
|
2048
|
+
level_value_id,
|
|
2049
|
+
level_value_mnemonic,
|
|
2050
|
+
});
|
|
2051
|
+
hierarchy.order.push(level);
|
|
2052
|
+
}
|
|
2053
|
+
/**
|
|
2054
|
+
* Remove a level and all levels below it
|
|
2055
|
+
*/
|
|
2056
|
+
removeLevelAndBelow(level, groupId = 'default') {
|
|
2057
|
+
const hierarchy = this.getHierarchy(groupId);
|
|
2058
|
+
const index = hierarchy.order.indexOf(level);
|
|
2059
|
+
if (index >= 0) {
|
|
2060
|
+
// Remove this level and all subsequent levels
|
|
2061
|
+
const levelsToRemove = hierarchy.order.slice(index);
|
|
2062
|
+
levelsToRemove.forEach((l) => {
|
|
2063
|
+
hierarchy.levels.delete(l);
|
|
2064
|
+
hierarchy.order = hierarchy.order.filter((o) => o !== l);
|
|
2065
|
+
});
|
|
2066
|
+
}
|
|
2067
|
+
}
|
|
2068
|
+
/**
|
|
2069
|
+
* Build hierarchy JSON structure
|
|
2070
|
+
*/
|
|
2071
|
+
buildHierarchyJson(groupId = 'default') {
|
|
2072
|
+
const hierarchy = this.getHierarchy(groupId);
|
|
2073
|
+
if (hierarchy.order.length === 0) {
|
|
2074
|
+
return null;
|
|
2075
|
+
}
|
|
2076
|
+
const hierarchyArray = hierarchy.order.map((level) => {
|
|
2077
|
+
const data = hierarchy.levels.get(level);
|
|
2078
|
+
return {
|
|
2079
|
+
level: data.level,
|
|
2080
|
+
level_value_id: data.level_value_id,
|
|
2081
|
+
level_value_mnemonic: data.level_value_mnemonic,
|
|
2082
|
+
};
|
|
2083
|
+
});
|
|
2084
|
+
const lowestLevel = hierarchy.order[hierarchy.order.length - 1];
|
|
2085
|
+
const lowestLevelData = hierarchy.levels.get(lowestLevel);
|
|
2086
|
+
return {
|
|
2087
|
+
geo_lowest_level_value_id: lowestLevelData.level_value_id,
|
|
2088
|
+
geo_code_hierarchy_json: {
|
|
2089
|
+
hierarchy: hierarchyArray,
|
|
2090
|
+
lowest_level_value_id: lowestLevelData.level_value_id,
|
|
2091
|
+
},
|
|
2092
|
+
};
|
|
2093
|
+
}
|
|
2094
|
+
/**
|
|
2095
|
+
* Clear hierarchy for a group
|
|
2096
|
+
*/
|
|
2097
|
+
clear(groupId = 'default') {
|
|
2098
|
+
this.hierarchies.delete(groupId);
|
|
2099
|
+
}
|
|
2100
|
+
/**
|
|
2101
|
+
* Clear all hierarchies
|
|
2102
|
+
*/
|
|
2103
|
+
clearAll() {
|
|
2104
|
+
this.hierarchies.clear();
|
|
2105
|
+
}
|
|
2106
|
+
/**
|
|
2107
|
+
* Get current levels for a group
|
|
2108
|
+
*/
|
|
2109
|
+
getLevels(groupId = 'default') {
|
|
2110
|
+
const hierarchy = this.getHierarchy(groupId);
|
|
2111
|
+
return hierarchy.order.map((level) => hierarchy.levels.get(level));
|
|
2112
|
+
}
|
|
2113
|
+
}
|
|
2114
|
+
// Singleton instance
|
|
2115
|
+
const geoHierarchyBuilder = new GeoHierarchyBuilder();
|
|
2116
|
+
/** Sentinel written to Redux when a geo level is cleared by cascade (distinct from "never set"). */
|
|
2117
|
+
const GEO_LEVEL_CLEARED = null;
|
|
2118
|
+
const geoWidgetParentRegistry = new Map();
|
|
2119
|
+
function registerGeoWidgetParent(widgetId, parentWidgetId) {
|
|
2120
|
+
geoWidgetParentRegistry.set(widgetId, parentWidgetId || null);
|
|
2121
|
+
}
|
|
2122
|
+
function unregisterGeoWidgetParent(widgetId) {
|
|
2123
|
+
geoWidgetParentRegistry.delete(widgetId);
|
|
2124
|
+
}
|
|
2125
|
+
/** True when changedWidgetId is any upstream geo parent of widgetId (not only immediate parent). */
|
|
2126
|
+
function isUpstreamGeoAncestor(changedWidgetId, widgetId, immediateParentWidgetId) {
|
|
2127
|
+
if (changedWidgetId === widgetId) {
|
|
2128
|
+
return false;
|
|
2129
|
+
}
|
|
2130
|
+
let cursor = immediateParentWidgetId;
|
|
2131
|
+
while (cursor) {
|
|
2132
|
+
if (cursor === changedWidgetId) {
|
|
2133
|
+
return true;
|
|
2134
|
+
}
|
|
2135
|
+
cursor = geoWidgetParentRegistry.get(cursor) ?? null;
|
|
2136
|
+
}
|
|
2137
|
+
return false;
|
|
2138
|
+
}
|
|
2139
|
+
function readStoredHierarchyLevels(values, dataPath, widgetId) {
|
|
2140
|
+
const stored = getWidgetValue(values, dataPath, widgetId);
|
|
2141
|
+
const hierarchy = stored?.hierarchy || stored?.geo_code_hierarchy_json?.hierarchy;
|
|
2142
|
+
if (!Array.isArray(hierarchy)) {
|
|
2143
|
+
return [];
|
|
2144
|
+
}
|
|
2145
|
+
return hierarchy.filter((entry) => entry?.level && entry.level_value_id);
|
|
2146
|
+
}
|
|
2147
|
+
function builderMatchesStored(groupId, storedLevels) {
|
|
2148
|
+
const builderLevels = geoHierarchyBuilder.getLevels(groupId);
|
|
2149
|
+
if (builderLevels.length !== storedLevels.length) {
|
|
2150
|
+
return false;
|
|
2151
|
+
}
|
|
2152
|
+
return storedLevels.every((stored, index) => {
|
|
2153
|
+
const built = builderLevels[index];
|
|
2154
|
+
return (built.level === stored.level &&
|
|
2155
|
+
String(built.level_value_id) === String(stored.level_value_id));
|
|
2156
|
+
});
|
|
2157
|
+
}
|
|
2158
|
+
/** Seed in-memory builder from persisted hierarchy JSON (edit-mode rehydration). */
|
|
2159
|
+
function seedGeoHierarchyFromValues(values, dataPath, widgetId, groupId) {
|
|
2160
|
+
if (!dataPath || typeof dataPath !== 'string') {
|
|
2161
|
+
return;
|
|
2162
|
+
}
|
|
2163
|
+
const storedLevels = readStoredHierarchyLevels(values, dataPath, widgetId);
|
|
2164
|
+
if (storedLevels.length === 0) {
|
|
2165
|
+
return;
|
|
2166
|
+
}
|
|
2167
|
+
if (builderMatchesStored(groupId, storedLevels)) {
|
|
2168
|
+
return;
|
|
2169
|
+
}
|
|
2170
|
+
geoHierarchyBuilder.clear(groupId);
|
|
2171
|
+
storedLevels.forEach((entry) => {
|
|
2172
|
+
geoHierarchyBuilder.addLevel(entry.level, String(entry.level_value_id), entry.level_value_mnemonic || String(entry.level_value_id), groupId);
|
|
2173
|
+
});
|
|
2174
|
+
}
|
|
2175
|
+
/** Force-clear builder for a group, then seed from Redux/schema values (e.g. after Cancel). */
|
|
2176
|
+
function resetAndSeedGeoHierarchyFromValues(values, dataPath, widgetId, groupId) {
|
|
2177
|
+
geoHierarchyBuilder.clear(groupId);
|
|
2178
|
+
seedGeoHierarchyFromValues(values, dataPath, widgetId, groupId);
|
|
2179
|
+
}
|
|
2180
|
+
|
|
1935
2181
|
// Define stable empty arrays to avoid selector reference issues
|
|
1936
2182
|
const EMPTY_ERRORS = [];
|
|
1937
2183
|
const EMPTY_DATA_SOURCE$1 = [];
|
|
@@ -2021,6 +2267,17 @@ const useBaseWidget = (options) => {
|
|
|
2021
2267
|
if (isLayoutWidget) {
|
|
2022
2268
|
return undefined; // Layout widgets don't have values
|
|
2023
2269
|
}
|
|
2270
|
+
const geoConfig = config['widget-geo-config'];
|
|
2271
|
+
if (geoConfig) {
|
|
2272
|
+
const value = resolveGeoWidgetLevelValue(values, widgetId, config['widget-data-path'], geoConfig);
|
|
2273
|
+
if (userHasSetValueRef.current) {
|
|
2274
|
+
return value;
|
|
2275
|
+
}
|
|
2276
|
+
if (value === null) {
|
|
2277
|
+
return null;
|
|
2278
|
+
}
|
|
2279
|
+
return value !== undefined ? value : config['widget-data-default'];
|
|
2280
|
+
}
|
|
2024
2281
|
// Try to get value from widgetId first (this should have the actual selected value)
|
|
2025
2282
|
// For geo widgets with dataPath, widgetId stores the actual ID, while dataPath stores the hierarchy object
|
|
2026
2283
|
let value = values[widgetId];
|
|
@@ -2230,6 +2487,14 @@ const useBaseWidget = (options) => {
|
|
|
2230
2487
|
// Track readonly state explicitly to detect changes
|
|
2231
2488
|
// Use JSON.stringify to create a stable reference for the dependency array
|
|
2232
2489
|
const isReadonly = config['widget-readonly'] ?? false;
|
|
2490
|
+
// Leaving edit mode (Cancel): allow mirror/rehydration on next Edit
|
|
2491
|
+
React.useEffect(() => {
|
|
2492
|
+
if (config['widget-readonly']) {
|
|
2493
|
+
userHasSetValueRef.current = false;
|
|
2494
|
+
lastMirroredValueRef.current = null;
|
|
2495
|
+
lastDispatchedValueRef.current = null;
|
|
2496
|
+
}
|
|
2497
|
+
}, [config['widget-readonly']]);
|
|
2233
2498
|
const dataSource = config['widget-data-source'];
|
|
2234
2499
|
const geoConfig = config['widget-geo-config'];
|
|
2235
2500
|
// Use ref to store handler to avoid stale closures
|
|
@@ -2434,113 +2699,6 @@ const useWidgetCascade = (options) => {
|
|
|
2434
2699
|
}, [cascadeConfig, eventBus, dataSource, widgetId, dispatch]);
|
|
2435
2700
|
};
|
|
2436
2701
|
|
|
2437
|
-
/**
|
|
2438
|
-
* Geo Hierarchy Builder
|
|
2439
|
-
* Manages geo hierarchy state and builds hierarchy JSON structure
|
|
2440
|
-
*/
|
|
2441
|
-
class GeoHierarchyBuilder {
|
|
2442
|
-
constructor() {
|
|
2443
|
-
this.hierarchies = new Map();
|
|
2444
|
-
}
|
|
2445
|
-
/**
|
|
2446
|
-
* Get or create hierarchy state for a group
|
|
2447
|
-
*/
|
|
2448
|
-
getHierarchy(groupId = 'default') {
|
|
2449
|
-
if (!this.hierarchies.has(groupId)) {
|
|
2450
|
-
this.hierarchies.set(groupId, {
|
|
2451
|
-
levels: new Map(),
|
|
2452
|
-
order: [],
|
|
2453
|
-
});
|
|
2454
|
-
}
|
|
2455
|
-
return this.hierarchies.get(groupId);
|
|
2456
|
-
}
|
|
2457
|
-
/**
|
|
2458
|
-
* Add a level to the hierarchy
|
|
2459
|
-
*/
|
|
2460
|
-
addLevel(level, level_value_id, level_value_mnemonic, groupId = 'default') {
|
|
2461
|
-
const hierarchy = this.getHierarchy(groupId);
|
|
2462
|
-
// If level already exists, remove it and everything after it
|
|
2463
|
-
const existingIndex = hierarchy.order.indexOf(level);
|
|
2464
|
-
if (existingIndex >= 0) {
|
|
2465
|
-
// Remove this level and all subsequent levels
|
|
2466
|
-
const levelsToRemove = hierarchy.order.slice(existingIndex);
|
|
2467
|
-
levelsToRemove.forEach((l) => {
|
|
2468
|
-
hierarchy.levels.delete(l);
|
|
2469
|
-
hierarchy.order = hierarchy.order.filter((o) => o !== l);
|
|
2470
|
-
});
|
|
2471
|
-
}
|
|
2472
|
-
// Add new level
|
|
2473
|
-
hierarchy.levels.set(level, {
|
|
2474
|
-
level,
|
|
2475
|
-
level_value_id,
|
|
2476
|
-
level_value_mnemonic,
|
|
2477
|
-
});
|
|
2478
|
-
hierarchy.order.push(level);
|
|
2479
|
-
}
|
|
2480
|
-
/**
|
|
2481
|
-
* Remove a level and all levels below it
|
|
2482
|
-
*/
|
|
2483
|
-
removeLevelAndBelow(level, groupId = 'default') {
|
|
2484
|
-
const hierarchy = this.getHierarchy(groupId);
|
|
2485
|
-
const index = hierarchy.order.indexOf(level);
|
|
2486
|
-
if (index >= 0) {
|
|
2487
|
-
// Remove this level and all subsequent levels
|
|
2488
|
-
const levelsToRemove = hierarchy.order.slice(index);
|
|
2489
|
-
levelsToRemove.forEach((l) => {
|
|
2490
|
-
hierarchy.levels.delete(l);
|
|
2491
|
-
hierarchy.order = hierarchy.order.filter((o) => o !== l);
|
|
2492
|
-
});
|
|
2493
|
-
}
|
|
2494
|
-
}
|
|
2495
|
-
/**
|
|
2496
|
-
* Build hierarchy JSON structure
|
|
2497
|
-
*/
|
|
2498
|
-
buildHierarchyJson(groupId = 'default') {
|
|
2499
|
-
const hierarchy = this.getHierarchy(groupId);
|
|
2500
|
-
if (hierarchy.order.length === 0) {
|
|
2501
|
-
return null;
|
|
2502
|
-
}
|
|
2503
|
-
const hierarchyArray = hierarchy.order.map((level) => {
|
|
2504
|
-
const data = hierarchy.levels.get(level);
|
|
2505
|
-
return {
|
|
2506
|
-
level: data.level,
|
|
2507
|
-
level_value_id: data.level_value_id,
|
|
2508
|
-
level_value_mnemonic: data.level_value_mnemonic,
|
|
2509
|
-
};
|
|
2510
|
-
});
|
|
2511
|
-
const lowestLevel = hierarchy.order[hierarchy.order.length - 1];
|
|
2512
|
-
const lowestLevelData = hierarchy.levels.get(lowestLevel);
|
|
2513
|
-
return {
|
|
2514
|
-
geo_lowest_level_value_id: lowestLevelData.level_value_id,
|
|
2515
|
-
geo_code_hierarchy_json: {
|
|
2516
|
-
hierarchy: hierarchyArray,
|
|
2517
|
-
lowest_level_value_id: lowestLevelData.level_value_id,
|
|
2518
|
-
},
|
|
2519
|
-
};
|
|
2520
|
-
}
|
|
2521
|
-
/**
|
|
2522
|
-
* Clear hierarchy for a group
|
|
2523
|
-
*/
|
|
2524
|
-
clear(groupId = 'default') {
|
|
2525
|
-
this.hierarchies.delete(groupId);
|
|
2526
|
-
}
|
|
2527
|
-
/**
|
|
2528
|
-
* Clear all hierarchies
|
|
2529
|
-
*/
|
|
2530
|
-
clearAll() {
|
|
2531
|
-
this.hierarchies.clear();
|
|
2532
|
-
}
|
|
2533
|
-
/**
|
|
2534
|
-
* Get current levels for a group
|
|
2535
|
-
*/
|
|
2536
|
-
getLevels(groupId = 'default') {
|
|
2537
|
-
const hierarchy = this.getHierarchy(groupId);
|
|
2538
|
-
return hierarchy.order.map((level) => hierarchy.levels.get(level));
|
|
2539
|
-
}
|
|
2540
|
-
}
|
|
2541
|
-
// Singleton instance
|
|
2542
|
-
const geoHierarchyBuilder = new GeoHierarchyBuilder();
|
|
2543
|
-
|
|
2544
2702
|
// Define stable empty array to avoid selector reference issues
|
|
2545
2703
|
const EMPTY_DATA_SOURCE = [];
|
|
2546
2704
|
/**
|
|
@@ -2560,138 +2718,108 @@ const useGeoWidgetCascade = (options) => {
|
|
|
2560
2718
|
: 'default';
|
|
2561
2719
|
const valuesRef = React.useRef(values);
|
|
2562
2720
|
const handlerRef = React.useRef(dataSourceRequestHandler);
|
|
2721
|
+
const lastCascadePublishRef = React.useRef(undefined);
|
|
2563
2722
|
// Keep refs updated
|
|
2564
2723
|
React.useEffect(() => {
|
|
2565
2724
|
valuesRef.current = values;
|
|
2566
2725
|
handlerRef.current = dataSourceRequestHandler;
|
|
2567
2726
|
}, [values, dataSourceRequestHandler]);
|
|
2568
2727
|
// Get current value and data source options
|
|
2569
|
-
const currentValue = reactRedux.useSelector((state) =>
|
|
2570
|
-
|
|
2571
|
-
|
|
2572
|
-
// If not found in widgetId, try dataPath
|
|
2573
|
-
if (value === undefined && dataPath) {
|
|
2574
|
-
value = getWidgetValue(state.widget.values, dataPath, widgetId);
|
|
2575
|
-
}
|
|
2576
|
-
// Extract value if it's a geo hierarchy object
|
|
2577
|
-
if (value && typeof value === 'object' && !Array.isArray(value) && geoConfig) {
|
|
2578
|
-
const hierarchy = value.hierarchy || value.geo_code_hierarchy_json?.hierarchy;
|
|
2579
|
-
if (Array.isArray(hierarchy)) {
|
|
2580
|
-
const levelData = hierarchy.find((l) => l.level === geoConfig.level);
|
|
2581
|
-
if (levelData) {
|
|
2582
|
-
return levelData.level_value_id;
|
|
2583
|
-
}
|
|
2584
|
-
}
|
|
2585
|
-
// Extended fallbacks (matching useBaseWidget)
|
|
2586
|
-
if ('geo_lowest_level_value_id' in value) {
|
|
2587
|
-
return value.geo_lowest_level_value_id;
|
|
2588
|
-
}
|
|
2589
|
-
if ('lowest_level_value_id' in value) {
|
|
2590
|
-
return value.lowest_level_value_id;
|
|
2591
|
-
}
|
|
2592
|
-
if (value.geo_code_hierarchy_json?.lowest_level_value_id) {
|
|
2593
|
-
return value.geo_code_hierarchy_json.lowest_level_value_id;
|
|
2594
|
-
}
|
|
2595
|
-
if (value.geo_code_hierarchy_json?.geo_lowest_level_value_id) {
|
|
2596
|
-
return value.geo_code_hierarchy_json.geo_lowest_level_value_id;
|
|
2597
|
-
}
|
|
2598
|
-
}
|
|
2599
|
-
return value;
|
|
2600
|
-
});
|
|
2728
|
+
const currentValue = reactRedux.useSelector((state) => geoConfig
|
|
2729
|
+
? resolveGeoWidgetLevelValue(state.widget.values, widgetId, dataPath, geoConfig)
|
|
2730
|
+
: state.widget.values[widgetId]);
|
|
2601
2731
|
// Memoize selector to avoid returning new array reference
|
|
2602
2732
|
const dataSourceOptions = reactRedux.useSelector((state) => state.widget.dataSources[widgetId] ?? EMPTY_DATA_SOURCE);
|
|
2733
|
+
// Register parent chain for upstream-ancestor detection (grandparent → grandchild reset)
|
|
2734
|
+
React.useEffect(() => {
|
|
2735
|
+
if (!geoConfig) {
|
|
2736
|
+
return;
|
|
2737
|
+
}
|
|
2738
|
+
registerGeoWidgetParent(widgetId, geoConfig.parentWidgetId);
|
|
2739
|
+
return () => unregisterGeoWidgetParent(widgetId);
|
|
2740
|
+
}, [widgetId, geoConfig]);
|
|
2741
|
+
// Keep in-memory builder in sync with persisted hierarchy (reload, cancel→re-edit, etc.)
|
|
2742
|
+
React.useEffect(() => {
|
|
2743
|
+
if (!geoConfig || typeof dataPath !== 'string') {
|
|
2744
|
+
return;
|
|
2745
|
+
}
|
|
2746
|
+
seedGeoHierarchyFromValues(values, dataPath, widgetId, groupId);
|
|
2747
|
+
}, [geoConfig, dataPath, widgetId, groupId, values]);
|
|
2603
2748
|
React.useEffect(() => {
|
|
2604
2749
|
if (!geoConfig || !eventBus || !dataSource || dataSource.type !== 'api') {
|
|
2605
2750
|
return;
|
|
2606
2751
|
}
|
|
2607
|
-
const { level, isLastLevel, parentWidgetId } = geoConfig;
|
|
2608
|
-
|
|
2609
|
-
if (parentWidgetId) {
|
|
2610
|
-
|
|
2611
|
-
|
|
2612
|
-
|
|
2613
|
-
|
|
2614
|
-
|
|
2615
|
-
|
|
2616
|
-
|
|
2617
|
-
|
|
2618
|
-
|
|
2619
|
-
|
|
2620
|
-
|
|
2621
|
-
|
|
2622
|
-
|
|
2623
|
-
|
|
2624
|
-
|
|
2625
|
-
|
|
2626
|
-
|
|
2627
|
-
|
|
2628
|
-
|
|
2629
|
-
|
|
2630
|
-
|
|
2631
|
-
|
|
2632
|
-
|
|
2633
|
-
|
|
2634
|
-
|
|
2635
|
-
|
|
2636
|
-
|
|
2637
|
-
|
|
2638
|
-
|
|
2639
|
-
|
|
2640
|
-
|
|
2641
|
-
|
|
2642
|
-
|
|
2643
|
-
|
|
2644
|
-
|
|
2645
|
-
|
|
2646
|
-
|
|
2647
|
-
|
|
2648
|
-
|
|
2649
|
-
|
|
2650
|
-
|
|
2651
|
-
// This ensures we don't accidentally overwrite the parent widget's value
|
|
2652
|
-
dispatch(setValue({ widgetId, value: undefined }));
|
|
2653
|
-
}
|
|
2654
|
-
}
|
|
2655
|
-
}
|
|
2656
|
-
else {
|
|
2657
|
-
dispatch(setValue({ widgetId, value: undefined }));
|
|
2752
|
+
const { level, isLastLevel, parentWidgetId: rawParentWidgetId } = geoConfig;
|
|
2753
|
+
const parentWidgetId = rawParentWidgetId || null;
|
|
2754
|
+
if (!parentWidgetId) {
|
|
2755
|
+
return;
|
|
2756
|
+
}
|
|
2757
|
+
const clearThisLevel = (baseValues) => {
|
|
2758
|
+
geoHierarchyBuilder.removeLevelAndBelow(level, groupId);
|
|
2759
|
+
if (dataPath) {
|
|
2760
|
+
dispatch(setValues(applySharedGeoHierarchyToValues(baseValues, groupId, dataPath, widgetId)));
|
|
2761
|
+
}
|
|
2762
|
+
dispatch(setValue({ widgetId, value: GEO_LEVEL_CLEARED }));
|
|
2763
|
+
if (!isLastLevel) {
|
|
2764
|
+
eventBus.publish({
|
|
2765
|
+
type: 'widget:change',
|
|
2766
|
+
widgetId,
|
|
2767
|
+
value: GEO_LEVEL_CLEARED,
|
|
2768
|
+
timestamp: Date.now(),
|
|
2769
|
+
});
|
|
2770
|
+
}
|
|
2771
|
+
dispatch(setDataSource({ widgetId, data: [] }));
|
|
2772
|
+
};
|
|
2773
|
+
const handleParentChange = async (event) => {
|
|
2774
|
+
const isDirectParent = event.widgetId === parentWidgetId;
|
|
2775
|
+
const isAncestor = isUpstreamGeoAncestor(event.widgetId, widgetId, parentWidgetId);
|
|
2776
|
+
if (!isDirectParent && !isAncestor) {
|
|
2777
|
+
return;
|
|
2778
|
+
}
|
|
2779
|
+
await new Promise(resolve => setTimeout(resolve, 0));
|
|
2780
|
+
const currentValues = valuesRef.current;
|
|
2781
|
+
const currentHandler = handlerRef.current;
|
|
2782
|
+
// Grandparent (or higher) changed: clear this level; only immediate parent drives reload
|
|
2783
|
+
if (isAncestor && !isDirectParent) {
|
|
2784
|
+
clearThisLevel(currentValues);
|
|
2785
|
+
return;
|
|
2786
|
+
}
|
|
2787
|
+
const parentCleared = event.value === undefined ||
|
|
2788
|
+
event.value === null ||
|
|
2789
|
+
event.value === '' ||
|
|
2790
|
+
event.value === GEO_LEVEL_CLEARED;
|
|
2791
|
+
let parentValue = event.value;
|
|
2792
|
+
if (!parentCleared && (parentValue === undefined || parentValue === null)) {
|
|
2793
|
+
parentValue = currentValues[parentWidgetId];
|
|
2794
|
+
if (parentValue === undefined && dataSource.dependsOn) {
|
|
2795
|
+
parentValue = getWidgetValue(currentValues, dataSource.dependsOn, '');
|
|
2658
2796
|
}
|
|
2659
|
-
|
|
2660
|
-
|
|
2661
|
-
|
|
2662
|
-
|
|
2663
|
-
|
|
2664
|
-
|
|
2665
|
-
|
|
2666
|
-
|
|
2667
|
-
|
|
2668
|
-
|
|
2669
|
-
|
|
2670
|
-
|
|
2671
|
-
|
|
2672
|
-
|
|
2673
|
-
const valueKey = dataSource.valueKey || 'level_value_id';
|
|
2674
|
-
const labelKey = dataSource.labelKey || 'level_value_mnemonic';
|
|
2675
|
-
const transformed = transformDataSourceOptions(data, valueKey, labelKey);
|
|
2676
|
-
dispatch(setDataSource({ widgetId, data: transformed }));
|
|
2677
|
-
}
|
|
2678
|
-
catch (error) {
|
|
2679
|
-
console.error('Error reloading geo data source:', error);
|
|
2680
|
-
dispatch(setDataSource({ widgetId, data: [] }));
|
|
2681
|
-
}
|
|
2797
|
+
}
|
|
2798
|
+
clearThisLevel(currentValues);
|
|
2799
|
+
if (currentHandler && parentValue !== null && parentValue !== undefined && parentValue !== '') {
|
|
2800
|
+
try {
|
|
2801
|
+
const updatedValues = {
|
|
2802
|
+
...currentValues,
|
|
2803
|
+
[parentWidgetId]: parentValue,
|
|
2804
|
+
};
|
|
2805
|
+
const levelId = geoConfig.level;
|
|
2806
|
+
const data = await getApiDataSource(dataSource, updatedValues, currentHandler, levelId);
|
|
2807
|
+
const valueKey = dataSource.valueKey || 'level_value_id';
|
|
2808
|
+
const labelKey = dataSource.labelKey || 'level_value_mnemonic';
|
|
2809
|
+
const transformed = transformDataSourceOptions(data, valueKey, labelKey);
|
|
2810
|
+
dispatch(setDataSource({ widgetId, data: transformed }));
|
|
2682
2811
|
}
|
|
2683
|
-
|
|
2684
|
-
|
|
2685
|
-
geoHierarchyBuilder.removeLevelAndBelow(level, groupId);
|
|
2812
|
+
catch (error) {
|
|
2813
|
+
console.error('Error reloading geo data source:', error);
|
|
2686
2814
|
dispatch(setDataSource({ widgetId, data: [] }));
|
|
2687
2815
|
}
|
|
2688
|
-
}
|
|
2689
|
-
|
|
2690
|
-
|
|
2691
|
-
|
|
2692
|
-
|
|
2693
|
-
}
|
|
2694
|
-
}, [geoConfig, eventBus, dataSource, widgetId, dataPath, dispatch]);
|
|
2816
|
+
}
|
|
2817
|
+
};
|
|
2818
|
+
const unsubscribe = eventBus.subscribe('widget:change', handleParentChange);
|
|
2819
|
+
return () => {
|
|
2820
|
+
unsubscribe();
|
|
2821
|
+
};
|
|
2822
|
+
}, [geoConfig, eventBus, dataSource, widgetId, dataPath, dispatch, groupId]);
|
|
2695
2823
|
// Handle value changes to build hierarchy
|
|
2696
2824
|
React.useEffect(() => {
|
|
2697
2825
|
if (!geoConfig) {
|
|
@@ -2700,22 +2828,20 @@ const useGeoWidgetCascade = (options) => {
|
|
|
2700
2828
|
// Skip if value is undefined (it might still be loading or rehydrating)
|
|
2701
2829
|
// ONLY clear hierarchy if the value is explicitly null or empty string (user action)
|
|
2702
2830
|
if (currentValue === null || currentValue === '') {
|
|
2703
|
-
const { level } = geoConfig;
|
|
2831
|
+
const { level, isLastLevel } = geoConfig;
|
|
2704
2832
|
geoHierarchyBuilder.removeLevelAndBelow(level, groupId);
|
|
2705
2833
|
// If we have a dataPath, we need to update Redux with the cleared hierarchy
|
|
2706
2834
|
if (dataPath) {
|
|
2707
|
-
|
|
2708
|
-
|
|
2709
|
-
|
|
2710
|
-
|
|
2711
|
-
|
|
2712
|
-
|
|
2713
|
-
|
|
2714
|
-
|
|
2715
|
-
|
|
2716
|
-
|
|
2717
|
-
}
|
|
2718
|
-
dispatch(setValues(finalUpdatedValues));
|
|
2835
|
+
dispatch(setValues(applySharedGeoHierarchyToValues(valuesRef.current, groupId, dataPath, widgetId)));
|
|
2836
|
+
}
|
|
2837
|
+
if (!isLastLevel && eventBus && lastCascadePublishRef.current !== GEO_LEVEL_CLEARED) {
|
|
2838
|
+
lastCascadePublishRef.current = GEO_LEVEL_CLEARED;
|
|
2839
|
+
eventBus.publish({
|
|
2840
|
+
type: 'widget:change',
|
|
2841
|
+
widgetId,
|
|
2842
|
+
value: GEO_LEVEL_CLEARED,
|
|
2843
|
+
timestamp: Date.now(),
|
|
2844
|
+
});
|
|
2719
2845
|
}
|
|
2720
2846
|
return;
|
|
2721
2847
|
}
|
|
@@ -2766,30 +2892,20 @@ const useGeoWidgetCascade = (options) => {
|
|
|
2766
2892
|
// Add level to hierarchy
|
|
2767
2893
|
geoHierarchyBuilder.addLevel(level, level_value_id, level_value_mnemonic, groupId);
|
|
2768
2894
|
// Build and store hierarchy JSON on every change
|
|
2769
|
-
if (dataPath) {
|
|
2770
|
-
|
|
2771
|
-
|
|
2772
|
-
|
|
2773
|
-
|
|
2774
|
-
|
|
2775
|
-
|
|
2776
|
-
|
|
2777
|
-
|
|
2778
|
-
|
|
2779
|
-
|
|
2780
|
-
|
|
2781
|
-
finalUpdatedValues = setWidgetValue(finalUpdatedValues, `${prefix}.geo_lowest_level_value_id`, widgetId, hierarchyJson.geo_lowest_level_value_id);
|
|
2782
|
-
}
|
|
2783
|
-
else {
|
|
2784
|
-
// Fallback if path doesn't follow the naming convention
|
|
2785
|
-
finalUpdatedValues = setWidgetValue(finalUpdatedValues, dataPath, widgetId, hierarchyJson.geo_code_hierarchy_json);
|
|
2786
|
-
}
|
|
2787
|
-
// CRITICAL: Use setValues for deep merge instead of replacing root keys with setValue
|
|
2788
|
-
// setWidgetValue returns the complete updated state object with all keys preserved
|
|
2789
|
-
dispatch(setValues(finalUpdatedValues));
|
|
2790
|
-
}
|
|
2895
|
+
if (dataPath && geoHierarchyBuilder.buildHierarchyJson(groupId)) {
|
|
2896
|
+
dispatch(setValues(applySharedGeoHierarchyToValues(valuesRef.current, groupId, dataPath, widgetId)));
|
|
2897
|
+
}
|
|
2898
|
+
// Notify descendants when this level changes via hierarchy/rehydration (handleChange may not run).
|
|
2899
|
+
if (!isLastLevel && eventBus && lastCascadePublishRef.current !== level_value_id) {
|
|
2900
|
+
lastCascadePublishRef.current = level_value_id;
|
|
2901
|
+
eventBus.publish({
|
|
2902
|
+
type: 'widget:change',
|
|
2903
|
+
widgetId,
|
|
2904
|
+
value: level_value_id,
|
|
2905
|
+
timestamp: Date.now(),
|
|
2906
|
+
});
|
|
2791
2907
|
}
|
|
2792
|
-
}, [geoConfig, currentValue, widgetId, dataPath, dispatch, dataSourceOptions]);
|
|
2908
|
+
}, [geoConfig, currentValue, widgetId, dataPath, dispatch, dataSourceOptions, eventBus, groupId]);
|
|
2793
2909
|
};
|
|
2794
2910
|
|
|
2795
2911
|
class WidgetRegistry {
|
|
@@ -8788,16 +8904,65 @@ const DisplayWidget = ({ config }) => {
|
|
|
8788
8904
|
return (jsxRuntimeExports.jsxs("div", { className: "mb-[10px] DisplayFieldWidget flex flex-col sm:flex-row sm:items-start", children: [jsxRuntimeExports.jsxs("div", { className: "text-base text-gray-600 font-medium md:min-w-[120px] sm:pr-4 mb-1 sm:mb-0", style: { fontFamily: 'Roboto, sans-serif' }, title: label, children: [label, ":"] }), jsxRuntimeExports.jsx("div", { className: "flex-1 min-w-0", children: jsxRuntimeExports.jsx("div", { className: "text-base text-gray-900 font-medium", title: String(displayValue ?? ''), children: displayValue }) })] }));
|
|
8789
8905
|
};
|
|
8790
8906
|
|
|
8907
|
+
const getDateColumnConstraintError = (column, cellValue, rowValues, translateConfig) => {
|
|
8908
|
+
const displayValue = cellValue && typeof cellValue === 'string' ? cellValue.split('T')[0] : '';
|
|
8909
|
+
if (!displayValue) {
|
|
8910
|
+
return null;
|
|
8911
|
+
}
|
|
8912
|
+
const optionsConfig = column['widget-data-options'];
|
|
8913
|
+
const formatConfig = column['widget-data-format'];
|
|
8914
|
+
const dateConstraint = formatConfig?.dateConstraint || 'any';
|
|
8915
|
+
const minDate = optionsConfig?.minDate;
|
|
8916
|
+
const maxDate = optionsConfig?.maxDate;
|
|
8917
|
+
const minDateField = optionsConfig?.minDateField;
|
|
8918
|
+
const maxDateField = optionsConfig?.maxDateField;
|
|
8919
|
+
const minDateMessage = optionsConfig?.minDateMessage
|
|
8920
|
+
? translateConfig(optionsConfig.minDateMessage)
|
|
8921
|
+
: undefined;
|
|
8922
|
+
const maxDateMessage = optionsConfig?.maxDateMessage
|
|
8923
|
+
? translateConfig(optionsConfig.maxDateMessage)
|
|
8924
|
+
: undefined;
|
|
8925
|
+
const resolveSiblingDate = (fieldRef) => {
|
|
8926
|
+
if (!fieldRef) {
|
|
8927
|
+
return undefined;
|
|
8928
|
+
}
|
|
8929
|
+
const raw = getValueByPath(rowValues, fieldRef) ?? rowValues[fieldRef];
|
|
8930
|
+
return resolveDateBoundFromFieldValue(raw);
|
|
8931
|
+
};
|
|
8932
|
+
const effectiveMinDate = mergeMinDateBounds(getMinDate(dateConstraint, minDate), resolveSiblingDate(minDateField));
|
|
8933
|
+
const effectiveMaxDate = mergeMaxDateBounds(getMaxDate(dateConstraint, maxDate), resolveSiblingDate(maxDateField));
|
|
8934
|
+
return validateDateConstraints(displayValue, effectiveMinDate, effectiveMaxDate, dateConstraint, { minDateMessage, maxDateMessage });
|
|
8935
|
+
};
|
|
8936
|
+
const isTableRowDataValid = (rowData, columns, tableReadonly, translateConfig) => {
|
|
8937
|
+
for (const col of columns) {
|
|
8938
|
+
if (tableReadonly || col['widget-readonly'] === true) {
|
|
8939
|
+
continue;
|
|
8940
|
+
}
|
|
8941
|
+
const columnKey = col['column-key'];
|
|
8942
|
+
const cellValue = rowData[columnKey];
|
|
8943
|
+
const widgetErrors = validateWidget(cellValue, col['widget-data-validation'], col['widget-required']);
|
|
8944
|
+
if (widgetErrors.length > 0) {
|
|
8945
|
+
return false;
|
|
8946
|
+
}
|
|
8947
|
+
if ((col.widget || 'text') === 'date') {
|
|
8948
|
+
const dateError = getDateColumnConstraintError(col, cellValue, rowData, translateConfig);
|
|
8949
|
+
if (dateError) {
|
|
8950
|
+
return false;
|
|
8951
|
+
}
|
|
8952
|
+
}
|
|
8953
|
+
}
|
|
8954
|
+
return true;
|
|
8955
|
+
};
|
|
8791
8956
|
const TableCellSelect = ({ config, value, onValueChange }) => {
|
|
8792
8957
|
const { translate } = useWidgetTranslation();
|
|
8793
8958
|
// Use useBaseWidget to get data source options (it handles loading)
|
|
8794
8959
|
const { dataSourceOptions, loading, config: widgetConfig, } = useBaseWidget({ config });
|
|
8795
8960
|
const isReadonly = config['widget-readonly'] || false;
|
|
8796
|
-
return (jsxRuntimeExports.jsxs("select", { value: value || '', onChange: (e) => onValueChange(e.target.value), disabled: isReadonly || loading, className: `w-full h-[28px] px-2 text-sm border focus:outline-none ${isReadonly || loading ? 'cursor-not-allowed' : ''} table-cell-input`, style: {
|
|
8797
|
-
|
|
8798
|
-
|
|
8799
|
-
|
|
8800
|
-
|
|
8961
|
+
return (jsxRuntimeExports.jsxs("div", { className: "table-cell-field w-full", children: [jsxRuntimeExports.jsxs("select", { value: value || '', onChange: (e) => onValueChange(e.target.value), disabled: isReadonly || loading, className: `w-full h-[28px] px-2 text-sm border focus:outline-none ${isReadonly || loading ? 'cursor-not-allowed' : ''} table-cell-input`, style: {
|
|
8962
|
+
borderRadius: '10px',
|
|
8963
|
+
borderColor: 'var(--owt-widget-input-border, #C4C4C4)',
|
|
8964
|
+
backgroundColor: isReadonly || loading ? 'var(--owt-color-bg-alt, #F6F6F6)' : 'var(--owt-color-bg, #FFFFFF)',
|
|
8965
|
+
}, children: [jsxRuntimeExports.jsx("option", { value: "", children: translate('common.select') || 'Select' }), dataSourceOptions.map((option) => (jsxRuntimeExports.jsx("option", { value: option.value, children: option.label }, option.value)))] }), jsxRuntimeExports.jsx("p", { className: "table-cell-field-error", "aria-hidden": "true", children: '\u00a0' })] }));
|
|
8801
8966
|
};
|
|
8802
8967
|
const SelectDisplayValue$1 = ({ config, value }) => {
|
|
8803
8968
|
const { dataSourceOptions, loading } = useBaseWidget({ config });
|
|
@@ -8816,11 +8981,11 @@ const TableCellText = ({ config, value, onValueChange }) => {
|
|
|
8816
8981
|
config['widget-data-format'];
|
|
8817
8982
|
const maxLength = config['widget-data-validation']?.maxLength;
|
|
8818
8983
|
const displayValue = value !== null && value !== undefined ? String(value) : '';
|
|
8819
|
-
return (jsxRuntimeExports.jsx("input", { type: "text", value: displayValue, onChange: (e) => onValueChange(e.target.value), disabled: isReadonly, placeholder: placeholder, maxLength: maxLength, className: `w-full h-[28px] px-2 text-sm border focus:outline-none ${isReadonly ? 'cursor-not-allowed' : ''} table-cell-input`, style: {
|
|
8820
|
-
|
|
8821
|
-
|
|
8822
|
-
|
|
8823
|
-
|
|
8984
|
+
return (jsxRuntimeExports.jsxs("div", { className: "table-cell-field w-full", children: [jsxRuntimeExports.jsx("input", { type: "text", value: displayValue, onChange: (e) => onValueChange(e.target.value), disabled: isReadonly, placeholder: placeholder, maxLength: maxLength, className: `w-full h-[28px] px-2 text-sm border focus:outline-none ${isReadonly ? 'cursor-not-allowed' : ''} table-cell-input`, style: {
|
|
8985
|
+
borderRadius: '10px',
|
|
8986
|
+
borderColor: 'var(--owt-widget-input-border, #C4C4C4)',
|
|
8987
|
+
backgroundColor: isReadonly ? 'var(--owt-color-bg-alt, #F6F6F6)' : 'var(--owt-color-bg, #FFFFFF)',
|
|
8988
|
+
} }), jsxRuntimeExports.jsx("p", { className: "table-cell-field-error", "aria-hidden": "true", children: '\u00a0' })] }));
|
|
8824
8989
|
};
|
|
8825
8990
|
const TableCellNumber = ({ config, value, onValueChange }) => {
|
|
8826
8991
|
const isReadonly = config['widget-readonly'] || false;
|
|
@@ -8843,11 +9008,11 @@ const TableCellNumber = ({ config, value, onValueChange }) => {
|
|
|
8843
9008
|
onValueChange(inputValue);
|
|
8844
9009
|
}
|
|
8845
9010
|
};
|
|
8846
|
-
return (jsxRuntimeExports.jsx("input", { type: "number", value: displayValue, onChange: handleChange, disabled: isReadonly, placeholder: placeholder, min: validationConfig?.min, max: validationConfig?.max, step: formatConfig?.decimalPlaces ? Math.pow(0.1, formatConfig.decimalPlaces) : undefined, className: `w-full h-[28px] px-2 text-sm border focus:outline-none text-right ${isReadonly ? 'cursor-not-allowed' : ''} table-cell-input`, style: {
|
|
8847
|
-
|
|
8848
|
-
|
|
8849
|
-
|
|
8850
|
-
|
|
9011
|
+
return (jsxRuntimeExports.jsxs("div", { className: "table-cell-field w-full", children: [jsxRuntimeExports.jsx("input", { type: "number", value: displayValue, onChange: handleChange, disabled: isReadonly, placeholder: placeholder, min: validationConfig?.min, max: validationConfig?.max, step: formatConfig?.decimalPlaces ? Math.pow(0.1, formatConfig.decimalPlaces) : undefined, className: `w-full h-[28px] px-2 text-sm border focus:outline-none text-right ${isReadonly ? 'cursor-not-allowed' : ''} table-cell-input`, style: {
|
|
9012
|
+
borderRadius: '10px',
|
|
9013
|
+
borderColor: 'var(--owt-widget-input-border, #C4C4C4)',
|
|
9014
|
+
backgroundColor: isReadonly ? 'var(--owt-color-bg-alt, #F6F6F6)' : 'var(--owt-color-bg, #FFFFFF)',
|
|
9015
|
+
} }), jsxRuntimeExports.jsx("p", { className: "table-cell-field-error", "aria-hidden": "true", children: '\u00a0' })] }));
|
|
8851
9016
|
};
|
|
8852
9017
|
const TableCellDate = ({ config, value, rowValues, onValueChange }) => {
|
|
8853
9018
|
const { translateConfig } = useWidgetTranslation();
|
|
@@ -8906,13 +9071,15 @@ const TableCellDate = ({ config, value, rowValues, onValueChange }) => {
|
|
|
8906
9071
|
setConstraintError(error);
|
|
8907
9072
|
};
|
|
8908
9073
|
const hasError = Boolean(constraintError);
|
|
8909
|
-
return (jsxRuntimeExports.jsxs("div", { className: "w-full", children: [jsxRuntimeExports.jsx("input", { type: "date", value: displayValue, onChange: handleChange, disabled: isReadonly, placeholder: placeholder, min: effectiveMinDate, max: effectiveMaxDate, title: constraintError || translateConfig(config['widget-data-tooltip']), className: `w-full h-[28px] px-2 text-sm border focus:outline-none ${isReadonly ? 'cursor-not-allowed' : ''}
|
|
9074
|
+
return (jsxRuntimeExports.jsxs("div", { className: "table-cell-field w-full", children: [jsxRuntimeExports.jsx("input", { type: "date", value: displayValue, onChange: handleChange, disabled: isReadonly, placeholder: placeholder, min: effectiveMinDate, max: effectiveMaxDate, title: constraintError || translateConfig(config['widget-data-tooltip']), className: `w-full h-[28px] px-2 text-sm border focus:outline-none ${isReadonly ? 'cursor-not-allowed' : ''} table-cell-input`, style: {
|
|
8910
9075
|
borderRadius: '10px',
|
|
8911
9076
|
borderColor: hasError
|
|
8912
9077
|
? 'var(--owt-color-error, #B91C1C)'
|
|
8913
9078
|
: 'var(--owt-widget-input-border, #C4C4C4)',
|
|
8914
9079
|
backgroundColor: isReadonly ? 'var(--owt-color-bg-alt, #F6F6F6)' : 'var(--owt-color-bg, #FFFFFF)',
|
|
8915
|
-
} }),
|
|
9080
|
+
} }), jsxRuntimeExports.jsx("p", { className: "table-cell-field-error text-xs mt-0.5 leading-tight", style: {
|
|
9081
|
+
color: hasError ? 'var(--owt-color-error, #B91C1C)' : 'transparent',
|
|
9082
|
+
}, "aria-live": "polite", children: constraintError ?? '\u00a0' })] }));
|
|
8916
9083
|
};
|
|
8917
9084
|
const TableWidget = ({ config }) => {
|
|
8918
9085
|
const { value, error, touched, isEnabled, onChange, config: widgetConfig, } = useBaseWidget({ config });
|
|
@@ -8938,6 +9105,18 @@ const TableWidget = ({ config }) => {
|
|
|
8938
9105
|
const isSectionEditMode = !isReadonly && operations.edit;
|
|
8939
9106
|
// Check if any row is being edited (either manually or via section edit mode)
|
|
8940
9107
|
const isAnyRowEditing = editingState !== null || isAdding;
|
|
9108
|
+
const canSaveEditingRow = React.useMemo(() => {
|
|
9109
|
+
if (!editingState) {
|
|
9110
|
+
return false;
|
|
9111
|
+
}
|
|
9112
|
+
return isTableRowDataValid(editingState.currentValue, columns, isReadonly, translateConfig);
|
|
9113
|
+
}, [editingState, columns, isReadonly, translateConfig]);
|
|
9114
|
+
const canSaveNewRow = React.useMemo(() => {
|
|
9115
|
+
if (!isAdding || !newRowData) {
|
|
9116
|
+
return false;
|
|
9117
|
+
}
|
|
9118
|
+
return isTableRowDataValid(newRowData, columns, isReadonly, translateConfig);
|
|
9119
|
+
}, [isAdding, newRowData, columns, isReadonly, translateConfig]);
|
|
8941
9120
|
// Show confirmation dialog
|
|
8942
9121
|
const showConfirmation = React.useCallback((message, onConfirm, onCancel) => {
|
|
8943
9122
|
setConfirmationState({
|
|
@@ -9027,6 +9206,8 @@ const TableWidget = ({ config }) => {
|
|
|
9027
9206
|
const saveEdit = React.useCallback(async () => {
|
|
9028
9207
|
if (!editingState)
|
|
9029
9208
|
return;
|
|
9209
|
+
if (!canSaveEditingRow)
|
|
9210
|
+
return;
|
|
9030
9211
|
const rowData = editingState.currentValue;
|
|
9031
9212
|
const rowIndex = editingState.rowIndex;
|
|
9032
9213
|
setLoadingRowIndex(rowIndex);
|
|
@@ -9098,7 +9279,7 @@ const TableWidget = ({ config }) => {
|
|
|
9098
9279
|
finally {
|
|
9099
9280
|
setLoadingRowIndex(null);
|
|
9100
9281
|
}
|
|
9101
|
-
}, [editingState, rows, onChange, dataSourceRequestHandler, apiConfig, translate, isSectionEditMode, originalRows, columns, widgetConfig, dispatch]);
|
|
9282
|
+
}, [editingState, canSaveEditingRow, rows, onChange, dataSourceRequestHandler, apiConfig, translate, isSectionEditMode, originalRows, columns, widgetConfig, dispatch]);
|
|
9102
9283
|
// Add new row
|
|
9103
9284
|
const startAdd = React.useCallback(() => {
|
|
9104
9285
|
// If there's an unsaved edit, cancel it first (no confirmation needed)
|
|
@@ -9116,6 +9297,8 @@ const TableWidget = ({ config }) => {
|
|
|
9116
9297
|
const saveAdd = React.useCallback(async () => {
|
|
9117
9298
|
if (!isAdding || !newRowData)
|
|
9118
9299
|
return;
|
|
9300
|
+
if (!canSaveNewRow)
|
|
9301
|
+
return;
|
|
9119
9302
|
setLoadingRowIndex(-1); // Use -1 to indicate new row
|
|
9120
9303
|
try {
|
|
9121
9304
|
let savedRow = { ...newRowData };
|
|
@@ -9146,7 +9329,7 @@ const TableWidget = ({ config }) => {
|
|
|
9146
9329
|
finally {
|
|
9147
9330
|
setLoadingRowIndex(null);
|
|
9148
9331
|
}
|
|
9149
|
-
}, [isAdding, newRowData, rows, onChange, dataSourceRequestHandler, apiConfig, translate, isSectionEditMode]);
|
|
9332
|
+
}, [isAdding, newRowData, canSaveNewRow, rows, onChange, dataSourceRequestHandler, apiConfig, translate, isSectionEditMode]);
|
|
9150
9333
|
// Delete row
|
|
9151
9334
|
const deleteRow = React.useCallback(async (rowIndex) => {
|
|
9152
9335
|
if (isAnyRowEditing) {
|
|
@@ -9424,6 +9607,22 @@ const TableWidget = ({ config }) => {
|
|
|
9424
9607
|
box-shadow: 0 0 0 1px var(--owt-widget-input-focus-border, #F07B1A);
|
|
9425
9608
|
border-color: var(--owt-widget-input-focus-border, #F07B1A);
|
|
9426
9609
|
}
|
|
9610
|
+
|
|
9611
|
+
/* Keep inputs and action buttons top-aligned when a cell shows validation text */
|
|
9612
|
+
.${tableWidgetId} tr.table-row-editing td {
|
|
9613
|
+
vertical-align: top;
|
|
9614
|
+
}
|
|
9615
|
+
|
|
9616
|
+
.${tableWidgetId} .table-cell-field-error {
|
|
9617
|
+
min-height: 1.125rem;
|
|
9618
|
+
}
|
|
9619
|
+
|
|
9620
|
+
.${tableWidgetId} .table-cell-actions {
|
|
9621
|
+
display: flex;
|
|
9622
|
+
flex-direction: row;
|
|
9623
|
+
gap: 0.5rem;
|
|
9624
|
+
align-items: flex-start;
|
|
9625
|
+
}
|
|
9427
9626
|
` }), jsxRuntimeExports.jsxs("div", { className: `table-widget-container ${tableWidgetId}`, children: [confirmationState?.show && (jsxRuntimeExports.jsx("div", { className: "fixed inset-0 flex items-center justify-center z-50", style: { backgroundColor: 'rgba(0,0,0,0.5)' }, children: jsxRuntimeExports.jsxs("div", { className: "rounded-lg p-6 max-w-md w-full mx-4", style: { backgroundColor: 'var(--owt-color-bg, #FFFFFF)' }, children: [jsxRuntimeExports.jsx("h3", { className: "text-lg font-semibold mb-4", style: { color: 'var(--owt-color-text, #011627)' }, children: translate('table.confirm') || 'Confirm Action' }), jsxRuntimeExports.jsx("p", { className: "mb-6", style: { color: 'var(--owt-color-text, #011627)' }, children: confirmationState.message }), jsxRuntimeExports.jsxs("div", { className: "flex justify-end gap-3", children: [jsxRuntimeExports.jsx("button", { onClick: confirmationState.onCancel, className: "px-4 py-2 text-sm font-medium", style: {
|
|
9428
9627
|
borderRadius: 'var(--owt-btn-border-radius, 10px)',
|
|
9429
9628
|
border: '1px solid var(--owt-btn-secondary-border, #C4C4C4)',
|
|
@@ -9442,7 +9641,7 @@ const TableWidget = ({ config }) => {
|
|
|
9442
9641
|
}, children: translate('table.addRecord') || 'Add New Record' }) })), jsxRuntimeExports.jsx("div", { className: "overflow-x-auto border", style: { borderRadius: 'var(--owt-widget-table-border-radius, 15px)', borderColor: 'var(--owt-widget-table-border-color, #C4C4C4)' }, children: jsxRuntimeExports.jsxs("table", { className: "min-w-full", style: { borderCollapse: 'separate', borderSpacing: 0 }, children: [jsxRuntimeExports.jsx("thead", { style: { backgroundColor: 'var(--owt-widget-table-header-bg, #F6F6F6)' }, children: jsxRuntimeExports.jsxs("tr", { style: { borderBottom: '1px solid var(--owt-widget-table-row-divider, #E4E4E4)' }, children: [columns.map((col) => (jsxRuntimeExports.jsx("th", { className: "px-4 py-3 text-left text-xs font-medium uppercase tracking-wider", style: { color: 'var(--owt-widget-table-header-color, #727474)' }, children: translateConfig(col['widget-label']) }, col['column-key']))), ((operations.edit || operations.remove) && !isReadonly) || isAnyRowEditing || isSectionEditMode ? (jsxRuntimeExports.jsx("th", { className: "px-4 py-3 text-left text-xs font-medium uppercase tracking-wider", style: { color: 'var(--owt-widget-table-header-color, #727474)' }, children: translate('common.actions') || 'Actions' })) : null] }) }), jsxRuntimeExports.jsxs("tbody", { style: { backgroundColor: 'var(--owt-widget-table-body-bg, #FFFFFF)' }, children: [rows.length === 0 && !isAdding && (jsxRuntimeExports.jsx("tr", { children: jsxRuntimeExports.jsxs("td", { colSpan: columns.length + (((operations.edit || operations.remove) && !isReadonly) || isSectionEditMode ? 1 : 0), className: "px-4 py-6 text-center text-sm", style: { color: 'var(--owt-widget-table-empty-color, #727474)' }, children: [translate('table.noData') || 'No records available.', operations.add && !isReadonly && ` ${translate('table.clickToAdd') || 'Click "Add New Record" to add one.'}`] }) })), rows.map((row, rowIndex) => {
|
|
9443
9642
|
const isEditing = isRowEditing(rowIndex);
|
|
9444
9643
|
const isLoading = loadingRowIndex === rowIndex;
|
|
9445
|
-
return (jsxRuntimeExports.jsxs("tr", { className: isLoading ? 'opacity-50' : ''
|
|
9644
|
+
return (jsxRuntimeExports.jsxs("tr", { className: `${isLoading ? 'opacity-50' : ''}${isEditing ? ' table-row-editing' : ''}`, style: {
|
|
9446
9645
|
borderBottom: '1px solid var(--owt-widget-table-row-divider, #E4E4E4)',
|
|
9447
9646
|
backgroundColor: isEditing
|
|
9448
9647
|
? 'var(--owt-widget-table-editing-row-bg, #FBE6AA)'
|
|
@@ -9453,7 +9652,7 @@ const TableWidget = ({ config }) => {
|
|
|
9453
9652
|
return (jsxRuntimeExports.jsx("td", { className: "px-4 py-3 whitespace-nowrap", children: renderCell(rowIndex, col, row) }, col['column-key']));
|
|
9454
9653
|
}), ((operations.edit || operations.remove) && !isReadonly) || isEditing || isSectionEditMode ? (jsxRuntimeExports.jsx("td", { className: "px-4 py-3 whitespace-nowrap", style: { minWidth: '120px' }, children: isEditing ? (
|
|
9455
9654
|
// Show OK (Save)/Cancel buttons when row is being edited (works in both section edit mode and normal mode)
|
|
9456
|
-
jsxRuntimeExports.jsxs("div", { className: "
|
|
9655
|
+
jsxRuntimeExports.jsxs("div", { className: "table-cell-actions", style: { width: '100%' }, children: [jsxRuntimeExports.jsx("button", { type: "button", onClick: saveEdit, disabled: isLoading || !canSaveEditingRow, className: "px-3 py-1 text-xs font-medium disabled:opacity-50 disabled:cursor-not-allowed whitespace-nowrap flex-shrink-0", style: {
|
|
9457
9656
|
display: 'inline-block',
|
|
9458
9657
|
minWidth: '60px',
|
|
9459
9658
|
backgroundColor: 'var(--owt-color-success, #16A34A)',
|
|
@@ -9480,7 +9679,7 @@ const TableWidget = ({ config }) => {
|
|
|
9480
9679
|
backgroundColor: 'transparent',
|
|
9481
9680
|
border: 'none',
|
|
9482
9681
|
}, children: translate('common.remove') || 'Delete' }))] })) })) : null] }, rowIndex));
|
|
9483
|
-
}), isAdding && newRowData && (jsxRuntimeExports.jsxs("tr", { style: { backgroundColor: 'var(--owt-widget-table-editing-row-bg, #FBE6AA)' }, children: [columns.map((col) => (jsxRuntimeExports.jsx("td", { className: "px-4 py-3 whitespace-nowrap", children: renderCell(rows.length, col, { ...newRowData, edit_action: 'ADD' }) }, col['column-key']))), jsxRuntimeExports.jsx("td", { className: "px-4 py-3 whitespace-nowrap", children: jsxRuntimeExports.jsxs("div", { className: "
|
|
9682
|
+
}), isAdding && newRowData && (jsxRuntimeExports.jsxs("tr", { className: "table-row-editing", style: { backgroundColor: 'var(--owt-widget-table-editing-row-bg, #FBE6AA)' }, children: [columns.map((col) => (jsxRuntimeExports.jsx("td", { className: "px-4 py-3 whitespace-nowrap", children: renderCell(rows.length, col, { ...newRowData, edit_action: 'ADD' }) }, col['column-key']))), jsxRuntimeExports.jsx("td", { className: "px-4 py-3 whitespace-nowrap", children: jsxRuntimeExports.jsxs("div", { className: "table-cell-actions", children: [jsxRuntimeExports.jsx("button", { type: "button", onClick: saveAdd, disabled: loadingRowIndex === -1 || !canSaveNewRow, className: "px-3 py-1 text-xs disabled:opacity-50 disabled:cursor-not-allowed", style: {
|
|
9484
9683
|
borderRadius: 'var(--owt-btn-border-radius, 10px)',
|
|
9485
9684
|
backgroundColor: 'var(--owt-color-success, #16A34A)',
|
|
9486
9685
|
color: 'var(--owt-color-bg, #FFFFFF)',
|
|
@@ -11778,6 +11977,7 @@ exports.DateTimeInputWidget = DateTimeInputWidget;
|
|
|
11778
11977
|
exports.DialogTableWidget = DialogTableWidget;
|
|
11779
11978
|
exports.DisplayWidget = DisplayWidget;
|
|
11780
11979
|
exports.FileInputWidget = FileInputWidget;
|
|
11980
|
+
exports.GEO_LEVEL_CLEARED = GEO_LEVEL_CLEARED;
|
|
11781
11981
|
exports.HeaderSectionWidget = HeaderSectionWidget;
|
|
11782
11982
|
exports.IdAuthenticationWidget = IdAuthenticationWidget;
|
|
11783
11983
|
exports.IterableAccordionWidget = IterableAccordionWidget;
|
|
@@ -11805,6 +12005,7 @@ exports.WidgetRenderer = WidgetRenderer;
|
|
|
11805
12005
|
exports.applyCaseControl = applyCaseControl;
|
|
11806
12006
|
exports.applyDecimalPrecision = applyDecimalPrecision;
|
|
11807
12007
|
exports.applyMask = applyMask;
|
|
12008
|
+
exports.applySharedGeoHierarchyToValues = applySharedGeoHierarchyToValues;
|
|
11808
12009
|
exports.createWidgetStore = createWidgetStore;
|
|
11809
12010
|
exports.createZodSchema = createZodSchema;
|
|
11810
12011
|
exports.defaultTheme = defaultTheme;
|
|
@@ -11824,14 +12025,20 @@ exports.getValueByPath = getValueByPath;
|
|
|
11824
12025
|
exports.getWidgetValue = getWidgetValue;
|
|
11825
12026
|
exports.initI18n = initI18n;
|
|
11826
12027
|
exports.isAllowedKey = isAllowedKey;
|
|
12028
|
+
exports.isUpstreamGeoAncestor = isUpstreamGeoAncestor;
|
|
11827
12029
|
exports.normalizeNumericDefault = normalizeNumericDefault;
|
|
11828
12030
|
exports.parseDataPath = parseDataPath;
|
|
11829
12031
|
exports.parseNumber = parseNumber;
|
|
11830
12032
|
exports.registerDefaultWidgets = registerDefaultWidgets;
|
|
12033
|
+
exports.registerGeoWidgetParent = registerGeoWidgetParent;
|
|
11831
12034
|
exports.removeMask = removeMask;
|
|
11832
12035
|
exports.resetAll = resetAll;
|
|
12036
|
+
exports.resetAndSeedGeoHierarchyFromValues = resetAndSeedGeoHierarchyFromValues;
|
|
11833
12037
|
exports.resetWidget = resetWidget;
|
|
12038
|
+
exports.resolveGeoWidgetLevelValue = resolveGeoWidgetLevelValue;
|
|
11834
12039
|
exports.resolveTheme = resolveTheme;
|
|
12040
|
+
exports.resolveWidgetIdValue = resolveWidgetIdValue;
|
|
12041
|
+
exports.seedGeoHierarchyFromValues = seedGeoHierarchyFromValues;
|
|
11835
12042
|
exports.setDataSource = setDataSource;
|
|
11836
12043
|
exports.setError = setError;
|
|
11837
12044
|
exports.setLoading = setLoading;
|
|
@@ -11846,6 +12053,7 @@ exports.transformDataSourceOptions = transformDataSourceOptions;
|
|
|
11846
12053
|
exports.translatePanelConfig = translatePanelConfig;
|
|
11847
12054
|
exports.translateUISchema = translateUISchema;
|
|
11848
12055
|
exports.translateWidgetConfig = translateWidgetConfig;
|
|
12056
|
+
exports.unregisterGeoWidgetParent = unregisterGeoWidgetParent;
|
|
11849
12057
|
exports.useBaseWidget = useBaseWidget;
|
|
11850
12058
|
exports.useGeoWidgetCascade = useGeoWidgetCascade;
|
|
11851
12059
|
exports.useWidgetCascade = useWidgetCascade;
|