@vizzly/dashboard 0.15.0-dev-8a72201c3d82e791bf61245fda865c4ef9852097 → 0.15.0-dev-24c4b893399beb435b745863f889e25bec999e60

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.
@@ -2,8 +2,8 @@ import React__default, { Fragment, useEffect, useState, useContext, createContex
2
2
  import isEmpty$3 from 'lodash-es/isEmpty';
3
3
  import _, { isArray, capitalize, isEmpty as isEmpty$2, isFunction, replace, isObject, isNumber, every, some, mergeWith, remove as remove$2, cloneDeep, findIndex, reduce, merge, sumBy, mapValues, zipObject, isDate, omit as omit$1, maxBy, reject, defaultsDeep, isString, flatMap, filter, uniq, uniqBy, debounce as debounce$1, orderBy, minBy, throttle, get as get$1, min, max, groupBy, isEqual, intersection } from 'lodash-es';
4
4
  import { QueryEngineConfig } from '@vizzly/semantic-layer-public';
5
- import Joi from '@vizzly/joi';
6
5
  import moment from 'moment-timezone';
6
+ import Joi from '@vizzly/joi';
7
7
  import { v4 } from 'uuid';
8
8
  import { Global, css as css$2, CacheProvider, createElement as createElement$1 } from '@emotion/react';
9
9
  import { jsx, jsxs, Fragment as Fragment$1 } from '@emotion/react/jsx-runtime';
@@ -1203,6 +1203,35 @@ function extractValue(variables, key) {
1203
1203
  return variables[key].value;
1204
1204
  }
1205
1205
 
1206
+ var getUTCDate = function getUTCDate(date) {
1207
+ if (date !== null) {
1208
+ var momentDate = moment(new Date(date));
1209
+ return momentDate.tz(Intl.DateTimeFormat().resolvedOptions().timeZone)._d;
1210
+ }
1211
+ return date;
1212
+ };
1213
+
1214
+ var filterIsDate = function filterIsDate(filter) {
1215
+ var isoDateRegex = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z$/;
1216
+ if (!isoDateRegex.test(filter.value)) {
1217
+ return false;
1218
+ }
1219
+ var date = new Date(filter.value);
1220
+ if (isNaN(date.getTime())) {
1221
+ return false;
1222
+ }
1223
+
1224
+ // Additional check to verify that the date parts match exactly
1225
+ var _filter$value$split$ = filter.value.split('T')[0].split('-').map(Number),
1226
+ year = _filter$value$split$[0],
1227
+ month = _filter$value$split$[1],
1228
+ day = _filter$value$split$[2];
1229
+ if (date.getUTCFullYear() !== year || date.getUTCMonth() + 1 !== month || date.getUTCDate() !== day) {
1230
+ return false;
1231
+ }
1232
+ return true;
1233
+ };
1234
+
1206
1235
  var _Joi$string, _Joi$string2;
1207
1236
  var defaultDurationOptions = function defaultDurationOptions(textOverride) {
1208
1237
  return {
@@ -1315,6 +1344,175 @@ var buildRelativeRange = function buildRelativeRange(relativeFilters, dataSet, a
1315
1344
  });
1316
1345
  };
1317
1346
 
1347
+ var addAndFilters = function addAndFilters(filter, filterToAddToAll) {
1348
+ if (isEmpty$2(filterToAddToAll)) return [].concat(filter);
1349
+ if (!filter || isEmpty$2(filter)) filter = [[]];
1350
+ var result = [];
1351
+ for (var _iterator = _createForOfIteratorHelperLoose(filterToAddToAll), _step; !(_step = _iterator()).done;) {
1352
+ var additionalAndFilter = _step.value;
1353
+ for (var _iterator2 = _createForOfIteratorHelperLoose(filter), _step2; !(_step2 = _iterator2()).done;) {
1354
+ var andFilter = _step2.value;
1355
+ var combined = [].concat(additionalAndFilter, andFilter);
1356
+ if (!isEmpty$2(combined)) {
1357
+ result.push(combined);
1358
+ }
1359
+ }
1360
+ }
1361
+ return result;
1362
+ };
1363
+ var convertSingleFilterToRecursiveFilter = function convertSingleFilterToRecursiveFilter(filter, variables) {
1364
+ var field = {
1365
+ type: 'field',
1366
+ value: filter.field,
1367
+ "function": filter["function"] || 'none'
1368
+ };
1369
+ if ((filter.op === 'array_contains' || filter.op === 'array_does_not_contain') && Array.isArray(filter.value)) {
1370
+ return {
1371
+ type: 'andWhere',
1372
+ value: filter.value.map(function (value) {
1373
+ return {
1374
+ type: 'where',
1375
+ value: {
1376
+ field: field,
1377
+ op: filter.op,
1378
+ value: value
1379
+ }
1380
+ };
1381
+ })
1382
+ };
1383
+ }
1384
+ var value = useValue(filter.value, variables);
1385
+ if (isRelativeDateDefined(filter.value)) {
1386
+ value = calculateRelativeDate(filter.value);
1387
+ }
1388
+ if (filterIsDate(filter)) {
1389
+ value = getUTCDate(filter.value);
1390
+ }
1391
+ return {
1392
+ type: 'where',
1393
+ value: {
1394
+ field: field,
1395
+ op: filter.op,
1396
+ value: value
1397
+ }
1398
+ };
1399
+ };
1400
+ var convertArrayFilterStructureToQueryFilter = function convertArrayFilterStructureToQueryFilter(arrayFilterStructure, variables) {
1401
+ if (!Array.isArray(arrayFilterStructure)) {
1402
+ return arrayFilterStructure;
1403
+ }
1404
+ if (arrayFilterStructure.length === 0 || arrayFilterStructure.every(function (andFilters) {
1405
+ return andFilters.length === 0;
1406
+ })) {
1407
+ return {
1408
+ type: 'andWhere',
1409
+ value: []
1410
+ };
1411
+ }
1412
+ var convertedAndGroups = arrayFilterStructure.filter(function (andFilters) {
1413
+ return andFilters.length > 0;
1414
+ }).map(function (andFilters) {
1415
+ return {
1416
+ type: 'andWhere',
1417
+ value: andFilters.map(function (filter) {
1418
+ return convertSingleFilterToRecursiveFilter(filter, variables);
1419
+ })
1420
+ };
1421
+ });
1422
+ if (convertedAndGroups.length === 1) {
1423
+ return convertedAndGroups[0];
1424
+ }
1425
+ return {
1426
+ type: 'orWhere',
1427
+ value: convertedAndGroups
1428
+ };
1429
+ };
1430
+ var combineQueryFilters = function combineQueryFilters(filter, filterToAddToAll) {
1431
+ if (Array.isArray(filter.value) && filter.value.length === 0) {
1432
+ return filterToAddToAll;
1433
+ }
1434
+ if (Array.isArray(filterToAddToAll.value) && filterToAddToAll.value.length === 0) {
1435
+ return filter;
1436
+ }
1437
+ return {
1438
+ type: 'andWhere',
1439
+ value: [filter, filterToAddToAll]
1440
+ };
1441
+ };
1442
+
1443
+ /**
1444
+ * Iterates through a query filter and, for each custom metric field, builds a custom metric.
1445
+ */
1446
+ function buildQueryCustomMetrics(filter, dataSet, queryEngineConfig, params) {
1447
+ if (filter.type === 'where') {
1448
+ var field = getFieldFromFilter(filter);
1449
+ if (!field) return filter;
1450
+ var dataSetField = findField(dataSet, field.value);
1451
+ var fieldFunction = 'function' in field && !!field["function"] ? field["function"] : 'none';
1452
+ if (isCustomField(dataSetField)) {
1453
+ var customField = toQueryMeasure({
1454
+ field: dataSetField.id,
1455
+ "function": fieldFunction
1456
+ }, dataSetField, queryEngineConfig, dataSet, false, params);
1457
+ return {
1458
+ type: 'where',
1459
+ value: {
1460
+ field: customField,
1461
+ op: filter.value.op,
1462
+ value: filter.value.value
1463
+ }
1464
+ };
1465
+ }
1466
+ return filter;
1467
+ }
1468
+ if (filter.type === 'andWhere' || filter.type === 'orWhere') {
1469
+ var processedValues = filter.value.map(function (f) {
1470
+ return buildQueryCustomMetrics(f, dataSet, queryEngineConfig, params);
1471
+ });
1472
+ return {
1473
+ type: filter.type,
1474
+ value: processedValues
1475
+ };
1476
+ }
1477
+ return filter;
1478
+ }
1479
+ function getFieldFromFilter(filter) {
1480
+ if (filter.type === 'where') {
1481
+ if ('value' in filter.value.field && typeof filter.value.field.value === 'string') {
1482
+ return filter.value.field;
1483
+ }
1484
+ }
1485
+ return null;
1486
+ }
1487
+ var isAvailable = function isAvailable(filter) {
1488
+ return filter && isArray(filter) && isArray(filter[0]);
1489
+ };
1490
+ var isAdditionalFilter = function isAdditionalFilter(value) {
1491
+ return value && isArray(value) && isArray(value[0]) && 'field' in value[0][0] && 'op' in value[0][0] && 'value' in value[0][0];
1492
+ };
1493
+
1494
+ var combineFilters = function combineFilters(array1, array2) {
1495
+ var validArray1 = array1.length > 0 && array1[0] ? array1 : [[]];
1496
+ var validArray2 = array2.length > 0 && array2[0] ? array2 : [[]];
1497
+
1498
+ // If array1 has more than one sub-array, loop through each sub-array in array1
1499
+ if (validArray1.length > 1) {
1500
+ return validArray1.map(function (subArray) {
1501
+ return [].concat(validArray2[0] || [], subArray || []);
1502
+ });
1503
+ }
1504
+ // Otherwise, if array2 has more than one sub-array, loop through array2
1505
+ else if (validArray2.length > 1) {
1506
+ return validArray2.map(function (subArray) {
1507
+ return [].concat(validArray1[0] || [], subArray || []);
1508
+ });
1509
+ }
1510
+ // Default: merge both single sub-arrays
1511
+ else {
1512
+ return [[].concat(validArray1[0] || [], validArray2[0] || [])];
1513
+ }
1514
+ };
1515
+
1318
1516
  /** Upcasts from an old global filter, to a new "additional filter" */
1319
1517
  var upcastToAdditionalFilter = function upcastToAdditionalFilter(globalFilter) {
1320
1518
  if (globalFilter.type == 'globalSelectFilter') {
@@ -1366,105 +1564,6 @@ var MULTI_SELECT_FILTER = 'multiSelectFilter';
1366
1564
  var NUMERIC_FILTER = 'numericFilter';
1367
1565
  var ADVANCED_FILTER = 'advancedFilter';
1368
1566
 
1369
- var getUTCDate = function getUTCDate(date) {
1370
- if (date !== null) {
1371
- var momentDate = moment(new Date(date));
1372
- return momentDate.tz(Intl.DateTimeFormat().resolvedOptions().timeZone)._d;
1373
- }
1374
- return date;
1375
- };
1376
-
1377
- var toQueryAttributesFilter = function toQueryAttributesFilter(dataSet, filter, customTimeRangeFuncs) {
1378
- return filter.appliesToFields.flatMap(function (field) {
1379
- var _filter$value, _filter$value2, _filter$value3;
1380
- if (field.dataSetId != dataSet.id) return [];
1381
- if (filter.value == null) return [];
1382
- var dataSetField = findField(dataSet, field.fieldId);
1383
-
1384
- // might be able to remove this
1385
- if (dataSetField.dataType == 'string[]' && filter.type !== MULTI_SELECT_FILTER && !isAdditionalFilter(filter.value)) {
1386
- return [[{
1387
- field: field.fieldId,
1388
- op: 'array_contains',
1389
- value: filter.value
1390
- }]];
1391
- }
1392
- if ((filter.type == DATE_FILTER || filter.type == DATE_AND_TIME_FILTER) && ((_filter$value = filter.value) == null ? void 0 : _filter$value.type) == 'relativeRange') {
1393
- return [];
1394
- }
1395
- if ((filter.type == DATE_FILTER || filter.type == DATE_AND_TIME_FILTER) && ((_filter$value2 = filter.value) == null ? void 0 : _filter$value2.type) == 'fixedRange') {
1396
- // We have a fixed time range, so we can use those values.
1397
-
1398
- return [[{
1399
- field: field.fieldId,
1400
- op: inclusiveExclusiveCurrent(DateOp.Greater, filter),
1401
- value: getUTCDate(filter.value.after)
1402
- }, {
1403
- field: field.fieldId,
1404
- op: inclusiveExclusiveCurrent(DateOp.Less, filter),
1405
- value: getUTCDate(filter.value.before)
1406
- }]];
1407
- } else if ((filter.type == DATE_FILTER || filter.type == DATE_AND_TIME_FILTER) && ((_filter$value3 = filter.value) == null ? void 0 : _filter$value3.type) == 'relative') {
1408
- // We have a relative time filter, so need to call the time functions to get the values....
1409
-
1410
- var _customTimeRangeFuncs = customTimeRangeFuncs[filter.value.value].range,
1411
- before = _customTimeRangeFuncs.before,
1412
- after = _customTimeRangeFuncs.after;
1413
- var filters = [[]];
1414
- if (before) {
1415
- filters = filters.map(function (f) {
1416
- return [].concat(f, [{
1417
- field: field.fieldId,
1418
- op: inclusiveExclusiveCurrent(DateOp.Less, filter),
1419
- value: before
1420
- }]);
1421
- });
1422
- }
1423
- if (after) {
1424
- filters = filters.map(function (f) {
1425
- return [].concat(f, [{
1426
- field: field.fieldId,
1427
- op: inclusiveExclusiveCurrent(DateOp.Greater, filter),
1428
- value: after
1429
- }]);
1430
- });
1431
- }
1432
- return filters;
1433
- } else if (filter.type == SINGLE_SELECT_FILTER) {
1434
- var value = filter.value;
1435
- if (filter.value === NULL_VALUE_OPT) {
1436
- value = null;
1437
- }
1438
- return [[{
1439
- field: field.fieldId,
1440
- op: '=',
1441
- value: value
1442
- }]];
1443
- } else if (isAdditionalFilter(filter.value)) {
1444
- return buildAdvancedFilters(filter.value, field, dataSet.id);
1445
- } else if (filter.type == MULTI_SELECT_FILTER && filter.value.length > 0) {
1446
- return [[{
1447
- field: field.fieldId,
1448
- op: 'is_one_of',
1449
- value: filter.value
1450
- }]];
1451
- } else if (filter.type == DATE_FILTER && !filter.value || filter.type == DATE_AND_TIME_FILTER && !filter.value || filter.type == MULTI_SELECT_FILTER && filter.value.length === 0) {
1452
- // No value set on the filter, so it cannot become a query attribute.
1453
- return [];
1454
- } else if (filter.type == NUMERIC_FILTER) {
1455
- if ('op' in filter.value && 'value' in filter.value) {
1456
- return [[{
1457
- field: field.fieldId,
1458
- op: filter.value.op,
1459
- value: filter.value.value
1460
- }]];
1461
- }
1462
- return [[]];
1463
- }
1464
- throw "Cannot convert filter type " + filter.type + " to query attributes filter. " + JSON.stringify(filter);
1465
- });
1466
- };
1467
-
1468
1567
  var typeToString = function typeToString(type, textOverride) {
1469
1568
  if (type == DATE_FILTER) return textOverride('date_filter', 'Date filter');
1470
1569
  if (type == DATE_AND_TIME_FILTER) return textOverride('date_time_filter', 'Date Time filter');
@@ -1667,31 +1766,48 @@ function inclusiveExclusiveCurrent(op, filter) {
1667
1766
  throw new Error('Unknown date operation');
1668
1767
  }
1669
1768
  }
1670
- function getCascadeOptionsFilters(globalFilters, dataSets, dateFilterOptions, cascadeFilterSelection) {
1769
+ function getCascadeOptionsFilters(globalFilters, dataSets, dateFilterOptions, variables, cascadeFilterSelection) {
1671
1770
  if (!cascadeFilterSelection) return undefined;
1672
- var result = globalFilters.reduce(function (acc, dataObj) {
1673
- if (dataObj.value !== null) {
1674
- if (Array.isArray(dataObj.value) && dataObj.value.length === 0) {
1675
- return acc;
1771
+ var dataSetMap = new Map(dataSets.map(function (ds) {
1772
+ return [ds.id, ds];
1773
+ }));
1774
+ var filtersByDataSet = globalFilters.reduce(function (acc, filter) {
1775
+ if (!hasValidFilterValue(filter.value)) {
1776
+ return acc;
1777
+ }
1778
+ var uniqueDataSetIds = new Set(filter.appliesToFields.map(function (f) {
1779
+ return f.dataSetId;
1780
+ }));
1781
+ for (var _iterator = _createForOfIteratorHelperLoose(uniqueDataSetIds), _step; !(_step = _iterator()).done;) {
1782
+ var dataSetId = _step.value;
1783
+ var dataSet = dataSetMap.get(dataSetId);
1784
+ if (!dataSet) continue;
1785
+ if (!acc[dataSetId]) {
1786
+ acc[dataSetId] = [];
1676
1787
  }
1677
- var uniqueDataSetIds = new Set(dataObj.appliesToFields.map(function (f) {
1678
- return f.dataSetId;
1679
- }));
1680
- uniqueDataSetIds.forEach(function (dataSetId) {
1681
- var dataSet = find(dataSets, dataSetId);
1682
- if (!acc[dataSetId]) {
1683
- acc[dataSetId] = [];
1684
- }
1685
- if (dataSet !== null) {
1686
- var filters = toQueryAttributesFilter(dataSet, dataObj, dateFilterOptions);
1687
- acc[dataSetId] = addAndFilters(acc[dataSetId], filters);
1688
- }
1689
- });
1788
+ var queryFilters = processAdditionalFilter(filter, dataSet, dateFilterOptions, variables);
1789
+ acc[dataSetId].push(queryFilters);
1790
+ }
1791
+ return acc;
1792
+ }, {});
1793
+ var result = Object.entries(filtersByDataSet).reduce(function (acc, _ref2) {
1794
+ var dataSetId = _ref2[0],
1795
+ filters = _ref2[1];
1796
+ if (filters.length > 0) {
1797
+ acc[dataSetId] = {
1798
+ type: 'andWhere',
1799
+ value: filters
1800
+ };
1690
1801
  }
1691
1802
  return acc;
1692
1803
  }, {});
1693
1804
  return Object.keys(result).length === 0 ? undefined : result;
1694
1805
  }
1806
+ function hasValidFilterValue(value) {
1807
+ if (value === null || value === undefined) return false;
1808
+ if (Array.isArray(value) && value.length === 0) return false;
1809
+ return true;
1810
+ }
1695
1811
  var updateFilterForOptionalPulledFromOptions = function updateFilterForOptionalPulledFromOptions(filter) {
1696
1812
  if (!('optionsPulledFrom' in filter)) return filter;
1697
1813
  if (!filter.optionsPulledFrom || filter.optionsPulledFrom.length === 0) {
@@ -1746,168 +1862,182 @@ function getFilterDataType(filter, dataSets) {
1746
1862
  return findField(dataSet, filter.appliesToFields[0].fieldId).dataType;
1747
1863
  }
1748
1864
 
1749
- var fromFilterConfig = function fromFilterConfig(filterConfig, dataSet, timeRangeOptions) {
1750
- var filters = [];
1751
- (filterConfig.globalFilters || []).forEach(function (additionalFilter) {
1752
- var addFilter = [];
1753
- if (additionalFilter.type === DATE_AND_TIME_FILTER || additionalFilter.type === DATE_FILTER) {
1754
- addFilter = toRelativeQueryAttributesFilters(additionalFilter, dataSet);
1865
+ var toQueryAttributesFilter = function toQueryAttributesFilter(dataSet, filter, customTimeRangeFuncs) {
1866
+ return filter.appliesToFields.flatMap(function (field) {
1867
+ var _filter$value, _filter$value2, _filter$value3;
1868
+ if (field.dataSetId != dataSet.id) return [];
1869
+ if (filter.value == null) return [];
1870
+ var dataSetField = findField(dataSet, field.fieldId);
1871
+
1872
+ // might be able to remove this
1873
+ if (dataSetField.dataType == 'string[]' && filter.type !== MULTI_SELECT_FILTER && !isAdditionalFilter(filter.value)) {
1874
+ return [[{
1875
+ field: field.fieldId,
1876
+ op: 'array_contains',
1877
+ value: filter.value
1878
+ }]];
1755
1879
  }
1756
- filters = addAndFilters(filters, addFilter);
1757
- filters = addAndFilters(filters, toQueryAttributesFilter(dataSet, additionalFilter, timeRangeOptions));
1758
- });
1759
- var localAdditionalFilters = Object.values(filterConfig.localFilters || {}).flat();
1760
- localAdditionalFilters.forEach(function (additionalFilter) {
1761
- var addFilter = [];
1762
- if (additionalFilter.type === DATE_AND_TIME_FILTER || additionalFilter.type === DATE_FILTER) {
1763
- addFilter = toRelativeQueryAttributesFilters(additionalFilter, dataSet);
1880
+ if ((filter.type == DATE_FILTER || filter.type == DATE_AND_TIME_FILTER) && ((_filter$value = filter.value) == null ? void 0 : _filter$value.type) == 'relativeRange') {
1881
+ return [];
1764
1882
  }
1765
- filters = addAndFilters(filters, addFilter);
1766
- filters = addAndFilters(filters, toQueryAttributesFilter(dataSet, additionalFilter, timeRangeOptions));
1767
- });
1768
- return filters;
1769
- };
1770
-
1771
- var filterIsDate = function filterIsDate(filter) {
1772
- var isoDateRegex = /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z$/;
1773
- if (!isoDateRegex.test(filter.value)) {
1774
- return false;
1775
- }
1776
- var date = new Date(filter.value);
1777
- if (isNaN(date.getTime())) {
1778
- return false;
1779
- }
1883
+ if ((filter.type == DATE_FILTER || filter.type == DATE_AND_TIME_FILTER) && ((_filter$value2 = filter.value) == null ? void 0 : _filter$value2.type) == 'fixedRange') {
1884
+ // We have a fixed time range, so we can use those values.
1780
1885
 
1781
- // Additional check to verify that the date parts match exactly
1782
- var _filter$value$split$ = filter.value.split('T')[0].split('-').map(Number),
1783
- year = _filter$value$split$[0],
1784
- month = _filter$value$split$[1],
1785
- day = _filter$value$split$[2];
1786
- if (date.getUTCFullYear() !== year || date.getUTCMonth() + 1 !== month || date.getUTCDate() !== day) {
1787
- return false;
1788
- }
1789
- return true;
1790
- };
1886
+ return [[{
1887
+ field: field.fieldId,
1888
+ op: inclusiveExclusiveCurrent(DateOp.Greater, filter),
1889
+ value: getUTCDate(filter.value.after)
1890
+ }, {
1891
+ field: field.fieldId,
1892
+ op: inclusiveExclusiveCurrent(DateOp.Less, filter),
1893
+ value: getUTCDate(filter.value.before)
1894
+ }]];
1895
+ } else if ((filter.type == DATE_FILTER || filter.type == DATE_AND_TIME_FILTER) && ((_filter$value3 = filter.value) == null ? void 0 : _filter$value3.type) == 'relative') {
1896
+ // We have a relative time filter, so need to call the time functions to get the values....
1791
1897
 
1792
- var addAndFilters = function addAndFilters(filter, filterToAddToAll) {
1793
- if (isEmpty$2(filterToAddToAll)) return [].concat(filter);
1794
- if (!filter || isEmpty$2(filter)) filter = [[]];
1795
- var result = [];
1796
- for (var _iterator = _createForOfIteratorHelperLoose(filterToAddToAll), _step; !(_step = _iterator()).done;) {
1797
- var additionalAndFilter = _step.value;
1798
- for (var _iterator2 = _createForOfIteratorHelperLoose(filter), _step2; !(_step2 = _iterator2()).done;) {
1799
- var andFilter = _step2.value;
1800
- var combined = [].concat(additionalAndFilter, andFilter);
1801
- if (!isEmpty$2(combined)) {
1802
- result.push(combined);
1898
+ var _customTimeRangeFuncs = customTimeRangeFuncs[filter.value.value].range,
1899
+ before = _customTimeRangeFuncs.before,
1900
+ after = _customTimeRangeFuncs.after;
1901
+ var filters = [[]];
1902
+ if (before) {
1903
+ filters = filters.map(function (f) {
1904
+ return [].concat(f, [{
1905
+ field: field.fieldId,
1906
+ op: inclusiveExclusiveCurrent(DateOp.Less, filter),
1907
+ value: before
1908
+ }]);
1909
+ });
1910
+ }
1911
+ if (after) {
1912
+ filters = filters.map(function (f) {
1913
+ return [].concat(f, [{
1914
+ field: field.fieldId,
1915
+ op: inclusiveExclusiveCurrent(DateOp.Greater, filter),
1916
+ value: after
1917
+ }]);
1918
+ });
1919
+ }
1920
+ return filters;
1921
+ } else if (filter.type == SINGLE_SELECT_FILTER) {
1922
+ var value = filter.value;
1923
+ if (filter.value === NULL_VALUE_OPT) {
1924
+ value = null;
1803
1925
  }
1926
+ return [[{
1927
+ field: field.fieldId,
1928
+ op: '=',
1929
+ value: value
1930
+ }]];
1931
+ } else if (isAdditionalFilter(filter.value)) {
1932
+ return buildAdvancedFilters(filter.value, field, dataSet.id);
1933
+ } else if (filter.type == MULTI_SELECT_FILTER && filter.value.length > 0) {
1934
+ return [[{
1935
+ field: field.fieldId,
1936
+ op: 'is_one_of',
1937
+ value: filter.value
1938
+ }]];
1939
+ } else if (filter.type == DATE_FILTER && !filter.value || filter.type == DATE_AND_TIME_FILTER && !filter.value || filter.type == MULTI_SELECT_FILTER && filter.value.length === 0) {
1940
+ // No value set on the filter, so it cannot become a query attribute.
1941
+ return [];
1942
+ } else if (filter.type == NUMERIC_FILTER) {
1943
+ if ('op' in filter.value && 'value' in filter.value) {
1944
+ return [[{
1945
+ field: field.fieldId,
1946
+ op: filter.value.op,
1947
+ value: filter.value.value
1948
+ }]];
1949
+ }
1950
+ return [[]];
1804
1951
  }
1805
- }
1806
- return result;
1952
+ throw "Cannot convert filter type " + filter.type + " to query attributes filter. " + JSON.stringify(filter);
1953
+ });
1807
1954
  };
1808
- var filterAttributeToQueryFilter = function filterAttributeToQueryFilter(filterAttrs, queryEngineConfig, dataSet, params) {
1809
- var _params$filterConfig;
1810
- // Either build using the filter attributes passed in, or take the viewFilters in the filter config.
1811
- // They represent the same thing, however some view-filters are passed around in the filter config
1812
- // to reduce custom metrics arguments being passed around.
1813
- var filter = filterAttrs.length > 0 && filterAttrs.some(function (group) {
1814
- return group.length > 0;
1815
- }) ? filterAttrs : ((_params$filterConfig = params.filterConfig) == null ? void 0 : _params$filterConfig.viewFilters) || [];
1816
- var extraFilters = fromFilterConfig(params.filterConfig, dataSet, params.timeRangeOptions);
1817
- var combinedFilters = addAndFilters(filter, extraFilters);
1818
- if (Array.isArray(filter)) {
1819
- return {
1820
- type: 'orWhere',
1821
- value: combinedFilters.map(function (andFilters) {
1822
- return {
1823
- type: 'andWhere',
1824
- value: andFilters.map(function (filter) {
1825
- var dataSetField = findField(dataSet, filter.field);
1826
- var field = {
1827
- type: 'field',
1828
- value: filter.field,
1829
- "function": filter["function"] || 'none'
1830
- };
1831
- if (isCustomField(dataSetField)) {
1832
- var _filter$function;
1833
- field = toQueryMeasure({
1834
- field: dataSetField.id,
1835
- "function": (_filter$function = filter["function"]) != null ? _filter$function : 'none'
1836
- }, dataSetField, queryEngineConfig, dataSet, false, params);
1837
- }
1838
1955
 
1839
- // If the value is an array, and we're checking that all values ARE or ARE NOT in a field, then we need to split
1840
- // out this check into multiple filters, as a value in a filter cannot be an array.
1841
- if ((filter.op == 'array_contains' || filter.op == 'array_does_not_contain') && Array.isArray(filter.value)) {
1842
- return {
1843
- type: 'andWhere',
1844
- value: [].concat(filter.value).map(function (value) {
1845
- return {
1846
- type: 'where',
1847
- value: {
1848
- field: field,
1849
- op: filter.op,
1850
- value: value
1851
- }
1852
- };
1853
- })
1854
- };
1855
- }
1856
- var value = useValue(filter.value, params.variables);
1857
- if (isRelativeDateDefined(filter.value)) {
1858
- value = calculateRelativeDate(filter.value);
1859
- }
1860
- if (filterIsDate(filter)) {
1861
- value = getUTCDate(filter.value);
1862
- }
1863
- return {
1864
- type: 'where',
1865
- value: {
1866
- field: field,
1867
- op: filter.op,
1868
- value: value
1869
- }
1870
- };
1871
- })
1872
- };
1873
- })
1956
+ var processAdditionalFilter = function processAdditionalFilter(filter, dataSet, timeRangeOptions, variables) {
1957
+ var queryAttributesFilter = toQueryAttributesFilter(dataSet, filter, timeRangeOptions);
1958
+ var convertedFilter = convertArrayFilterStructureToQueryFilter(queryAttributesFilter, variables);
1959
+ if (filter.type === DATE_AND_TIME_FILTER || filter.type === DATE_FILTER) {
1960
+ var relativeDateFilter = toRelativeQueryAttributesFilters(filter, dataSet);
1961
+ var convertedRelativeFilter = convertArrayFilterStructureToQueryFilter(relativeDateFilter, variables);
1962
+ return {
1963
+ type: 'andWhere',
1964
+ value: [convertedFilter, convertedRelativeFilter]
1874
1965
  };
1875
1966
  }
1876
- return filter;
1967
+ return convertedFilter;
1877
1968
  };
1878
- var isAvailable = function isAvailable(filter) {
1879
- return filter && isArray(filter) && isArray(filter[0]);
1880
- };
1881
- var isAdditionalFilter = function isAdditionalFilter(value) {
1882
- return value && isArray(value) && isArray(value[0]) && 'field' in value[0][0] && 'op' in value[0][0] && 'value' in value[0][0];
1883
- };
1884
-
1885
- var combineFilters = function combineFilters(array1, array2) {
1886
- var validArray1 = array1.length > 0 && array1[0] ? array1 : [[]];
1887
- var validArray2 = array2.length > 0 && array2[0] ? array2 : [[]];
1888
-
1889
- // If array1 has more than one sub-array, loop through each sub-array in array1
1890
- if (validArray1.length > 1) {
1891
- return validArray1.map(function (subArray) {
1892
- return [].concat(validArray2[0] || [], subArray || []);
1893
- });
1894
- }
1895
- // Otherwise, if array2 has more than one sub-array, loop through array2
1896
- else if (validArray2.length > 1) {
1897
- return validArray2.map(function (subArray) {
1898
- return [].concat(validArray1[0] || [], subArray || []);
1969
+ var isAdditionalFilterValid = function isAdditionalFilterValid(filter) {
1970
+ if (Array.isArray(filter.value)) {
1971
+ return filter.value.length > 0 && filter.value.some(function (item) {
1972
+ return !Array.isArray(item) || item.length > 0;
1899
1973
  });
1900
1974
  }
1901
- // Default: merge both single sub-arrays
1902
- else {
1903
- return [[].concat(validArray1[0] || [], validArray2[0] || [])];
1904
- }
1975
+ return Boolean(filter.value);
1976
+ };
1977
+
1978
+ /**
1979
+ * Combines different types of filters (global, local, and view filters) into a single Query filter structure.
1980
+ *
1981
+ * @param filterConfig - Configuration containing different filter types
1982
+ * @param dataSet - Dataset to validate filters against
1983
+ * @param timeRangeOptions - Time range configuration for date filters
1984
+ * @param variables - Variable list for template substitution
1985
+ * @returns Combined Query filter with proper AND/OR structure
1986
+ */
1987
+ var combineFiltersFromFilterConfig = function combineFiltersFromFilterConfig(filterConfig, dataSet, timeRangeOptions, variables) {
1988
+ var globalFilters = filterConfig.globalFilters || [];
1989
+ var processedGlobalFilters = globalFilters.filter(isAdditionalFilterValid).map(function (filter) {
1990
+ return processAdditionalFilter(filter, dataSet, timeRangeOptions, variables);
1991
+ });
1992
+ var localFilters = filterConfig.localFilters || [];
1993
+ var processedLocalFilters = localFilters.filter(isAdditionalFilterValid).map(function (filter) {
1994
+ return processAdditionalFilter(filter, dataSet, timeRangeOptions, variables);
1995
+ });
1996
+ var viewFilters = filterConfig.viewFilters ? filterConfig.viewFilters.filter(function (filter) {
1997
+ return filter.length > 0;
1998
+ }) : [];
1999
+ var processedViewFilters = convertArrayFilterStructureToQueryFilter(viewFilters, variables);
2000
+ var andFilters = [].concat(processedGlobalFilters, processedLocalFilters, [processedViewFilters]).filter(function (andFilter) {
2001
+ if (Array.isArray(andFilter.value)) {
2002
+ return andFilter.value.length > 0;
2003
+ }
2004
+ return true;
2005
+ });
2006
+ return {
2007
+ type: 'andWhere',
2008
+ value: andFilters
2009
+ };
1905
2010
  };
1906
2011
 
1907
2012
  var generateId = function generateId() {
1908
2013
  return v4().replace(/-/g, '');
1909
2014
  };
1910
2015
 
2016
+ var Clause = /*#__PURE__*/function (Clause) {
2017
+ Clause["AND_WHERE"] = "andWhere";
2018
+ Clause["OR_WHERE"] = "orWhere";
2019
+ Clause["WHERE"] = "where";
2020
+ return Clause;
2021
+ }({});
2022
+
2023
+ // export type WhereClause = SqlAST.MultiWhereToken<any>;
2024
+
2025
+ var DEFAULT_ALWAYS_FILTER_VALUE = 2;
2026
+ var alwaysTrueFilter = {
2027
+ type: Clause.AND_WHERE,
2028
+ value: [{
2029
+ type: Clause.WHERE,
2030
+ value: {
2031
+ field: {
2032
+ type: 'number',
2033
+ value: DEFAULT_ALWAYS_FILTER_VALUE
2034
+ },
2035
+ op: '=',
2036
+ value: DEFAULT_ALWAYS_FILTER_VALUE
2037
+ }
2038
+ }]
2039
+ };
2040
+
1911
2041
  /**
1912
2042
  * Creates a new custom percentage field.
1913
2043
  */
@@ -1932,10 +2062,15 @@ var init$1 = function init(publicName, denominatorFieldId, denominatorAggregate,
1932
2062
  };
1933
2063
  };
1934
2064
  var build$2 = function build(customField, queryEngineConfig, dataSet, _queryHasDimension, params) {
1935
- var _params$filterConfig$, _params$filterConfig, _customField$numerato, _customField$numerato2, _customField$denomina, _customField$denomina2;
1936
- var _buildPercentageFilte = buildPercentageFilters((_params$filterConfig$ = params == null || (_params$filterConfig = params.filterConfig) == null ? void 0 : _params$filterConfig.viewFilters) != null ? _params$filterConfig$ : [], customField),
1937
- combinedNominatorFilters = _buildPercentageFilte.combinedNominatorFilters,
1938
- combinedDenominatorFilters = _buildPercentageFilte.combinedDenominatorFilters;
2065
+ var _customField$numerato, _customField$numerato2, _customField$denomina, _customField$denomina2;
2066
+ var queryFiltersFromFilterConfig = combineFiltersFromFilterConfig(params.filterConfig, dataSet, params.timeRangeOptions, params.variables);
2067
+ var _buildPercentageFilte = buildPercentageFilters(customField, params.variables),
2068
+ queryFilterFromNumeratorFilter = _buildPercentageFilte.queryFilterFromNumeratorFilter,
2069
+ queryFilterFromDenominatorFilter = _buildPercentageFilte.queryFilterFromDenominatorFilter;
2070
+ var combinedNominatorFilters = combineQueryFilters(queryFiltersFromFilterConfig, queryFilterFromNumeratorFilter);
2071
+ var combinedDenominatorFilters = combineQueryFilters(queryFiltersFromFilterConfig, queryFilterFromDenominatorFilter);
2072
+ var completeNominatorFilters = buildQueryCustomMetrics(combinedNominatorFilters, dataSet, queryEngineConfig, params);
2073
+ var completeDenominatorFilters = buildQueryCustomMetrics(combinedDenominatorFilters, dataSet, queryEngineConfig, params);
1939
2074
  var left = {
1940
2075
  fieldId: (_customField$numerato = customField.numeratorFieldId) != null ? _customField$numerato : customField.denominatorFieldId,
1941
2076
  aggregate: (_customField$numerato2 = customField.numeratorAggregate) != null ? _customField$numerato2 : customField.denominatorAggregate
@@ -1952,44 +2087,31 @@ var build$2 = function build(customField, queryEngineConfig, dataSet, _queryHasD
1952
2087
  value: customField.denominatorFieldId,
1953
2088
  "function": customField.denominatorAggregate
1954
2089
  }],
1955
- filter: filterAttributeToQueryFilter(combinedDenominatorFilters || [], queryEngineConfig, dataSet, params)
2090
+ filter: completeDenominatorFilters
1956
2091
  }
1957
2092
  };
1958
- var denominatorForWithinGroupingScope = buildSide(right, isAvailable(customField.denominatorFilter) ? filterAttributeToQueryFilter(combinedDenominatorFilters, queryEngineConfig, dataSet, params) : {
2093
+ var denominatorForWithinGroupingScope = buildSide(right, isAvailable(customField.denominatorFilter) ? completeDenominatorFilters : {
1959
2094
  type: 'andWhere',
1960
2095
  value: []
1961
- });
2096
+ }, params.variables);
1962
2097
  return {
1963
2098
  type: 'maths',
1964
- left: buildSide(left, isAvailable(customField.numeratorFilter) ? filterAttributeToQueryFilter(combinedNominatorFilters, queryEngineConfig, dataSet, params) : {
2099
+ left: buildSide(left, isAvailable(customField.numeratorFilter) ? completeNominatorFilters : {
1965
2100
  type: 'andWhere',
1966
2101
  value: []
1967
- }),
2102
+ }, params.variables),
1968
2103
  op: '/',
1969
2104
  right: customField.denominatorScope === 'withinGrouping' ? denominatorForWithinGroupingScope : denominatorForAllScope
1970
2105
  };
1971
2106
  };
1972
- var buildSide = function buildSide(field, filter) {
1973
- var alwaysTrueFilter = {
1974
- type: 'andWhere',
1975
- value: [{
1976
- type: 'where',
1977
- value: {
1978
- field: {
1979
- type: 'number',
1980
- value: 2
1981
- },
1982
- op: '=',
1983
- value: 2
1984
- }
1985
- }]
1986
- };
2107
+ var buildSide = function buildSide(field, filter, variables) {
2108
+ var value = useValue(field.fieldId, variables);
1987
2109
  var hasNumeratorFilter = filter.type === 'where' || filter.value.length > 0;
1988
2110
  if (!hasNumeratorFilter) {
1989
2111
  return {
1990
2112
  type: 'field',
1991
2113
  "function": field.aggregate,
1992
- value: field.fieldId
2114
+ value: value
1993
2115
  };
1994
2116
  } else {
1995
2117
  return {
@@ -2002,7 +2124,7 @@ var buildSide = function buildSide(field, filter) {
2002
2124
  returns: {
2003
2125
  type: 'field',
2004
2126
  "function": 'none',
2005
- value: field.fieldId
2127
+ value: value
2006
2128
  },
2007
2129
  filter: filter
2008
2130
  }, {
@@ -2017,22 +2139,24 @@ var buildSide = function buildSide(field, filter) {
2017
2139
  };
2018
2140
  }
2019
2141
  };
2020
- function buildPercentageFilters(filters, customField) {
2021
- var combinedNominatorFilters = [];
2022
- var combinedDenominatorFilters = [];
2142
+ function buildPercentageFilters(customField, variables) {
2143
+ var queryFilterFromNumeratorFilter = {
2144
+ type: 'andWhere',
2145
+ value: []
2146
+ };
2147
+ var queryFilterFromDenominatorFilter = {
2148
+ type: 'andWhere',
2149
+ value: []
2150
+ };
2023
2151
  if (customField.numeratorFilter && isAvailable(customField.numeratorFilter)) {
2024
- combinedNominatorFilters = addAndFilters(filters != null ? filters : [], customField.numeratorFilter);
2025
- } else {
2026
- combinedNominatorFilters = filters != null ? filters : [];
2152
+ queryFilterFromNumeratorFilter = convertArrayFilterStructureToQueryFilter(customField.numeratorFilter, variables);
2027
2153
  }
2028
2154
  if (customField.denominatorFilter && isAvailable(customField.denominatorFilter)) {
2029
- combinedDenominatorFilters = addAndFilters(filters != null ? filters : [], customField.denominatorFilter);
2030
- } else {
2031
- combinedDenominatorFilters = filters != null ? filters : [];
2155
+ queryFilterFromDenominatorFilter = convertArrayFilterStructureToQueryFilter(customField.denominatorFilter, variables);
2032
2156
  }
2033
2157
  return {
2034
- combinedNominatorFilters: combinedNominatorFilters,
2035
- combinedDenominatorFilters: combinedDenominatorFilters
2158
+ queryFilterFromNumeratorFilter: queryFilterFromNumeratorFilter,
2159
+ queryFilterFromDenominatorFilter: queryFilterFromDenominatorFilter
2036
2160
  };
2037
2161
  }
2038
2162
 
@@ -2080,10 +2204,7 @@ var buildSide$1 = function buildSide(value, dataSet, variables) {
2080
2204
  "function": 'none'
2081
2205
  };
2082
2206
  }
2083
- var valueAsString = value;
2084
- if (detect(value)) {
2085
- valueAsString = useValue(value, variables);
2086
- }
2207
+ var valueAsString = useValue(value, variables);
2087
2208
  var valueAsNumber = Number(valueAsString);
2088
2209
  if (isNaN(valueAsNumber)) {
2089
2210
  var message = "Invalid number for Maths field: " + value + ".";
@@ -2117,35 +2238,36 @@ var init$3 = function init(publicName, leftFieldId, leftFunction, operator, righ
2117
2238
  rightNested: rightNested
2118
2239
  };
2119
2240
  };
2120
- var build$4 = function build(customField) {
2121
- var buildSide = function buildSide(fieldId, func, nested) {
2241
+ var build$4 = function build(customField, variables) {
2242
+ var buildSide = function buildSide(fieldId, func, variables, nested) {
2243
+ var value = useValue(fieldId, variables);
2122
2244
  if (nested) {
2245
+ var nestedValue = useValue(nested.fieldId, variables);
2123
2246
  return {
2124
2247
  type: 'maths',
2125
2248
  left: {
2126
2249
  type: 'field',
2127
- value: fieldId,
2250
+ value: value,
2128
2251
  "function": func
2129
2252
  },
2130
2253
  right: {
2131
2254
  type: 'field',
2132
- value: nested.fieldId,
2255
+ value: nestedValue,
2133
2256
  "function": nested["function"]
2134
2257
  },
2135
2258
  op: nested.operator
2136
2259
  };
2137
- } else {
2138
- return {
2139
- type: 'field',
2140
- value: fieldId,
2141
- "function": func
2142
- };
2143
2260
  }
2261
+ return {
2262
+ type: 'field',
2263
+ value: value,
2264
+ "function": func
2265
+ };
2144
2266
  };
2145
2267
  return {
2146
2268
  type: 'maths',
2147
- left: buildSide(customField.leftFieldId, customField.leftFunction, customField.leftNested),
2148
- right: buildSide(customField.rightFieldId, customField.rightFunction, customField.rightNested),
2269
+ left: buildSide(customField.leftFieldId, customField.leftFunction, variables, customField.leftNested),
2270
+ right: buildSide(customField.rightFieldId, customField.rightFunction, variables, customField.rightNested),
2149
2271
  op: customField.operator
2150
2272
  };
2151
2273
  };
@@ -2166,14 +2288,9 @@ var init$4 = function init(publicName, fieldId, func, rule, queryEngineConfig) {
2166
2288
  };
2167
2289
  };
2168
2290
  var build$5 = function build(field, queryEngineConfig, dataSet, params) {
2169
- var alwaysTrueFilter = [[{
2170
- value: 1,
2171
- op: '=',
2172
- field: {
2173
- type: 'number',
2174
- value: 1
2175
- }
2176
- }]];
2291
+ var queryFilterFromField = convertArrayFilterStructureToQueryFilter(field.rule, params.variables);
2292
+ var completeFilters = buildQueryCustomMetrics(queryFilterFromField, dataSet, queryEngineConfig, params);
2293
+ var value = useValue(field.fieldId, params.variables);
2177
2294
  return {
2178
2295
  type: 'function',
2179
2296
  "function": field["function"],
@@ -2184,9 +2301,9 @@ var build$5 = function build(field, queryEngineConfig, dataSet, params) {
2184
2301
  returns: {
2185
2302
  type: 'field',
2186
2303
  "function": 'none',
2187
- value: field.fieldId
2304
+ value: value
2188
2305
  },
2189
- filter: filterAttributeToQueryFilter(field.rule, queryEngineConfig, dataSet, params)
2306
+ filter: completeFilters
2190
2307
  }, {
2191
2308
  returns: {
2192
2309
  type: 'null'
@@ -2233,12 +2350,14 @@ var convertToCases = function convertToCases(rules, queryEngineConfig, dataSet,
2233
2350
  return rules.map(function (_ref) {
2234
2351
  var rule = _ref.rule,
2235
2352
  name = _ref.name;
2353
+ var queryFilterFromRule = convertArrayFilterStructureToQueryFilter(rule, params.variables);
2354
+ var completeFilters = buildQueryCustomMetrics(queryFilterFromRule, dataSet, queryEngineConfig, params);
2236
2355
  return {
2237
2356
  returns: {
2238
2357
  type: 'string',
2239
2358
  value: name
2240
2359
  },
2241
- filter: filterAttributeToQueryFilter(rule, queryEngineConfig, dataSet, params)
2360
+ filter: completeFilters
2242
2361
  };
2243
2362
  });
2244
2363
  };
@@ -2258,7 +2377,9 @@ var init$6 = function init(publicName, leftFieldId, dateCalculationFunction, rig
2258
2377
  }, queryEngineConfig)
2259
2378
  };
2260
2379
  };
2261
- var build$7 = function build(measureAttribute, customField) {
2380
+ var build$7 = function build(measureAttribute, customField, variables) {
2381
+ var leftValue = useValue(customField.leftFieldId, variables);
2382
+ var rightValue = useValue(customField.rightFieldId, variables);
2262
2383
  if (measureAttribute["function"] != 'none') {
2263
2384
  return {
2264
2385
  type: 'function',
@@ -2269,12 +2390,12 @@ var build$7 = function build(measureAttribute, customField) {
2269
2390
  left: {
2270
2391
  type: 'field',
2271
2392
  "function": 'none',
2272
- value: customField.leftFieldId
2393
+ value: leftValue
2273
2394
  },
2274
2395
  right: {
2275
2396
  type: 'field',
2276
2397
  "function": 'none',
2277
- value: customField.rightFieldId
2398
+ value: rightValue
2278
2399
  }
2279
2400
  }
2280
2401
  };
@@ -2285,12 +2406,12 @@ var build$7 = function build(measureAttribute, customField) {
2285
2406
  left: {
2286
2407
  type: 'field',
2287
2408
  "function": 'none',
2288
- value: customField.leftFieldId
2409
+ value: leftValue
2289
2410
  },
2290
2411
  right: {
2291
2412
  type: 'field',
2292
2413
  "function": 'none',
2293
- value: customField.rightFieldId
2414
+ value: rightValue
2294
2415
  }
2295
2416
  };
2296
2417
  }
@@ -2310,13 +2431,6 @@ var init$7 = function init(publicName, metric, queryEngineConfig) {
2310
2431
  };
2311
2432
  };
2312
2433
 
2313
- function combineForCustomMetricFilters(filters, customFilters) {
2314
- if (customFilters && isAvailable(customFilters)) {
2315
- return addAndFilters(filters != null ? filters : [], customFilters);
2316
- }
2317
- return filters != null ? filters : [];
2318
- }
2319
-
2320
2434
  var PropertyType = /*#__PURE__*/function (PropertyType) {
2321
2435
  PropertyType["Operator"] = "operator";
2322
2436
  PropertyType["IfLogic"] = "ifLogic";
@@ -2350,21 +2464,13 @@ var build$8 = function build(measureAttribute, customField, dataSet, queryEngine
2350
2464
  return buildOperator(customField.metric, dataSet, params, measureAttribute, false);
2351
2465
  };
2352
2466
  var buildIfLogic = function buildIfLogic(ifLogic, dataSet, queryEngineConfig, params, measureAttribute) {
2353
- var alwaysTrueFilter = [[{
2354
- value: 1,
2355
- op: '=',
2356
- field: {
2357
- type: 'number',
2358
- value: 1
2359
- }
2360
- }]];
2361
2467
  var cases = function () {
2362
2468
  var thenCases = ifLogic.cases.map(function (c) {
2363
- var _params$filterConfig$, _params$filterConfig;
2364
- var customMetricFilter = combineForCustomMetricFilters((_params$filterConfig$ = params == null || (_params$filterConfig = params.filterConfig) == null ? void 0 : _params$filterConfig.viewFilters) != null ? _params$filterConfig$ : [], c.filter);
2469
+ var customMetricFilter = convertArrayFilterStructureToQueryFilter(c.filter, params.variables);
2470
+ var completeFilters = buildQueryCustomMetrics(customMetricFilter, dataSet, queryEngineConfig, params);
2365
2471
  return {
2366
2472
  returns: buildMetric(c.returns, dataSet, params, measureAttribute),
2367
- filter: filterAttributeToQueryFilter(customMetricFilter, queryEngineConfig, dataSet, params)
2473
+ filter: completeFilters
2368
2474
  };
2369
2475
  });
2370
2476
  if (!ifLogic["else"]) return [].concat(thenCases, [{
@@ -2377,7 +2483,12 @@ var buildIfLogic = function buildIfLogic(ifLogic, dataSet, queryEngineConfig, pa
2377
2483
  returns: buildMetric(ifLogic["else"], dataSet, params, measureAttribute),
2378
2484
  filter: alwaysTrueFilter // Do not remove
2379
2485
  };
2380
- return [].concat(thenCases, [elseCase]);
2486
+ return [].concat(thenCases, [elseCase, {
2487
+ returns: {
2488
+ type: 'null'
2489
+ },
2490
+ filter: alwaysTrueFilter // Do not remove
2491
+ }]);
2381
2492
  }();
2382
2493
  if (!(measureAttribute != null && measureAttribute["function"]) || measureAttribute["function"] === 'none') {
2383
2494
  throw new Error('measure needs to be defined for if logic');
@@ -2532,11 +2643,12 @@ var init$8 = function init(publicName, fieldId, roundToDecimalPlaces, queryEngin
2532
2643
  }, queryEngineConfig)
2533
2644
  };
2534
2645
  };
2535
- var build$9 = function build(measureAttribute, customField) {
2646
+ var build$9 = function build(measureAttribute, customField, variables) {
2647
+ var value = useValue(customField.fieldId, variables);
2536
2648
  var builtRoundedNumber = {
2537
2649
  type: 'field',
2538
2650
  "function": "round_to_" + customField.roundToDecimalPlaces + "_dp",
2539
- value: customField.fieldId
2651
+ value: value
2540
2652
  };
2541
2653
  if (measureAttribute["function"] == 'none') return builtRoundedNumber;
2542
2654
  return {
@@ -2597,19 +2709,19 @@ var toQueryMeasure = function toQueryMeasure(measureAttribute, customField, quer
2597
2709
  return build$6(measureAttribute, customField, queryEngineConfig, dataSet, params);
2598
2710
  }
2599
2711
  if (isAggregateMathField(customField)) {
2600
- return build$4(customField);
2712
+ return build$4(customField, params.variables);
2601
2713
  }
2602
2714
  if (isSimpleMathField(customField)) {
2603
2715
  return build$3(measureAttribute, customField, dataSet, params);
2604
2716
  }
2605
2717
  if (isRoundedNumberField(customField)) {
2606
- return build$9(measureAttribute, customField);
2718
+ return build$9(measureAttribute, customField, params.variables);
2607
2719
  }
2608
2720
  if (isConditional(customField)) {
2609
2721
  return build$5(customField, queryEngineConfig, dataSet, params);
2610
2722
  }
2611
2723
  if (isDateCalculation(customField)) {
2612
- return build$7(measureAttribute, customField);
2724
+ return build$7(measureAttribute, customField, params.variables);
2613
2725
  }
2614
2726
  if (isCustomBuildMetric(customField)) {
2615
2727
  return build$8(measureAttribute, customField, dataSet, queryEngineConfig, params);
@@ -2924,13 +3036,44 @@ var dimensionSchema = function dimensionSchema(supportedTimeTruncFunctions, attr
2924
3036
  }
2925
3037
  return Joi.array().items(buildDimensionJoi(Joi.string().description('The ID of the field from the data set to reference.'), true)).description('Fields to group the data by');
2926
3038
  };
2927
- var filterSchema = function filterSchema(queryEngineConfig) {
3039
+ var queryFilterSchema = function queryFilterSchema(queryEngineConfig, maxDepth) {
2928
3040
  var _Joi$string3, _Joi$string4;
3041
+ if (maxDepth === void 0) {
3042
+ maxDepth = 10;
3043
+ }
3044
+ var whereFilterSchema = Joi.object({
3045
+ field: Joi.object({
3046
+ type: Joi.string().valid('field').required(),
3047
+ value: Joi.string().required().description('The ID of the field from the data set to reference.'),
3048
+ "function": (_Joi$string3 = Joi.string()).valid.apply(_Joi$string3, Object.keys(queryEngineConfig.supportedAggregates).concat(Object.keys(queryEngineConfig.supportedTimeTruncFunctions), ['none'])).description('Which function should be applied to the field?')
3049
+ }),
3050
+ op: (_Joi$string4 = Joi.string()).valid.apply(_Joi$string4, Object.keys(queryEngineConfig.supportedOperators)).required(),
3051
+ value: Joi.alternatives()["try"](joiDate, Joi.string().allow(null), Joi.number(), Joi["boolean"](), Joi.array().items(Joi.string(), Joi.number(), Joi.allow(null)), relativeSchema).required()
3052
+ });
3053
+ var _buildRecursiveSchema = function buildRecursiveSchema(depth) {
3054
+ if (depth <= 0) {
3055
+ return Joi.object({
3056
+ type: Joi.string().valid('where').required(),
3057
+ value: whereFilterSchema.required()
3058
+ });
3059
+ }
3060
+ return Joi.alternatives()["try"](Joi.object({
3061
+ type: Joi.string().valid('where').required(),
3062
+ value: whereFilterSchema.required()
3063
+ }), Joi.object({
3064
+ type: Joi.string().valid('andWhere', 'orWhere').required(),
3065
+ value: Joi.array().items(_buildRecursiveSchema(depth - 1)).min(1).required().description('Array of nested filters')
3066
+ }));
3067
+ };
3068
+ return _buildRecursiveSchema(maxDepth);
3069
+ };
3070
+ var filterSchema = function filterSchema(queryEngineConfig) {
3071
+ var _Joi$string5, _Joi$string6;
2929
3072
  return Joi.object({
2930
3073
  field: Joi.string().required().description('The ID of the field from the data set to reference.'),
2931
- op: (_Joi$string3 = Joi.string()).valid.apply(_Joi$string3, Object.keys(queryEngineConfig.supportedOperators)).required(),
3074
+ op: (_Joi$string5 = Joi.string()).valid.apply(_Joi$string5, Object.keys(queryEngineConfig.supportedOperators)).required(),
2932
3075
  value: Joi.alternatives()["try"](joiDate, Joi.string().allow(null), Joi.number(), Joi["boolean"](), Joi.array().items(Joi.string(), Joi.number(), Joi.allow(null)), relativeSchema).required(),
2933
- "function": (_Joi$string4 = Joi.string()).valid.apply(_Joi$string4, Object.keys(queryEngineConfig.supportedAggregates).concat(Object.keys(queryEngineConfig.supportedTimeTruncFunctions), ['none'])).description('Which function should be applied to the field?')
3076
+ "function": (_Joi$string6 = Joi.string()).valid.apply(_Joi$string6, Object.keys(queryEngineConfig.supportedAggregates).concat(Object.keys(queryEngineConfig.supportedTimeTruncFunctions), ['none'])).description('Which function should be applied to the field?')
2934
3077
  });
2935
3078
  };
2936
3079
  var queryAttributesFilter = function queryAttributesFilter(queryEngineConfig) {
@@ -2940,8 +3083,8 @@ var queryAttributesLimit = function queryAttributesLimit() {
2940
3083
  return Joi.number().description('Limit the number of results returned after the query has been ran.');
2941
3084
  };
2942
3085
  var baseAttributesSchema = function baseAttributesSchema(attributeSchemaOptions) {
2943
- var _Joi$string5;
2944
- var dataSetIdSchema = attributeSchemaOptions != null && attributeSchemaOptions.restrictDataSetIds ? (_Joi$string5 = Joi.string()).valid.apply(_Joi$string5, attributeSchemaOptions.restrictDataSetIds) : Joi.string();
3086
+ var _Joi$string7;
3087
+ var dataSetIdSchema = attributeSchemaOptions != null && attributeSchemaOptions.restrictDataSetIds ? (_Joi$string7 = Joi.string()).valid.apply(_Joi$string7, attributeSchemaOptions.restrictDataSetIds) : Joi.string();
2945
3088
  return {
2946
3089
  viewId: Joi.string().allow('').optional().description('__vizzly_hide_from_docs'),
2947
3090
  displayTitle: Joi.string().allow('').description('A title that explains what is being displayed.'),
@@ -2978,16 +3121,16 @@ var timeDimensionQuerySchema = function timeDimensionQuerySchema(queryEngineConf
2978
3121
  var lineCurveSchema = /*#__PURE__*/Joi.string().valid('natural', 'straight', 'step', 'stepBefore', 'stepAfter', 'dotted');
2979
3122
  var areaCurveSchema = /*#__PURE__*/Joi.string().valid('natural', 'straight', 'step');
2980
3123
  var protectedFieldsMeasure = function protectedFieldsMeasure(queryEngineConfig) {
2981
- var _Joi$string6;
3124
+ var _Joi$string8;
2982
3125
  return Joi.array().items(Joi.object({
2983
- "function": (_Joi$string6 = Joi.string()).valid.apply(_Joi$string6, Object.keys(queryEngineConfig.supportedAggregates).concat(Object.keys(queryEngineConfig.supportedTimeTruncFunctions), ['none'])),
3126
+ "function": (_Joi$string8 = Joi.string()).valid.apply(_Joi$string8, Object.keys(queryEngineConfig.supportedAggregates).concat(Object.keys(queryEngineConfig.supportedTimeTruncFunctions), ['none'])),
2984
3127
  field: Joi.string().required().description('The ID of the field from the data set to reference.')
2985
3128
  }));
2986
3129
  };
2987
3130
  var protectedFieldsDimension = function protectedFieldsDimension(queryEngineConfig) {
2988
- var _Joi$string7;
3131
+ var _Joi$string9;
2989
3132
  return Joi.array().items(Joi.object({
2990
- "function": (_Joi$string7 = Joi.string()).valid.apply(_Joi$string7, Object.keys(queryEngineConfig.supportedAggregates).concat(Object.keys(queryEngineConfig.supportedTimeTruncFunctions), ['none'])),
3133
+ "function": (_Joi$string9 = Joi.string()).valid.apply(_Joi$string9, Object.keys(queryEngineConfig.supportedAggregates).concat(Object.keys(queryEngineConfig.supportedTimeTruncFunctions), ['none'])),
2991
3134
  truncate: Joi.string(),
2992
3135
  field: Joi.string().required().description('The ID of the field from the data set to reference.'),
2993
3136
  bucketFill: Joi["boolean"]().optional(),
@@ -13010,8 +13153,8 @@ var defaultNumberFormatOptions = function defaultNumberFormatOptions(textOverrid
13010
13153
  },
13011
13154
  description: textOverride('number_format_option.minutes_to_hours_minutes', 'Minutes to hours & minutes')
13012
13155
  },
13013
- hour_of_day: {
13014
- description: 'Hour of the day',
13156
+ _vizzly_hour_of_day: {
13157
+ description: textOverride('number_format_option.hour_of_day', 'Hour of the day'),
13015
13158
  formatter: function formatter(value, noValueReplacement) {
13016
13159
  if (noValueReplacement === void 0) {
13017
13160
  noValueReplacement = noValue;
@@ -13020,8 +13163,8 @@ var defaultNumberFormatOptions = function defaultNumberFormatOptions(textOverrid
13020
13163
  return format$1(value, 'hour_of_day');
13021
13164
  }
13022
13165
  },
13023
- month_of_year: {
13024
- description: 'Month of the year',
13166
+ _vizzly_month_of_year: {
13167
+ description: textOverride('number_format_option.month_of_year', 'Month of the year'),
13025
13168
  formatter: function formatter(value, noValueReplacement) {
13026
13169
  if (noValueReplacement === void 0) {
13027
13170
  noValueReplacement = noValue;
@@ -13030,8 +13173,8 @@ var defaultNumberFormatOptions = function defaultNumberFormatOptions(textOverrid
13030
13173
  return format$1(value, 'month_of_year');
13031
13174
  }
13032
13175
  },
13033
- day_of_month: {
13034
- description: 'Day of month',
13176
+ _vizzly_day_of_month: {
13177
+ description: textOverride('number_format_option.day_of_month', 'Day of month'),
13035
13178
  formatter: function formatter(value, noValueReplacement) {
13036
13179
  if (noValueReplacement === void 0) {
13037
13180
  noValueReplacement = noValue;
@@ -13040,8 +13183,8 @@ var defaultNumberFormatOptions = function defaultNumberFormatOptions(textOverrid
13040
13183
  return format$1(value, 'day_of_month');
13041
13184
  }
13042
13185
  },
13043
- day_of_week_iso: {
13044
- description: 'Day of week',
13186
+ _vizzly_day_of_week_iso: {
13187
+ description: textOverride('number_format_option.day_of_week', 'Day of week'),
13045
13188
  formatter: function formatter(value, noValueReplacement) {
13046
13189
  if (noValueReplacement === void 0) {
13047
13190
  noValueReplacement = noValue;
@@ -13050,8 +13193,8 @@ var defaultNumberFormatOptions = function defaultNumberFormatOptions(textOverrid
13050
13193
  return format$1(value, 'day_of_week_iso');
13051
13194
  }
13052
13195
  },
13053
- week_of_year: {
13054
- description: 'Week of year',
13196
+ _vizzly_week_of_year: {
13197
+ description: textOverride('number_format_option.week_of_year', 'Week of year'),
13055
13198
  formatter: function formatter(value, noValueReplacement) {
13056
13199
  if (noValueReplacement === void 0) {
13057
13200
  noValueReplacement = noValue;
@@ -15122,8 +15265,7 @@ var fieldSchema = /*#__PURE__*/Joi.object({
15122
15265
  dataSetId: /*#__PURE__*/Joi.string().required()
15123
15266
  });
15124
15267
  var optionsFiltersSchema = function optionsFiltersSchema(queryEngineConfig) {
15125
- var innerArraySchema = Joi.array().items(filterSchema(queryEngineConfig));
15126
- return Joi.object().pattern(Joi.string(), Joi.array().items(innerArraySchema).optional());
15268
+ return Joi.object().pattern(Joi.string(), queryFilterSchema(queryEngineConfig));
15127
15269
  };
15128
15270
  var sharedAdditionalFilterSchema = function sharedAdditionalFilterSchema(queryEngineConfig) {
15129
15271
  return {
@@ -26428,7 +26570,9 @@ var buildFromQueryAttributes = function buildFromQueryAttributes(dataSet, measur
26428
26570
  var measure = [];
26429
26571
  var group = [];
26430
26572
  var order = [];
26431
- var filters = filterAttributeToQueryFilter(filterAttr, queryEngineConfig, dataSet, params);
26573
+ var queryFilterConfig = combineFiltersFromFilterConfig(params.filterConfig, dataSet, params.timeRangeOptions, params.variables);
26574
+ var queryFiltersFromAttributes = convertArrayFilterStructureToQueryFilter(filterAttr, params.variables);
26575
+ var filters = combineQueryFilters(queryFilterConfig, queryFiltersFromAttributes);
26432
26576
  if (timeDimensionAttr) {
26433
26577
  // Add the measure for the time field.
26434
26578
  var addedAt = undefined;
@@ -29069,7 +29213,7 @@ var FilterInputForm = function FilterInputForm(props) {
29069
29213
  }), props.onAddOrFilter && jsx(OrWrapper, {
29070
29214
  children: jsx(Tooltip, {
29071
29215
  tooltipContent: function tooltipContent() {
29072
- return 'Add OR filter';
29216
+ return textOverride('filters.add_or_filter', 'Add OR filter');
29073
29217
  },
29074
29218
  children: jsx(Button$2, {
29075
29219
  secondary: true,
@@ -40292,7 +40436,8 @@ var _GlobalFiltersView = /*#__PURE__*/withCustomRenderGuard(function (props) {
40292
40436
  dateFilterOptions = _useDashboardBehaviou.dateFilterOptions,
40293
40437
  featureToggles = _useDashboardBehaviou.featureToggles,
40294
40438
  cascadeFilterSelection = _useDashboardBehaviou.cascadeFilterSelection,
40295
- scope = _useDashboardBehaviou.scope;
40439
+ scope = _useDashboardBehaviou.scope,
40440
+ variables = _useDashboardBehaviou.variables;
40296
40441
  return jsxs(Flex, {
40297
40442
  gap: "0.5rem",
40298
40443
  "data-component": "filters",
@@ -40300,12 +40445,13 @@ var _GlobalFiltersView = /*#__PURE__*/withCustomRenderGuard(function (props) {
40300
40445
  wrap: true,
40301
40446
  children: [props.globalFilters.length > 0 && jsx(Fragment, {
40302
40447
  children: [].concat(props.globalFilters).map(function (globalFilter, globalFilterIndex) {
40448
+ var _variables$variables;
40303
40449
  return jsx(AdditionalFilter, {
40304
40450
  shouldAlwaysHaveValue: globalFilter.requiresValue,
40305
40451
  dataSets: dashboard.dataSets,
40306
40452
  dateFilterOptions: dateFilterOptions,
40307
40453
  filter: _extends({}, globalFilter, {
40308
- optionsFilters: getCascadeOptionsFilters(props == null ? void 0 : props.globalFilters, dashboard.dataSets, dateFilterOptions, cascadeFilterSelection)
40454
+ optionsFilters: getCascadeOptionsFilters(props == null ? void 0 : props.globalFilters, dashboard.dataSets, dateFilterOptions, (_variables$variables = variables == null ? void 0 : variables.variables) != null ? _variables$variables : {}, cascadeFilterSelection)
40309
40455
  }),
40310
40456
  filterIndex: globalFilterIndex,
40311
40457
  onChange: function onChange(newFilter) {
@@ -60120,15 +60266,15 @@ function customMetricText(key, textOverride) {
60120
60266
  subtext: textOverride('custom_metric_description.conditional', 'Create a conditional field')
60121
60267
  },
60122
60268
  customBuildMetric: {
60123
- title: textOverride('custom_metric_title.caclulated_field', 'Custom Metric Builder'),
60124
- subtext: textOverride('custom_metric_description.caclulated_field', 'Create a custom build field')
60269
+ title: textOverride('custom_metric_title.calculated_field', 'Custom Metric Builder'),
60270
+ subtext: textOverride('custom_metric_description.calculated_field', 'Create a custom build field')
60125
60271
  }
60126
60272
  };
60127
60273
  return values[key];
60128
60274
  }
60129
60275
  function buildCustomMetricTitle(key, textOverride) {
60130
- return textOverride('custom_metric_modal_title', '[[custom_metric_title]] Custom Metric', {
60131
- custom_metric_title: customMetricText(key, textOverride).title
60276
+ return textOverride('custom_metric_modal_title', '[[customMetricTitle]] Custom Metric', {
60277
+ customMetricTitle: customMetricText(key, textOverride).title
60132
60278
  });
60133
60279
  }
60134
60280
 
@@ -62700,7 +62846,7 @@ var RowOptions = function RowOptions(props) {
62700
62846
  });
62701
62847
  }
62702
62848
  };
62703
- var label = textOverride('cell_options', 'Move Row') + " " + (props == null ? void 0 : props.direction);
62849
+ var label = (props == null ? void 0 : props.direction) === Direction$2.Up ? textOverride('move_row_up', 'Move Row Up') : textOverride('move_row_down', 'Move Row Down');
62704
62850
  return jsx(Tooltip, {
62705
62851
  placement: "right-start",
62706
62852
  tooltipContent: function tooltipContent() {
@@ -69287,7 +69433,7 @@ var CustomMetricModal = function CustomMetricModal(props) {
69287
69433
  onClose: props.onClose,
69288
69434
  disableDnD: true,
69289
69435
  children: [jsx(Modal.Header, {
69290
- title: "Custom Metric Builder"
69436
+ title: textOverride('custom_metric_title.calculated_field', 'Custom Metric Builder')
69291
69437
  }), jsxs(Modal.Content, {
69292
69438
  children: [jsx(PanelProperty, {
69293
69439
  children: jsx(Input, {
@@ -74211,7 +74357,9 @@ var toQueries$1 = function toQueries$1(additionalFilter, dataSets, queryEngineCo
74211
74357
  if (!dataSet) throw 'Data set not found for additional filter query';
74212
74358
  var dataSetField = findField(dataSet, field.fieldId);
74213
74359
  if (dataSetField.dataType == 'string[]') {
74214
- var queryFilter = filterAttributeToQueryFilter(getOptionsFilters(additionalFilter, field), queryEngineConfig, dataSet, params);
74360
+ var optionsFilter = getOptionsFilters(additionalFilter, field);
74361
+ var queryFilterConfig = combineFiltersFromFilterConfig(params.filterConfig, dataSet, params.timeRangeOptions, params.variables);
74362
+ var queryFilter = combineQueryFilters(queryFilterConfig, optionsFilter);
74215
74363
  var _QueryLogic$buildUniq = buildUniqueArrayValuesPreparedQuery(field.dataSetId, dataSetField, queryFilter),
74216
74364
  query = _QueryLogic$buildUniq.query,
74217
74365
  resultFields = _QueryLogic$buildUniq.resultFields;
@@ -74220,8 +74368,17 @@ var toQueries$1 = function toQueries$1(additionalFilter, dataSets, queryEngineCo
74220
74368
  resultFields: [resultFields]
74221
74369
  };
74222
74370
  } else {
74223
- var filterQuery = buildFilterQuery(dataSet, field.fieldId, getOptionsFilters(additionalFilter, field), getOptionsOrders(dataSetField));
74224
- return toQueries(dataSets, [filterQuery], queryEngineConfig, params);
74371
+ var optionFilters = getOptionsFilters(additionalFilter, field);
74372
+ var filterQuery = buildFilterQuery(dataSet, field.fieldId, [], getOptionsOrders(dataSetField));
74373
+ var queryWithoutFilters = toQueries(dataSets, [filterQuery], queryEngineConfig, params);
74374
+ return {
74375
+ resultFields: queryWithoutFilters.resultFields,
74376
+ queries: queryWithoutFilters.queries.map(function (q) {
74377
+ return _extends({}, q, {
74378
+ filter: optionFilters
74379
+ });
74380
+ })
74381
+ };
74225
74382
  }
74226
74383
  });
74227
74384
  return {
@@ -74234,21 +74391,45 @@ var toQueries$1 = function toQueries$1(additionalFilter, dataSets, queryEngineCo
74234
74391
  };
74235
74392
  };
74236
74393
  function getOptionsFilters(additionalFilter, field) {
74237
- if (!additionalFilter.optionsFilters) {
74238
- return [];
74394
+ var optionsFilters = additionalFilter.optionsFilters ? additionalFilter.optionsFilters[field.dataSetId] : undefined;
74395
+ if (!optionsFilters) {
74396
+ return {
74397
+ type: 'andWhere',
74398
+ value: []
74399
+ };
74239
74400
  }
74240
- if (!(field.dataSetId in additionalFilter.optionsFilters)) {
74241
- return [];
74401
+ var filteredQuery = filterOutFieldId(optionsFilters, field.fieldId);
74402
+ return filteredQuery || {
74403
+ type: 'andWhere',
74404
+ value: []
74405
+ };
74406
+ }
74407
+ function filterOutFieldId(filter, fieldIdToExclude) {
74408
+ if (filter.type === 'where') {
74409
+ var field = getFieldFromFilter(filter);
74410
+ if (field && field.value === fieldIdToExclude) {
74411
+ return null;
74412
+ }
74413
+ return filter;
74242
74414
  }
74243
- var optionsFilters = additionalFilter.optionsFilters[field.dataSetId];
74244
- var orFilter = optionsFilters.map(function (filter) {
74245
- return filter.filter(function (f) {
74246
- return f.field !== field.fieldId;
74415
+ if (filter.type === 'andWhere' || filter.type === 'orWhere') {
74416
+ var filteredValues = filter.value.map(function (f) {
74417
+ return filterOutFieldId(f, fieldIdToExclude);
74418
+ }).filter(function (f) {
74419
+ return f !== null;
74247
74420
  });
74248
- });
74249
- return orFilter.filter(function (f) {
74250
- return f.length > 0;
74251
- });
74421
+ if (filteredValues.length === 0) {
74422
+ return null;
74423
+ }
74424
+ if (filteredValues.length === 1 && filteredValues[0].type === filter.type) {
74425
+ return filteredValues[0];
74426
+ }
74427
+ return {
74428
+ type: filter.type,
74429
+ value: filteredValues
74430
+ };
74431
+ }
74432
+ return filter;
74252
74433
  }
74253
74434
  function getOptionsOrders(dataSetField) {
74254
74435
  if ((dataSetField == null ? void 0 : dataSetField.dataType) === 'string' || (dataSetField == null ? void 0 : dataSetField.dataType) === 'number') {
@@ -74534,11 +74715,7 @@ var buildVizzlyQuery = function buildVizzlyQuery(thing, queryEngineConfig, param
74534
74715
  query = _QueryLogic$buildPreA.query,
74535
74716
  rF = _QueryLogic$buildPreA.resultFields;
74536
74717
  var underlyingDataSet = find(params.dataSets, underlyingDataSetId);
74537
- var filter = filterAttributeToQueryFilter([], queryEngineConfig, underlyingDataSet, _extends({}, params, {
74538
- filterConfig: _extends({}, params.filterConfig, {
74539
- viewFilters: undefined
74540
- })
74541
- }));
74718
+ var filter = combineFiltersFromFilterConfig(params.filterConfig, underlyingDataSet, params.timeRangeOptions, params.variables);
74542
74719
  queriesToSend = [_extends({}, query, {
74543
74720
  filter: (_filter = {}, _filter[underlyingDataSet.id] = filter, _filter)
74544
74721
  })];
@@ -74591,6 +74768,14 @@ var buildVizzlyQuery = function buildVizzlyQuery(thing, queryEngineConfig, param
74591
74768
  });
74592
74769
  });
74593
74770
  }
74771
+ queriesToSend = queriesToSend.map(function (q) {
74772
+ if (q.type === 'query') {
74773
+ return _extends({}, q, {
74774
+ filter: buildQueryCustomMetrics(q.filter, find(params.dataSets, q.dataSetId), queryEngineConfig, params)
74775
+ });
74776
+ }
74777
+ return q;
74778
+ });
74594
74779
  return {
74595
74780
  queries: queriesToSend,
74596
74781
  resultFields: resultFields
@@ -78149,9 +78334,9 @@ var useVizzly = function useVizzly(properties, options) {
78149
78334
  case 0:
78150
78335
  _context.prev = 0;
78151
78336
  _context.next = 3;
78152
- return Vizzly$1.load(properties, {
78337
+ return Vizzly$1.load(properties, _extends({}, options, {
78153
78338
  apiHost: (options == null ? void 0 : options.apiHost) || 'https://api.vizzly.co'
78154
- });
78339
+ }));
78155
78340
  case 3:
78156
78341
  vizzlyRef.current = _context.sent;
78157
78342
  _context.next = 6;
@@ -78577,7 +78762,9 @@ var useSessionContext = function useSessionContext(params) {
78577
78762
  dataSets: params.loadDataSetsCallback,
78578
78763
  programmaticDashboard: params.programmaticDashboard
78579
78764
  }, {
78580
- apiHost: params.apiConfig.host
78765
+ apiHost: params.apiConfig.host,
78766
+ developerMode: params.developerMode,
78767
+ textOverrides: params.textOverrides
78581
78768
  });
78582
78769
  var loadedStrategy = useDashboardStrategy(getStrategy(vizzly, params.parentDashboardId, params.dashboardId, params.isEditor), vizzly, params.programmaticDashboard);
78583
78770
  var _useScheduledReports = useScheduledReports(vizzly, loadedStrategy == null || (_loadedStrategy$dashb = loadedStrategy.dashboard) == null || (_loadedStrategy$dashb = _loadedStrategy$dashb.permission) == null ? void 0 : _loadedStrategy$dashb.token),
@@ -78677,7 +78864,7 @@ var GlobalProvider = function GlobalProvider(props) {
78677
78864
  }));
78678
78865
  };
78679
78866
  var GlobalProviderContents = function GlobalProviderContents(props) {
78680
- var _props$id, _session$identityConf, _props$dateFilterOpti, _session$vizzly$savin;
78867
+ var _props$developerTools, _props$id, _session$identityConf, _props$dateFilterOpti, _session$vizzly$savin;
78681
78868
  var _useState2 = useState(undefined),
78682
78869
  dashboardHash = _useState2[0],
78683
78870
  setDashboardHash = _useState2[1];
@@ -78688,9 +78875,9 @@ var GlobalProviderContents = function GlobalProviderContents(props) {
78688
78875
  host: 'https://api.vizzly.co'
78689
78876
  };
78690
78877
  var vizzlyAPI = api(apiConfig);
78878
+ var developerMode = typeof props.developerTools === 'object' && ((_props$developerTools = props.developerTools) == null ? void 0 : _props$developerTools.translationKeys) === true;
78691
78879
  var textOverride = function textOverride(key, value, options) {
78692
- var _props$developerTools;
78693
- return generateTranslation(key, value, options, props.textOverrides, typeof props.developerTools === 'object' && ((_props$developerTools = props.developerTools) == null ? void 0 : _props$developerTools.translationKeys) === true);
78880
+ return generateTranslation(key, value, options, props.textOverrides, developerMode);
78694
78881
  };
78695
78882
  var session = useSessionContext({
78696
78883
  dashboardId: props.dashboardId,
@@ -78702,7 +78889,9 @@ var GlobalProviderContents = function GlobalProviderContents(props) {
78702
78889
  implementationMeta: implementationMeta,
78703
78890
  programmaticDashboard: props.parentDashboard,
78704
78891
  textOverride: textOverride,
78705
- isEditor: props.isEditor
78892
+ isEditor: props.isEditor,
78893
+ developerMode: developerMode,
78894
+ textOverrides: props.textOverrides
78706
78895
  });
78707
78896
  var updateDashboardHash = function updateDashboardHash(dashboard) {
78708
78897
  var definition = toSaveableDefinition(dashboard);