@vizzly/dashboard 0.14.4-dev-452014891c726bda8e71210563e32bb225b30c86 → 0.14.4-dev-5d1abd7a6424f860eb93453f0fe71ca68b0e9b0d

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.
Files changed (25) hide show
  1. package/dist/dashboard.cjs.development.js +744 -299
  2. package/dist/dashboard.cjs.production.min.js +1 -1
  3. package/dist/dashboard.esm.js +744 -299
  4. package/dist/shared-logic/src/ComponentInterface/types.d.ts +1 -0
  5. package/dist/shared-logic/src/CustomField/CustomBuild/index.d.ts +7 -0
  6. package/dist/shared-logic/src/CustomField/CustomBuild/schema.d.ts +5 -0
  7. package/dist/shared-logic/src/CustomField/CustomBuild/validate.d.ts +5 -0
  8. package/dist/shared-logic/src/CustomField/CustomField.d.ts +2 -1
  9. package/dist/shared-logic/src/CustomField/CustomMetric/types.d.ts +10 -4
  10. package/dist/shared-logic/src/CustomField/index.d.ts +1 -0
  11. package/dist/shared-logic/src/CustomField/types.d.ts +8 -3
  12. package/dist/shared-logic/src/DataSet/fieldFilterOptions.d.ts +1 -0
  13. package/dist/shared-logic/src/FeatureToggle/types.d.ts +1 -0
  14. package/dist/shared-ui/src/components/CustomMetric/CustomMetricAggregate.d.ts +12 -0
  15. package/dist/shared-ui/src/components/CustomMetric/MetricOverview.d.ts +2 -0
  16. package/dist/shared-ui/src/components/CustomMetric/buildAggregateItems.d.ts +3 -0
  17. package/dist/shared-ui/src/components/CustomMetric/buildCustomMetric.d.ts +12 -8
  18. package/dist/shared-ui/src/components/CustomMetric/buildFieldsAndAggregates.d.ts +8 -0
  19. package/dist/shared-ui/src/components/CustomMetric/formatFormula.d.ts +2 -1
  20. package/dist/shared-ui/src/contexts/DashboardContext/types.d.ts +3 -1
  21. package/dist/shared-ui/src/library/DataPanel/CustomFieldInput/CustomMetricBuilder/CustomMetricBuilderModal.d.ts +5 -0
  22. package/dist/shared-ui/src/library/DataPanel/CustomFieldInput/CustomMetricBuilder/useCustomMetricBuilderModal.d.ts +15 -0
  23. package/dist/shared-ui/src/library/DataPanel/CustomMetricsInput.d.ts +1 -1
  24. package/dist/shared-ui/src/library/DataPanel/MeasuresInput.d.ts +1 -0
  25. package/package.json +1 -1
@@ -2187,6 +2187,7 @@ var PropertyType = /*#__PURE__*/function (PropertyType) {
2187
2187
  PropertyType["NumberInput"] = "number";
2188
2188
  PropertyType["Variable"] = "variable";
2189
2189
  PropertyType["Field"] = "field";
2190
+ PropertyType["Aggregate"] = "aggregate";
2190
2191
  return PropertyType;
2191
2192
  }({});
2192
2193
  var OperatorType = /*#__PURE__*/function (OperatorType) {
@@ -2356,7 +2357,313 @@ var validate$1 = function validate(field) {
2356
2357
  return true;
2357
2358
  };
2358
2359
 
2359
- var init$8 = function init(publicName, fieldId, roundToDecimalPlaces, queryEngineConfig) {
2360
+ var tagSchema = function tagSchema() {
2361
+ return Joi.object({
2362
+ key: Joi.string().required()
2363
+ });
2364
+ };
2365
+ var tagsSchema = function tagsSchema() {
2366
+ return Joi.array().items(tagSchema()).min(0);
2367
+ };
2368
+
2369
+ var measureSchema = function measureSchema(supportedAggregates, attributeSchemaOptions) {
2370
+ var buildMeasureJoi = function buildMeasureJoi(fieldJoi, functionJoi) {
2371
+ return Joi.object({
2372
+ field: fieldJoi.required(),
2373
+ "function": functionJoi.required().description('Which if any, aggregate function should be applied to the field?')
2374
+ });
2375
+ };
2376
+
2377
+ // Return an enum using the restriction fields
2378
+ if (attributeSchemaOptions != null && attributeSchemaOptions.restrictFields) {
2379
+ return Joi.alternatives.apply(Joi, attributeSchemaOptions.restrictFields.filter(function (f) {
2380
+ return f.canBeMeasure;
2381
+ }).map(function (restrictedField) {
2382
+ var _Joi$string;
2383
+ var supportedFunctionsForField = listValidFunctionsForDataType(restrictedField, supportedAggregates);
2384
+ return buildMeasureJoi(Joi.string().valid(restrictedField.id).description(restrictedField.publicName + ", " + (restrictedField.description || '') + "."), (_Joi$string = Joi.string()).valid.apply(_Joi$string, supportedFunctionsForField.concat(['none'])));
2385
+ }));
2386
+ }
2387
+ return buildMeasureJoi(Joi.string().description('The ID of the field from the data set to reference.'), Joi.valid.apply(Joi, Object.keys(supportedAggregates).concat(['none'])));
2388
+ };
2389
+ var orderSchema = function orderSchema(queryEngineConfig) {
2390
+ var _Joi$string2;
2391
+ return Joi.object({
2392
+ field: Joi.string().required().description('The ID of the field from the data set to reference.'),
2393
+ direction: Joi.string().valid('asc', 'desc').required().description('In which direction should the results be ordered?'),
2394
+ "function": (_Joi$string2 = Joi.string()).valid.apply(_Joi$string2, Object.keys(queryEngineConfig.supportedAggregates).concat(Object.keys(queryEngineConfig.supportedTimeTruncFunctions), ['none'])).description('Which if any, function should be applied to the field?')
2395
+ });
2396
+ };
2397
+ var timeDimensionSchema = function timeDimensionSchema(supportedTimeTruncFunctions) {
2398
+ return Joi.object({
2399
+ field: Joi.string().required().description('The ID of the field from the data set to reference.'),
2400
+ truncate: Joi.valid.apply(Joi, Object.keys(supportedTimeTruncFunctions).concat(['none'])),
2401
+ bucketFill: Joi["boolean"]()
2402
+ });
2403
+ };
2404
+ var dimensionSchema = function dimensionSchema(supportedTimeTruncFunctions, attributeSchemaOptions) {
2405
+ var buildDimensionJoi = function buildDimensionJoi(fieldJoi, isDate) {
2406
+ return Joi.object({
2407
+ field: fieldJoi.required(),
2408
+ pivot: Joi.string().valid('x', 'y').optional(),
2409
+ "function": isDate ? Joi.valid.apply(Joi, Object.keys(supportedTimeTruncFunctions).concat(['none'])).required() : Joi.valid('none').required()
2410
+ });
2411
+ };
2412
+
2413
+ // Return an enum using the restriction fields
2414
+ if (attributeSchemaOptions != null && attributeSchemaOptions.restrictFields) {
2415
+ return Joi.array().items(Joi.alternatives.apply(Joi, attributeSchemaOptions.restrictFields.filter(function (f) {
2416
+ return f.canBeDimension;
2417
+ }).map(function (restrictedField) {
2418
+ return buildDimensionJoi(Joi.string().valid(restrictedField.id).description(restrictedField.publicName + ", " + (restrictedField.description || '') + "."), restrictedField.dataType === 'date_time');
2419
+ }))).description('Fields to group the data by');
2420
+ }
2421
+ 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');
2422
+ };
2423
+ var filterSchema = function filterSchema(queryEngineConfig) {
2424
+ var _Joi$string3, _Joi$string4;
2425
+ return Joi.object({
2426
+ field: Joi.string().required().description('The ID of the field from the data set to reference.'),
2427
+ op: (_Joi$string3 = Joi.string()).valid.apply(_Joi$string3, Object.keys(queryEngineConfig.supportedOperators)).required(),
2428
+ 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(),
2429
+ "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?')
2430
+ });
2431
+ };
2432
+ var queryAttributesFilter = function queryAttributesFilter(queryEngineConfig) {
2433
+ return Joi.array().items(Joi.array().items(filterSchema(queryEngineConfig)));
2434
+ };
2435
+ var queryAttributesLimit = function queryAttributesLimit() {
2436
+ return Joi.number().description('Limit the number of results returned after the query has been ran.');
2437
+ };
2438
+ var baseAttributesSchema = function baseAttributesSchema(attributeSchemaOptions) {
2439
+ var _Joi$string5;
2440
+ var dataSetIdSchema = attributeSchemaOptions != null && attributeSchemaOptions.restrictDataSetIds ? (_Joi$string5 = Joi.string()).valid.apply(_Joi$string5, attributeSchemaOptions.restrictDataSetIds) : Joi.string();
2441
+ return {
2442
+ viewId: Joi.string().allow('').optional().description('__vizzly_hide_from_docs'),
2443
+ displayTitle: Joi.string().allow('').description('A title that explains what is being displayed.'),
2444
+ displaySubject: Joi.string().allow('').description('A chance to add a more detailed description of what is being shown.'),
2445
+ dataSetId: dataSetIdSchema.description('The ID of the data set that is being used by the view.'),
2446
+ protectedByOrganisation: Joi["boolean"]().optional().description('Has the view been created by your organisation, and therefore cannot be modified by your users?')
2447
+ };
2448
+ };
2449
+ var approxAxisLabelCountSchema = /*#__PURE__*/Joi.valid('auto', 2, 0).description('Determine how many axis labels should be shown on the axis');
2450
+ var querySchema = function querySchema(queryEngineConfig, attributeSchemaOptions) {
2451
+ return {
2452
+ measure: Joi.array().items(measureSchema(queryEngineConfig.supportedAggregates, attributeSchemaOptions)).required().description('A list of metrics that are to be shown. For example the `count` of a specific field in your data set.'),
2453
+ dimension: dimensionSchema(queryEngineConfig.supportedTimeTruncFunctions, attributeSchemaOptions).required(),
2454
+ order: Joi.array().items(orderSchema(queryEngineConfig)),
2455
+ limit: queryAttributesLimit(),
2456
+ offset: Joi.number().min(0).description('Paginate results by using this property with limit.')
2457
+ };
2458
+ };
2459
+ var timeDimensionQuerySchema = function timeDimensionQuerySchema(queryEngineConfig, attributeSchemaOptions) {
2460
+ return _extends({}, querySchema(queryEngineConfig, attributeSchemaOptions), {
2461
+ filter: Joi.array().items(Joi.array().items(filterSchema(queryEngineConfig))),
2462
+ timeDimension: Joi.alternatives(timeDimensionSchema(queryEngineConfig.supportedTimeTruncFunctions), Joi.valid(null)).required(),
2463
+ drilldown: Joi.alternatives(dimensionSchema(queryEngineConfig.supportedTimeTruncFunctions, attributeSchemaOptions).required(), Joi.string()),
2464
+ xAxisPrefix: Joi.string().allow('').description('Add a prefix to the X Axis'),
2465
+ yAxisPrefix: Joi.string().allow('').description('Add a prefix to the Y Axis'),
2466
+ xAxisPostfix: Joi.string().allow('').description('Add a postfix to the X Axis'),
2467
+ yAxisPostfix: Joi.string().allow('').description('Add a postfix to the Y Axis'),
2468
+ yAxisFormat: Joi.alternatives(Joi.string(), Joi.valid(null)).description('ID of the formatting function to apply to the Y Axis values'),
2469
+ xAxisFormat: Joi.alternatives(Joi.string(), Joi.valid(null)).description('ID of the formatting function to apply to the X Axis values'),
2470
+ approxYAxisLabelCount: approxAxisLabelCountSchema,
2471
+ approxXAxisLabelCount: approxAxisLabelCountSchema
2472
+ });
2473
+ };
2474
+ var lineCurveSchema = /*#__PURE__*/Joi.string().valid('natural', 'straight', 'step', 'stepBefore', 'stepAfter', 'dotted');
2475
+ var areaCurveSchema = /*#__PURE__*/Joi.string().valid('natural', 'straight', 'step');
2476
+ var protectedFieldsMeasure = function protectedFieldsMeasure(queryEngineConfig) {
2477
+ var _Joi$string6;
2478
+ return Joi.array().items(Joi.object({
2479
+ "function": (_Joi$string6 = Joi.string()).valid.apply(_Joi$string6, Object.keys(queryEngineConfig.supportedAggregates).concat(Object.keys(queryEngineConfig.supportedTimeTruncFunctions), ['none'])),
2480
+ field: Joi.string().required().description('The ID of the field from the data set to reference.')
2481
+ }));
2482
+ };
2483
+ var protectedFieldsDimension = function protectedFieldsDimension(queryEngineConfig) {
2484
+ var _Joi$string7;
2485
+ return Joi.array().items(Joi.object({
2486
+ "function": (_Joi$string7 = Joi.string()).valid.apply(_Joi$string7, Object.keys(queryEngineConfig.supportedAggregates).concat(Object.keys(queryEngineConfig.supportedTimeTruncFunctions), ['none'])),
2487
+ truncate: Joi.string(),
2488
+ field: Joi.string().required().description('The ID of the field from the data set to reference.'),
2489
+ bucketFill: Joi["boolean"]().optional(),
2490
+ pivot: Joi.string().valid('x', 'y').optional()
2491
+ }));
2492
+ };
2493
+ var parameterGroupSchema = function parameterGroupSchema(queryEngineConfig, attributeSchemaOptions) {
2494
+ return Joi.object().pattern(Joi.string(), Joi.alternatives()["try"](Joi.array().items(timeDimensionSchema(queryEngineConfig.supportedTimeTruncFunctions)).min(1), dimensionSchema(queryEngineConfig.supportedTimeTruncFunctions, attributeSchemaOptions))).unknown(true);
2495
+ };
2496
+ var parameterMeasureSchema = function parameterMeasureSchema(queryEngineConfig, attributeSchemaOptions) {
2497
+ return Joi.object().pattern(Joi.string(), Joi.array().items(measureSchema(queryEngineConfig.supportedAggregates, attributeSchemaOptions)).min(1)).unknown(true);
2498
+ };
2499
+ var parametersSchema = function parametersSchema(queryEngineConfig, attributeSchemaOptions) {
2500
+ return Joi.object({
2501
+ measure: parameterMeasureSchema(queryEngineConfig, attributeSchemaOptions),
2502
+ group: parameterGroupSchema(queryEngineConfig, attributeSchemaOptions)
2503
+ });
2504
+ };
2505
+ var goalLineValueSchema = /*#__PURE__*/Joi.alternatives()["try"]( /*#__PURE__*/Joi.number().required(), /*#__PURE__*/Joi.string().pattern(/^\{\{.*\}\}$/).required());
2506
+ var goalLineSchema = function goalLineSchema() {
2507
+ return Joi.object({
2508
+ color: Joi.string().required(),
2509
+ value: goalLineValueSchema,
2510
+ strokeWidth: Joi.number().required(),
2511
+ strokeStyle: Joi.string().valid('dashed', 'solid').required(),
2512
+ label: Joi["boolean"]().optional()
2513
+ });
2514
+ };
2515
+ var goalLinesSchema = function goalLinesSchema() {
2516
+ return Joi.array().items(goalLineSchema());
2517
+ };
2518
+ var headlineSchema = function headlineSchema() {
2519
+ return Joi.object({
2520
+ func: Joi.string().valid('mean', 'sum', 'current').allow(null).optional()
2521
+ });
2522
+ };
2523
+ var axisTitleSchema = function axisTitleSchema() {
2524
+ return Joi.object({
2525
+ x: Joi.string().allow(''),
2526
+ y: Joi.string().allow('')
2527
+ });
2528
+ };
2529
+ var sizingSchema = /*#__PURE__*/Joi.object().pattern( /*#__PURE__*/Joi.string(), /*#__PURE__*/Joi.object({
2530
+ width: /*#__PURE__*/Joi.number().min(0),
2531
+ height: /*#__PURE__*/Joi.number().min(0)
2532
+ }));
2533
+ var joiDate = /*#__PURE__*/Joi.custom(function (value, helpers) {
2534
+ if (Object.prototype.toString.call(value) === '[object Date]') {
2535
+ return value;
2536
+ }
2537
+ return helpers.error('any.invalid');
2538
+ }, 'Date object validation');
2539
+
2540
+ // Aggregate schema
2541
+ var aggregateSchema = /*#__PURE__*/Joi.object({
2542
+ type: /*#__PURE__*/Joi.string().valid('aggregate').required(),
2543
+ fieldId: /*#__PURE__*/Joi.string().required(),
2544
+ "function": /*#__PURE__*/Joi.string().required()
2545
+ });
2546
+
2547
+ // Field schema
2548
+ var fieldSchema = /*#__PURE__*/Joi.object({
2549
+ type: /*#__PURE__*/Joi.string().valid('field').required(),
2550
+ fieldId: /*#__PURE__*/Joi.string().required(),
2551
+ "function": /*#__PURE__*/Joi.string().valid('none').required()
2552
+ });
2553
+
2554
+ // Variable schema
2555
+ var variableSchema = /*#__PURE__*/Joi.object({
2556
+ type: /*#__PURE__*/Joi.string().valid('variable').required(),
2557
+ value: /*#__PURE__*/Joi.string().required()
2558
+ });
2559
+
2560
+ // Number schema
2561
+ var numberSchema = /*#__PURE__*/Joi.object({
2562
+ type: /*#__PURE__*/Joi.string().valid('number').required(),
2563
+ value: /*#__PURE__*/Joi.number().required()
2564
+ });
2565
+
2566
+ // Recursive operator schema (prevents empty values)
2567
+ var operatorSchema = /*#__PURE__*/Joi.object({
2568
+ type: Joi.string().valid('operator').required(),
2569
+ op: Joi.string().valid('+', '-', '*', '/').required(),
2570
+ values: Joi.array().items(Joi.when('type', {
2571
+ is: 'operator',
2572
+ then: Joi.link('#operatorSchema'),
2573
+ otherwise: Joi.alternatives()["try"](aggregateSchema, fieldSchema, variableSchema, numberSchema)
2574
+ })).min(2).custom(function (values, helpers) {
2575
+ var hasAggregate = values.some(function (v) {
2576
+ return v.type === 'aggregate';
2577
+ });
2578
+ var hasField = values.some(function (v) {
2579
+ return v.type === 'field';
2580
+ });
2581
+ var hasEmptyOperator = values.some(function (v) {
2582
+ return v.type === 'operator' && (!v.values || v.values.length === 0);
2583
+ });
2584
+ if (hasAggregate && hasField) {
2585
+ return helpers.error('any.invalid', {
2586
+ message: 'Field type cannot be mixed with Aggregate type in the same array'
2587
+ });
2588
+ }
2589
+ if (hasEmptyOperator) {
2590
+ return helpers.error('any.invalid', {
2591
+ message: 'Nested operators must have at least two values'
2592
+ });
2593
+ }
2594
+ return values;
2595
+ })
2596
+ }).meta({
2597
+ id: 'operatorSchema'
2598
+ });
2599
+ var ifLogicSchema = function ifLogicSchema(queryEngineConfig) {
2600
+ return Joi.object({
2601
+ type: Joi.string().valid('ifLogic').required(),
2602
+ cases: Joi.array().items(Joi.object({
2603
+ filter: Joi.array().items(Joi.array().items(filterSchema(queryEngineConfig)).min(1)).min(1).required(),
2604
+ returns: Joi.alternatives()["try"](fieldSchema, variableSchema, numberSchema, aggregateSchema, operatorSchema).required()
2605
+ })).min(1).required(),
2606
+ "else": Joi.alternatives()["try"](fieldSchema, variableSchema, numberSchema, aggregateSchema, operatorSchema).optional()
2607
+ });
2608
+ };
2609
+
2610
+ var validate$2 = function validate(queryEngineConfig, metric) {
2611
+ if (!metric) return {
2612
+ isValid: false
2613
+ };
2614
+ var schema = null;
2615
+
2616
+ // Determine which schema to use based on the metric type
2617
+ if (metric.type === 'operator') {
2618
+ schema = operatorSchema;
2619
+ } else if (metric.type === 'ifLogic') {
2620
+ schema = ifLogicSchema(queryEngineConfig);
2621
+ } else {
2622
+ return {
2623
+ isValid: false,
2624
+ errors: ['Unsupported metric type']
2625
+ };
2626
+ }
2627
+
2628
+ // Perform validation
2629
+ var _schema$validate = schema.validate(metric, {
2630
+ abortEarly: false
2631
+ }),
2632
+ error = _schema$validate.error;
2633
+ if (error) {
2634
+ return {
2635
+ isValid: false,
2636
+ errors: error.details.map(function (detail) {
2637
+ return detail.message;
2638
+ })
2639
+ };
2640
+ }
2641
+ return {
2642
+ isValid: true
2643
+ };
2644
+ };
2645
+
2646
+ var init$8 = function init(publicName, metric, queryEngineConfig) {
2647
+ return {
2648
+ id: generateId(),
2649
+ publicName: publicName,
2650
+ metricAtrributes: metric,
2651
+ canBeDimension: false,
2652
+ canBeMeasure: true,
2653
+ allowedOperators: validOperatorsForField({
2654
+ dataType: 'number'
2655
+ }, queryEngineConfig),
2656
+ dataType: 'number'
2657
+ };
2658
+ };
2659
+ var build$9 = function build() {
2660
+ return {
2661
+ type: 'number',
2662
+ value: 0
2663
+ };
2664
+ };
2665
+
2666
+ var init$9 = function init(publicName, fieldId, roundToDecimalPlaces, queryEngineConfig) {
2360
2667
  return {
2361
2668
  id: generateId(),
2362
2669
  publicName: publicName,
@@ -2370,7 +2677,7 @@ var init$8 = function init(publicName, fieldId, roundToDecimalPlaces, queryEngin
2370
2677
  }, queryEngineConfig)
2371
2678
  };
2372
2679
  };
2373
- var build$9 = function build(measureAttribute, customField) {
2680
+ var build$a = function build(measureAttribute, customField) {
2374
2681
  var builtRoundedNumber = {
2375
2682
  type: 'field',
2376
2683
  "function": "round_to_" + customField.roundToDecimalPlaces + "_dp",
@@ -2405,6 +2712,9 @@ var isConditional = function isConditional(field) {
2405
2712
  var isMetric = function isMetric(field) {
2406
2713
  return 'metric' in field;
2407
2714
  };
2715
+ var isCustomBuildMetric = function isCustomBuildMetric(field) {
2716
+ return 'metricAtrributes' in field;
2717
+ };
2408
2718
  var isDateCalculation = function isDateCalculation(field) {
2409
2719
  return 'dateCalculationFunction' in field;
2410
2720
  };
@@ -2417,10 +2727,11 @@ var getCustomFieldCategory = function getCustomFieldCategory(field) {
2417
2727
  if (isDateCalculation(field)) return 'dateCalculation';
2418
2728
  if (isConditional(field)) return 'conditional';
2419
2729
  if (isMetric(field)) return 'calculatedField';
2730
+ if (isCustomBuildMetric(field)) return 'customBuildMetric';
2420
2731
  throw "Unrecognised custom field type for custom field; " + JSON.stringify(field);
2421
2732
  };
2422
2733
  var isCustomField = function isCustomField(field) {
2423
- return isPercentageField(field) || isSimpleMathField(field) || isAggregateMathField(field) || isRules(field) || isRoundedNumberField(field) || isDateCalculation(field) || isConditional(field) || isMetric(field);
2734
+ return isPercentageField(field) || isSimpleMathField(field) || isAggregateMathField(field) || isRules(field) || isRoundedNumberField(field) || isDateCalculation(field) || isConditional(field) || isMetric(field) || isCustomBuildMetric(field);
2424
2735
  };
2425
2736
 
2426
2737
  /**
@@ -2441,7 +2752,7 @@ var toQueryMeasure = function toQueryMeasure(measureAttribute, customField, quer
2441
2752
  return build$3(measureAttribute, customField, dataSet, params);
2442
2753
  }
2443
2754
  if (isRoundedNumberField(customField)) {
2444
- return build$9(measureAttribute, customField);
2755
+ return build$a(measureAttribute, customField);
2445
2756
  }
2446
2757
  if (isConditional(customField)) {
2447
2758
  return build$5(customField, queryEngineConfig, dataSet, params);
@@ -2452,6 +2763,9 @@ var toQueryMeasure = function toQueryMeasure(measureAttribute, customField, quer
2452
2763
  if (isMetric(customField)) {
2453
2764
  return build$8(measureAttribute, customField, dataSet, queryEngineConfig, params);
2454
2765
  }
2766
+ if (isCustomBuildMetric(customField)) {
2767
+ return build$9();
2768
+ }
2455
2769
  throw "Unsupported custom field type; " + JSON.stringify(customField);
2456
2770
  };
2457
2771
 
@@ -2616,187 +2930,7 @@ var fromDashboardRequiredFilterGroups = function fromDashboardRequiredFilterGrou
2616
2930
  });
2617
2931
  };
2618
2932
 
2619
- var tagSchema = function tagSchema() {
2620
- return Joi.object({
2621
- key: Joi.string().required()
2622
- });
2623
- };
2624
- var tagsSchema = function tagsSchema() {
2625
- return Joi.array().items(tagSchema()).min(0);
2626
- };
2627
-
2628
- var measureSchema = function measureSchema(supportedAggregates, attributeSchemaOptions) {
2629
- var buildMeasureJoi = function buildMeasureJoi(fieldJoi, functionJoi) {
2630
- return Joi.object({
2631
- field: fieldJoi.required(),
2632
- "function": functionJoi.required().description('Which if any, aggregate function should be applied to the field?')
2633
- });
2634
- };
2635
-
2636
- // Return an enum using the restriction fields
2637
- if (attributeSchemaOptions != null && attributeSchemaOptions.restrictFields) {
2638
- return Joi.alternatives.apply(Joi, attributeSchemaOptions.restrictFields.filter(function (f) {
2639
- return f.canBeMeasure;
2640
- }).map(function (restrictedField) {
2641
- var _Joi$string;
2642
- var supportedFunctionsForField = listValidFunctionsForDataType(restrictedField, supportedAggregates);
2643
- return buildMeasureJoi(Joi.string().valid(restrictedField.id).description(restrictedField.publicName + ", " + (restrictedField.description || '') + "."), (_Joi$string = Joi.string()).valid.apply(_Joi$string, supportedFunctionsForField.concat(['none'])));
2644
- }));
2645
- }
2646
- return buildMeasureJoi(Joi.string().description('The ID of the field from the data set to reference.'), Joi.valid.apply(Joi, Object.keys(supportedAggregates).concat(['none'])));
2647
- };
2648
- var orderSchema = function orderSchema(queryEngineConfig) {
2649
- var _Joi$string2;
2650
- return Joi.object({
2651
- field: Joi.string().required().description('The ID of the field from the data set to reference.'),
2652
- direction: Joi.string().valid('asc', 'desc').required().description('In which direction should the results be ordered?'),
2653
- "function": (_Joi$string2 = Joi.string()).valid.apply(_Joi$string2, Object.keys(queryEngineConfig.supportedAggregates).concat(Object.keys(queryEngineConfig.supportedTimeTruncFunctions), ['none'])).description('Which if any, function should be applied to the field?')
2654
- });
2655
- };
2656
- var timeDimensionSchema = function timeDimensionSchema(supportedTimeTruncFunctions) {
2657
- return Joi.object({
2658
- field: Joi.string().required().description('The ID of the field from the data set to reference.'),
2659
- truncate: Joi.valid.apply(Joi, Object.keys(supportedTimeTruncFunctions).concat(['none'])),
2660
- bucketFill: Joi["boolean"]()
2661
- });
2662
- };
2663
- var dimensionSchema = function dimensionSchema(supportedTimeTruncFunctions, attributeSchemaOptions) {
2664
- var buildDimensionJoi = function buildDimensionJoi(fieldJoi, isDate) {
2665
- return Joi.object({
2666
- field: fieldJoi.required(),
2667
- pivot: Joi.string().valid('x', 'y').optional(),
2668
- "function": isDate ? Joi.valid.apply(Joi, Object.keys(supportedTimeTruncFunctions).concat(['none'])).required() : Joi.valid('none').required()
2669
- });
2670
- };
2671
-
2672
- // Return an enum using the restriction fields
2673
- if (attributeSchemaOptions != null && attributeSchemaOptions.restrictFields) {
2674
- return Joi.array().items(Joi.alternatives.apply(Joi, attributeSchemaOptions.restrictFields.filter(function (f) {
2675
- return f.canBeDimension;
2676
- }).map(function (restrictedField) {
2677
- return buildDimensionJoi(Joi.string().valid(restrictedField.id).description(restrictedField.publicName + ", " + (restrictedField.description || '') + "."), restrictedField.dataType === 'date_time');
2678
- }))).description('Fields to group the data by');
2679
- }
2680
- 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');
2681
- };
2682
- var filterSchema = function filterSchema(queryEngineConfig) {
2683
- var _Joi$string3, _Joi$string4;
2684
- return Joi.object({
2685
- field: Joi.string().required().description('The ID of the field from the data set to reference.'),
2686
- op: (_Joi$string3 = Joi.string()).valid.apply(_Joi$string3, Object.keys(queryEngineConfig.supportedOperators)).required(),
2687
- 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(),
2688
- "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?')
2689
- });
2690
- };
2691
- var queryAttributesFilter = function queryAttributesFilter(queryEngineConfig) {
2692
- return Joi.array().items(Joi.array().items(filterSchema(queryEngineConfig)));
2693
- };
2694
- var queryAttributesLimit = function queryAttributesLimit() {
2695
- return Joi.number().description('Limit the number of results returned after the query has been ran.');
2696
- };
2697
- var baseAttributesSchema = function baseAttributesSchema(attributeSchemaOptions) {
2698
- var _Joi$string5;
2699
- var dataSetIdSchema = attributeSchemaOptions != null && attributeSchemaOptions.restrictDataSetIds ? (_Joi$string5 = Joi.string()).valid.apply(_Joi$string5, attributeSchemaOptions.restrictDataSetIds) : Joi.string();
2700
- return {
2701
- viewId: Joi.string().allow('').optional().description('__vizzly_hide_from_docs'),
2702
- displayTitle: Joi.string().allow('').description('A title that explains what is being displayed.'),
2703
- displaySubject: Joi.string().allow('').description('A chance to add a more detailed description of what is being shown.'),
2704
- dataSetId: dataSetIdSchema.description('The ID of the data set that is being used by the view.'),
2705
- protectedByOrganisation: Joi["boolean"]().optional().description('Has the view been created by your organisation, and therefore cannot be modified by your users?')
2706
- };
2707
- };
2708
- var approxAxisLabelCountSchema = /*#__PURE__*/Joi.valid('auto', 2, 0).description('Determine how many axis labels should be shown on the axis');
2709
- var querySchema = function querySchema(queryEngineConfig, attributeSchemaOptions) {
2710
- return {
2711
- measure: Joi.array().items(measureSchema(queryEngineConfig.supportedAggregates, attributeSchemaOptions)).required().description('A list of metrics that are to be shown. For example the `count` of a specific field in your data set.'),
2712
- dimension: dimensionSchema(queryEngineConfig.supportedTimeTruncFunctions, attributeSchemaOptions).required(),
2713
- order: Joi.array().items(orderSchema(queryEngineConfig)),
2714
- limit: queryAttributesLimit(),
2715
- offset: Joi.number().min(0).description('Paginate results by using this property with limit.')
2716
- };
2717
- };
2718
- var timeDimensionQuerySchema = function timeDimensionQuerySchema(queryEngineConfig, attributeSchemaOptions) {
2719
- return _extends({}, querySchema(queryEngineConfig, attributeSchemaOptions), {
2720
- filter: Joi.array().items(Joi.array().items(filterSchema(queryEngineConfig))),
2721
- timeDimension: Joi.alternatives(timeDimensionSchema(queryEngineConfig.supportedTimeTruncFunctions), Joi.valid(null)).required(),
2722
- drilldown: Joi.alternatives(dimensionSchema(queryEngineConfig.supportedTimeTruncFunctions, attributeSchemaOptions).required(), Joi.string()),
2723
- xAxisPrefix: Joi.string().allow('').description('Add a prefix to the X Axis'),
2724
- yAxisPrefix: Joi.string().allow('').description('Add a prefix to the Y Axis'),
2725
- xAxisPostfix: Joi.string().allow('').description('Add a postfix to the X Axis'),
2726
- yAxisPostfix: Joi.string().allow('').description('Add a postfix to the Y Axis'),
2727
- yAxisFormat: Joi.alternatives(Joi.string(), Joi.valid(null)).description('ID of the formatting function to apply to the Y Axis values'),
2728
- xAxisFormat: Joi.alternatives(Joi.string(), Joi.valid(null)).description('ID of the formatting function to apply to the X Axis values'),
2729
- approxYAxisLabelCount: approxAxisLabelCountSchema,
2730
- approxXAxisLabelCount: approxAxisLabelCountSchema
2731
- });
2732
- };
2733
- var lineCurveSchema = /*#__PURE__*/Joi.string().valid('natural', 'straight', 'step', 'stepBefore', 'stepAfter', 'dotted');
2734
- var areaCurveSchema = /*#__PURE__*/Joi.string().valid('natural', 'straight', 'step');
2735
- var protectedFieldsMeasure = function protectedFieldsMeasure(queryEngineConfig) {
2736
- var _Joi$string6;
2737
- return Joi.array().items(Joi.object({
2738
- "function": (_Joi$string6 = Joi.string()).valid.apply(_Joi$string6, Object.keys(queryEngineConfig.supportedAggregates).concat(Object.keys(queryEngineConfig.supportedTimeTruncFunctions), ['none'])),
2739
- field: Joi.string().required().description('The ID of the field from the data set to reference.')
2740
- }));
2741
- };
2742
- var protectedFieldsDimension = function protectedFieldsDimension(queryEngineConfig) {
2743
- var _Joi$string7;
2744
- return Joi.array().items(Joi.object({
2745
- "function": (_Joi$string7 = Joi.string()).valid.apply(_Joi$string7, Object.keys(queryEngineConfig.supportedAggregates).concat(Object.keys(queryEngineConfig.supportedTimeTruncFunctions), ['none'])),
2746
- truncate: Joi.string(),
2747
- field: Joi.string().required().description('The ID of the field from the data set to reference.'),
2748
- bucketFill: Joi["boolean"]().optional(),
2749
- pivot: Joi.string().valid('x', 'y').optional()
2750
- }));
2751
- };
2752
- var parameterGroupSchema = function parameterGroupSchema(queryEngineConfig, attributeSchemaOptions) {
2753
- return Joi.object().pattern(Joi.string(), Joi.alternatives()["try"](Joi.array().items(timeDimensionSchema(queryEngineConfig.supportedTimeTruncFunctions)).min(1), dimensionSchema(queryEngineConfig.supportedTimeTruncFunctions, attributeSchemaOptions))).unknown(true);
2754
- };
2755
- var parameterMeasureSchema = function parameterMeasureSchema(queryEngineConfig, attributeSchemaOptions) {
2756
- return Joi.object().pattern(Joi.string(), Joi.array().items(measureSchema(queryEngineConfig.supportedAggregates, attributeSchemaOptions)).min(1)).unknown(true);
2757
- };
2758
- var parametersSchema = function parametersSchema(queryEngineConfig, attributeSchemaOptions) {
2759
- return Joi.object({
2760
- measure: parameterMeasureSchema(queryEngineConfig, attributeSchemaOptions),
2761
- group: parameterGroupSchema(queryEngineConfig, attributeSchemaOptions)
2762
- });
2763
- };
2764
- var goalLineValueSchema = /*#__PURE__*/Joi.alternatives()["try"]( /*#__PURE__*/Joi.number().required(), /*#__PURE__*/Joi.string().pattern(/^\{\{.*\}\}$/).required());
2765
- var goalLineSchema = function goalLineSchema() {
2766
- return Joi.object({
2767
- color: Joi.string().required(),
2768
- value: goalLineValueSchema,
2769
- strokeWidth: Joi.number().required(),
2770
- strokeStyle: Joi.string().valid('dashed', 'solid').required(),
2771
- label: Joi["boolean"]().optional()
2772
- });
2773
- };
2774
- var goalLinesSchema = function goalLinesSchema() {
2775
- return Joi.array().items(goalLineSchema());
2776
- };
2777
- var headlineSchema = function headlineSchema() {
2778
- return Joi.object({
2779
- func: Joi.string().valid('mean', 'sum', 'current').allow(null).optional()
2780
- });
2781
- };
2782
- var axisTitleSchema = function axisTitleSchema() {
2783
- return Joi.object({
2784
- x: Joi.string().allow(''),
2785
- y: Joi.string().allow('')
2786
- });
2787
- };
2788
- var sizingSchema = /*#__PURE__*/Joi.object().pattern( /*#__PURE__*/Joi.string(), /*#__PURE__*/Joi.object({
2789
- width: /*#__PURE__*/Joi.number().min(0),
2790
- height: /*#__PURE__*/Joi.number().min(0)
2791
- }));
2792
- var joiDate = /*#__PURE__*/Joi.custom(function (value, helpers) {
2793
- if (Object.prototype.toString.call(value) === '[object Date]') {
2794
- return value;
2795
- }
2796
- return helpers.error('any.invalid');
2797
- }, 'Date object validation');
2798
-
2799
- var fieldSchema = /*#__PURE__*/Joi.object({
2933
+ var fieldSchema$1 = /*#__PURE__*/Joi.object({
2800
2934
  fieldId: /*#__PURE__*/Joi.string().required(),
2801
2935
  dataSetId: /*#__PURE__*/Joi.string().required()
2802
2936
  });
@@ -2811,8 +2945,8 @@ var sharedAdditionalFilterSchema = function sharedAdditionalFilterSchema(queryEn
2811
2945
  managedByConfiguration: Joi["boolean"]().optional(),
2812
2946
  requiresValue: Joi["boolean"]().optional(),
2813
2947
  optionsFilters: optionsFiltersSchema(queryEngineConfig).optional(),
2814
- appliesToFields: Joi.array().items(fieldSchema).required(),
2815
- optionsPulledFrom: Joi.array().items(fieldSchema).optional(),
2948
+ appliesToFields: Joi.array().items(fieldSchema$1).required(),
2949
+ optionsPulledFrom: Joi.array().items(fieldSchema$1).optional(),
2816
2950
  hidden: Joi["boolean"](),
2817
2951
  options: Joi.array().items(Joi.object({
2818
2952
  value: Joi.allow(Joi.number(), Joi.string()),
@@ -3171,7 +3305,7 @@ var buildFilters = function buildFilters(dataSet, queryEngineConfig, params, pre
3171
3305
  return [];
3172
3306
  };
3173
3307
 
3174
- var build$a = buildFromQueryAttributes;
3308
+ var build$b = buildFromQueryAttributes;
3175
3309
  var hasDimensions = function hasDimensions(query) {
3176
3310
  return query.group.length > 0;
3177
3311
  };
@@ -4042,6 +4176,7 @@ var upcastHeadline = function upcastHeadline(headline, timeDimension) {
4042
4176
  var AcceptedTypes = /*#__PURE__*/function (AcceptedTypes) {
4043
4177
  AcceptedTypes["Maths"] = "maths";
4044
4178
  AcceptedTypes["IfStatement"] = "ifStatement";
4179
+ AcceptedTypes["Aggregates"] = "aggregates";
4045
4180
  return AcceptedTypes;
4046
4181
  }({});
4047
4182
 
@@ -4175,7 +4310,8 @@ var BarChart = function BarChart(config) {
4175
4310
  aggregateMaths: true,
4176
4311
  roundedNumbers: true,
4177
4312
  conditional: true,
4178
- calculatedField: [AcceptedTypes.Maths, AcceptedTypes.IfStatement]
4313
+ calculatedField: [AcceptedTypes.Maths, AcceptedTypes.IfStatement],
4314
+ customBuild: false
4179
4315
  },
4180
4316
  supportedFeatures: {
4181
4317
  parameters: true,
@@ -4570,7 +4706,8 @@ var LineChart = function LineChart(config) {
4570
4706
  aggregateMaths: true,
4571
4707
  roundedNumbers: true,
4572
4708
  conditional: true,
4573
- calculatedField: [AcceptedTypes.Maths, AcceptedTypes.IfStatement]
4709
+ calculatedField: [AcceptedTypes.Maths, AcceptedTypes.IfStatement],
4710
+ customBuild: false
4574
4711
  },
4575
4712
  supportedFeatures: {
4576
4713
  parameters: true,
@@ -4938,7 +5075,8 @@ var LineChart$1 = function LineChart(config) {
4938
5075
  rules: true,
4939
5076
  aggregateMaths: true,
4940
5077
  roundedNumbers: true,
4941
- conditional: true
5078
+ conditional: true,
5079
+ customBuild: false
4942
5080
  },
4943
5081
  supportedFeatures: {
4944
5082
  parameters: true,
@@ -5212,7 +5350,8 @@ var PieChart = function PieChart(config) {
5212
5350
  aggregateMaths: true,
5213
5351
  roundedNumbers: true,
5214
5352
  conditional: true,
5215
- calculatedField: [AcceptedTypes.Maths, AcceptedTypes.IfStatement]
5353
+ calculatedField: [AcceptedTypes.Maths, AcceptedTypes.IfStatement],
5354
+ customBuild: false
5216
5355
  },
5217
5356
  supportedFeatures: {
5218
5357
  parameters: true,
@@ -5566,7 +5705,8 @@ var ScatterChart = function ScatterChart(config) {
5566
5705
  aggregateMaths: true,
5567
5706
  roundedNumbers: true,
5568
5707
  conditional: true,
5569
- calculatedField: [AcceptedTypes.Maths, AcceptedTypes.IfStatement]
5708
+ calculatedField: [AcceptedTypes.Maths, AcceptedTypes.IfStatement],
5709
+ customBuild: false
5570
5710
  },
5571
5711
  supportedFeatures: {
5572
5712
  parameters: false,
@@ -5938,7 +6078,8 @@ var ComboChart = function ComboChart(config) {
5938
6078
  aggregateMaths: true,
5939
6079
  roundedNumbers: true,
5940
6080
  conditional: true,
5941
- calculatedField: [AcceptedTypes.Maths, AcceptedTypes.IfStatement]
6081
+ calculatedField: [AcceptedTypes.Maths, AcceptedTypes.IfStatement],
6082
+ customBuild: false
5942
6083
  },
5943
6084
  supportedFeatures: {
5944
6085
  parameters: false,
@@ -6273,7 +6414,8 @@ var DataTable = function DataTable(config) {
6273
6414
  aggregateMaths: true,
6274
6415
  roundedNumbers: true,
6275
6416
  conditional: true,
6276
- calculatedField: [AcceptedTypes.Maths, AcceptedTypes.IfStatement]
6417
+ calculatedField: [AcceptedTypes.Maths, AcceptedTypes.IfStatement],
6418
+ customBuild: false
6277
6419
  },
6278
6420
  supportedFeatures: {
6279
6421
  parameters: false,
@@ -6518,7 +6660,8 @@ var BasicTable = function BasicTable(config) {
6518
6660
  roundedNumbers: true,
6519
6661
  dateCalculations: true,
6520
6662
  conditional: true,
6521
- calculatedField: [AcceptedTypes.Maths]
6663
+ calculatedField: [AcceptedTypes.Maths],
6664
+ customBuild: false
6522
6665
  },
6523
6666
  supportedFeatures: {
6524
6667
  parameters: false,
@@ -6830,7 +6973,8 @@ var HorizontalBarChart = function HorizontalBarChart(config) {
6830
6973
  aggregateMaths: true,
6831
6974
  roundedNumbers: true,
6832
6975
  conditional: true,
6833
- calculatedField: [AcceptedTypes.Maths, AcceptedTypes.IfStatement]
6976
+ calculatedField: [AcceptedTypes.Maths, AcceptedTypes.IfStatement],
6977
+ customBuild: false
6834
6978
  },
6835
6979
  supportedFeatures: {
6836
6980
  parameters: true,
@@ -7191,7 +7335,8 @@ var AreaChart = function AreaChart(config) {
7191
7335
  aggregateMaths: true,
7192
7336
  roundedNumbers: true,
7193
7337
  conditional: true,
7194
- calculatedField: [AcceptedTypes.Maths, AcceptedTypes.IfStatement]
7338
+ calculatedField: [AcceptedTypes.Maths, AcceptedTypes.IfStatement],
7339
+ customBuild: false
7195
7340
  },
7196
7341
  supportedFeatures: {
7197
7342
  parameters: true,
@@ -7481,7 +7626,8 @@ var SingleStat = function SingleStat(config) {
7481
7626
  rules: true,
7482
7627
  roundedNumbers: true,
7483
7628
  conditional: true,
7484
- calculatedField: [AcceptedTypes.Maths, AcceptedTypes.IfStatement]
7629
+ calculatedField: [AcceptedTypes.Maths, AcceptedTypes.IfStatement],
7630
+ customBuild: [AcceptedTypes.Maths, AcceptedTypes.IfStatement]
7485
7631
  },
7486
7632
  supportedFeatures: {
7487
7633
  parameters: true,
@@ -7616,7 +7762,8 @@ var CustomChart = function CustomChart(config) {
7616
7762
  roundedNumbers: false,
7617
7763
  dateCalculations: false,
7618
7764
  conditional: false,
7619
- calculatedField: [AcceptedTypes.Maths, AcceptedTypes.IfStatement]
7765
+ calculatedField: [AcceptedTypes.Maths, AcceptedTypes.IfStatement],
7766
+ customBuild: false
7620
7767
  },
7621
7768
  supportedFeatures: {
7622
7769
  colorGradient: false,
@@ -7852,7 +7999,8 @@ var MercatorMap = function MercatorMap(config) {
7852
7999
  aggregateMaths: true,
7853
8000
  roundedNumbers: true,
7854
8001
  conditional: true,
7855
- calculatedField: [AcceptedTypes.Maths, AcceptedTypes.IfStatement]
8002
+ calculatedField: [AcceptedTypes.Maths, AcceptedTypes.IfStatement],
8003
+ customBuild: false
7856
8004
  },
7857
8005
  supportedFeatures: {
7858
8006
  parameters: false,
@@ -8163,7 +8311,8 @@ var RichText = function RichText(config) {
8163
8311
  aggregateMaths: true,
8164
8312
  roundedNumbers: true,
8165
8313
  conditional: true,
8166
- calculatedField: [AcceptedTypes.Maths, AcceptedTypes.IfStatement]
8314
+ calculatedField: [AcceptedTypes.Maths, AcceptedTypes.IfStatement],
8315
+ customBuild: false
8167
8316
  },
8168
8317
  supportedFeatures: {
8169
8318
  parameters: false,
@@ -8472,7 +8621,8 @@ var RadarChart = function RadarChart(config) {
8472
8621
  rules: true,
8473
8622
  aggregateMaths: true,
8474
8623
  roundedNumbers: true,
8475
- conditional: true
8624
+ conditional: true,
8625
+ customBuild: false
8476
8626
  },
8477
8627
  supportedFeatures: {
8478
8628
  parameters: true,
@@ -8690,7 +8840,8 @@ var Progress = function Progress(config) {
8690
8840
  rules: true,
8691
8841
  roundedNumbers: true,
8692
8842
  conditional: true,
8693
- calculatedField: [AcceptedTypes.Maths, AcceptedTypes.IfStatement]
8843
+ calculatedField: [AcceptedTypes.Maths, AcceptedTypes.IfStatement],
8844
+ customBuild: [AcceptedTypes.Maths, AcceptedTypes.IfStatement]
8694
8845
  },
8695
8846
  supportedFeatures: {
8696
8847
  parameters: false,
@@ -8993,7 +9144,8 @@ var FunnelChart = function FunnelChart(config) {
8993
9144
  aggregateMaths: true,
8994
9145
  roundedNumbers: true,
8995
9146
  conditional: true,
8996
- calculatedField: [AcceptedTypes.Maths, AcceptedTypes.IfStatement]
9147
+ calculatedField: [AcceptedTypes.Maths, AcceptedTypes.IfStatement],
9148
+ customBuild: false
8997
9149
  },
8998
9150
  supportedFeatures: {
8999
9151
  parameters: true,
@@ -9640,7 +9792,8 @@ var BubbleChart = function BubbleChart(config) {
9640
9792
  aggregateMaths: true,
9641
9793
  roundedNumbers: true,
9642
9794
  conditional: true,
9643
- calculatedField: [AcceptedTypes.Maths, AcceptedTypes.IfStatement]
9795
+ calculatedField: [AcceptedTypes.Maths, AcceptedTypes.IfStatement],
9796
+ customBuild: false
9644
9797
  },
9645
9798
  supportedFeatures: {
9646
9799
  parameters: false,
@@ -9999,7 +10152,8 @@ var BarChart$1 = function BarChart(config) {
9999
10152
  rules: true,
10000
10153
  aggregateMaths: true,
10001
10154
  roundedNumbers: true,
10002
- conditional: true
10155
+ conditional: true,
10156
+ customBuild: false
10003
10157
  },
10004
10158
  supportedFeatures: {
10005
10159
  parameters: true,
@@ -10330,7 +10484,8 @@ var WaterfallChart = function WaterfallChart(config) {
10330
10484
  aggregateMaths: true,
10331
10485
  roundedNumbers: true,
10332
10486
  conditional: true,
10333
- calculatedField: [AcceptedTypes.Maths, AcceptedTypes.IfStatement]
10487
+ calculatedField: [AcceptedTypes.Maths, AcceptedTypes.IfStatement],
10488
+ customBuild: false
10334
10489
  },
10335
10490
  supportedFeatures: {
10336
10491
  parameters: true,
@@ -10703,7 +10858,8 @@ var AreaChart$1 = function AreaChart(config) {
10703
10858
  rules: true,
10704
10859
  aggregateMaths: true,
10705
10860
  roundedNumbers: true,
10706
- conditional: true
10861
+ conditional: true,
10862
+ customBuild: false
10707
10863
  },
10708
10864
  supportedFeatures: {
10709
10865
  parameters: true,
@@ -10813,6 +10969,11 @@ function filterFields(originalFields, options) {
10813
10969
  return !isDateCalculation(field);
10814
10970
  });
10815
10971
  }
10972
+ if (options != null && options.removeCustomBuildMetric) {
10973
+ fields = fields.filter(function (field) {
10974
+ return !isCustomBuildMetric(field);
10975
+ });
10976
+ }
10816
10977
  if (options != null && options.removeConditional) {
10817
10978
  fields = fields.filter(function (field) {
10818
10979
  return !isConditional(field);
@@ -12023,7 +12184,7 @@ function linearForecast(data, forecastUnits, key, timeUnit, includeForecast // N
12023
12184
  return trendlineWithForecast;
12024
12185
  }
12025
12186
 
12026
- var init$9 = function init(_ref) {
12187
+ var init$a = function init(_ref) {
12027
12188
  var pivotConfig = _ref.pivotConfig,
12028
12189
  measures = _ref.measures,
12029
12190
  resultSet = _ref.resultSet,
@@ -13773,6 +13934,7 @@ var ADMIN_FEATURE_TOGGLES = {
13773
13934
  allowAggregateMathsCustomField: true,
13774
13935
  allowRoundedNumberCustomField: true,
13775
13936
  allowRulesCustomField: true,
13937
+ allowCustomBuildField: false,
13776
13938
  showDateAndTimeFilter: true,
13777
13939
  showDateFilter: true,
13778
13940
  canSeeEmptyState: false,
@@ -13810,6 +13972,7 @@ var END_USER_DEFAULT_FEATURE_TOGGLES = {
13810
13972
  allowRoundedNumberCustomField: true,
13811
13973
  allowCalculatedField: false,
13812
13974
  allowRulesCustomField: true,
13975
+ allowCustomBuildField: false,
13813
13976
  showDateAndTimeFilter: true,
13814
13977
  showDateFilter: true,
13815
13978
  canSeeEmptyState: false,
@@ -13822,7 +13985,7 @@ var END_USER_DEFAULT_FEATURE_TOGGLES = {
13822
13985
  showSavingIndicator: true,
13823
13986
  disablePersistingGlobalFiltersLocally: false
13824
13987
  };
13825
- var build$b = function build(partialFeatureToggles, queryEngineConfig, mode, scope) {
13988
+ var build$c = function build(partialFeatureToggles, queryEngineConfig, mode, scope) {
13826
13989
  var featureToggles = {};
13827
13990
  featureToggles = _extends({}, featureToggles, END_USER_DEFAULT_FEATURE_TOGGLES, partialFeatureToggles);
13828
13991
  if (mode == 'admin') {
@@ -13916,7 +14079,7 @@ var removeField$3 = function removeField(component, fieldId) {
13916
14079
  return newComponent;
13917
14080
  };
13918
14081
 
13919
- var init$a = function init(displayTitle) {
14082
+ var init$b = function init(displayTitle) {
13920
14083
  return {
13921
14084
  displayTitle: displayTitle,
13922
14085
  colSpan: 12
@@ -13928,7 +14091,7 @@ var isComponent = function isComponent(component) {
13928
14091
  var HEADER_ROW_HEIGHT$1 = 52;
13929
14092
  var add = function add(display, rowIndex, initialTitle) {
13930
14093
  var updatedDisplay = [].concat(display);
13931
- var newHeader = init$a(initialTitle);
14094
+ var newHeader = init$b(initialTitle);
13932
14095
  var newRow = initRow([newHeader], HEADER_ROW_HEIGHT$1);
13933
14096
  updatedDisplay.splice(rowIndex, 0, newRow);
13934
14097
  return updatedDisplay;
@@ -14394,7 +14557,7 @@ var defaultDateFilterOptions = function defaultDateFilterOptions() {
14394
14557
  }
14395
14558
  return defaultDateFilterOptions;
14396
14559
  };
14397
- var build$c = function build(textOverride, overrides) {
14560
+ var build$d = function build(textOverride, overrides) {
14398
14561
  var timeRangeMapping = defaultTimeRangeMapping(textOverride);
14399
14562
  var orderedKeys = Object.keys(DEFAULT_DATETIME_FILTER_OPTIONS).map(function (key) {
14400
14563
  return key in timeRangeMapping ? "_vizzly_" + key : key;
@@ -14688,7 +14851,7 @@ var base = {
14688
14851
  return undefined;
14689
14852
  }
14690
14853
  };
14691
- var init$b = function init(overrides, includeComponentTypes, excludeComponentTypes, textOverride, featureToggles) {
14854
+ var init$c = function init(overrides, includeComponentTypes, excludeComponentTypes, textOverride, featureToggles) {
14692
14855
  var _overrides$developerT;
14693
14856
  var onlyViewTypes = function onlyViewTypes(dataSet) {
14694
14857
  var allowedView = filterIncludedAndExcludedViews(ALL_VIZZLY_COMPONENT_TYPES, includeComponentTypes,
@@ -14726,7 +14889,7 @@ var init$b = function init(overrides, includeComponentTypes, excludeComponentTyp
14726
14889
  return _extends({}, defaultFormatMapping, overrides.defaultFormats ? overrides.defaultFormats() : {});
14727
14890
  },
14728
14891
  onEditorUpdate: overrides.onEditorUpdate ? overrides.onEditorUpdate : base.onEditorUpdate,
14729
- dateFilterOptions: build$c(textOverride, overrides.dateFilterOptions),
14892
+ dateFilterOptions: build$d(textOverride, overrides.dateFilterOptions),
14730
14893
  onSave: overrides.onSave ? overrides.onSave : base.onSave,
14731
14894
  onScheduledReportChange: overrides.onScheduledReportChange || base.onScheduledReportChange,
14732
14895
  dashboardFilters: overrides.dashboardFilters ? overrides.dashboardFilters : base.dashboardFilters,
@@ -14780,7 +14943,7 @@ function useSubscription(callback, idOverride) {
14780
14943
  var useFeatureTogglesSetup = function useFeatureTogglesSetup(mode, overrideFeatureToggles, queryEngineConfig, scope, id) {
14781
14944
  var base$1 = base;
14782
14945
  var buildInitialFeatureToggles = function () {
14783
- var updatedFeatureToggles = build$b(___default.merge({}, base$1.featureToggles, overrideFeatureToggles), queryEngineConfig != null ? queryEngineConfig : base$1.queryEngineConfig, mode || base$1.mode, scope || base$1.scope);
14946
+ var updatedFeatureToggles = build$c(___default.merge({}, base$1.featureToggles, overrideFeatureToggles), queryEngineConfig != null ? queryEngineConfig : base$1.queryEngineConfig, mode || base$1.mode, scope || base$1.scope);
14784
14947
  return updatedFeatureToggles;
14785
14948
  }();
14786
14949
  var _useState = React.useState(buildInitialFeatureToggles),
@@ -14810,7 +14973,7 @@ var DashboardBehaviourContextProvider = function DashboardBehaviourContextProvid
14810
14973
  var _useState = React.useState(null),
14811
14974
  overrideDeveloperInfo = _useState[0],
14812
14975
  setOverrideDeveloperInfo = _useState[1];
14813
- var dashboardBehaviour = init$b(_extends({}, props.dashboardBehaviour || {}, {
14976
+ var dashboardBehaviour = init$c(_extends({}, props.dashboardBehaviour || {}, {
14814
14977
  mode: props.mode
14815
14978
  }), props.includeComponentTypes, props.excludeComponentTypes, textOverride, featureToggles);
14816
14979
  return jsxRuntime.jsx(DashboardBehaviourContext.Provider, {
@@ -33429,7 +33592,7 @@ var AreaChart$3 = /*#__PURE__*/React.forwardRef(function (props, ref) {
33429
33592
  });
33430
33593
  });
33431
33594
 
33432
- var init$c = function init(attributes) {
33595
+ var init$d = function init(attributes) {
33433
33596
  var dimension = [];
33434
33597
  if ('dimension' in attributes) {
33435
33598
  dimension = [].concat(dimension, attributes.dimension || []);
@@ -34321,7 +34484,7 @@ var AreaChartView = function AreaChartView(props) {
34321
34484
  if (isLoading(props.result)) return jsxRuntime.jsx(LoadingComponent, {});
34322
34485
  if (hasFailed(props.result)) return jsxRuntime.jsx(FailedToLoadDataNotice, {});
34323
34486
  if (isEmpty(props.result)) return jsxRuntime.jsx(NoResultContentToShowNotice, _extends({}, headerProps));
34324
- var pivotConfig = init$c(props);
34487
+ var pivotConfig = init$d(props);
34325
34488
  var series$1 = series(pivotConfig, props.measure, props.result);
34326
34489
  var resultSet$1 = resultSet(props.result, props.measure, pivotConfig, props.stacked == '100%', checkForNullValue(props.dataSetId, props.dimension, props.timeDimension, textOverride, valueAlias));
34327
34490
  var showHeadline = headlineAvailable(props.order, props.headline, props.timeDimension);
@@ -35608,7 +35771,7 @@ var BarChartView = function BarChartView(props) {
35608
35771
  if (isLoading(props.result)) return jsxRuntime.jsx(LoadingComponent, {});
35609
35772
  if (hasFailed(props.result)) return jsxRuntime.jsx(FailedToLoadDataNotice, {});
35610
35773
  if (isEmpty(props.result)) return jsxRuntime.jsx(NoResultContentToShowNotice, _extends({}, headerProps));
35611
- var pivotConfig = init$c(props);
35774
+ var pivotConfig = init$d(props);
35612
35775
  var series$1 = series(pivotConfig, props.measure, props.result);
35613
35776
  var resultSet$1 = resultSet(props.result, props.measure, pivotConfig, props.stacked == '100%', checkForNullValue(props.dataSetId, props.dimension, props.timeDimension, textOverride, valueAlias));
35614
35777
  var showHeadline = headlineAvailable(props.order, props.headline, props.timeDimension);
@@ -36013,12 +36176,12 @@ var LineChartView = function LineChartView(props) {
36013
36176
  if (isLoading(props.result)) return jsxRuntime.jsx(LoadingComponent, {});
36014
36177
  if (hasFailed(props.result)) return jsxRuntime.jsx(FailedToLoadDataNotice, {});
36015
36178
  if (isEmpty(props.result)) return jsxRuntime.jsx(NoResultContentToShowNotice, _extends({}, headerProps));
36016
- var pivotConfig = init$c(props);
36179
+ var pivotConfig = init$d(props);
36017
36180
  var series$1 = series(pivotConfig, props.measure, props.result);
36018
36181
  var resultSet$1 = resultSet(props.result, props.measure, pivotConfig, props.stacked == '100%', checkForNullValue(props.dataSetId, props.dimension, props.timeDimension, textOverride, valueAlias));
36019
36182
  var buildTrends = function buildTrends() {
36020
36183
  if (props.order.length > 0 && props.trends && props.trends.length > 0 && acceptedTimeDimensions(props.timeDimension)) {
36021
- var trends = init$9({
36184
+ var trends = init$a({
36022
36185
  pivotConfig: pivotConfig,
36023
36186
  measures: props.measure,
36024
36187
  resultSet: resultSet$1,
@@ -36258,7 +36421,7 @@ var ScatterChartView = function ScatterChartView(props) {
36258
36421
  var measure = [];
36259
36422
  if (props.xMeasure) measure.push(props.xMeasure);
36260
36423
  if (props.yMeasure) measure.push(props.yMeasure);
36261
- var pivotConfig = init$c(props);
36424
+ var pivotConfig = init$d(props);
36262
36425
  var scatterData = props.result ? resultSet(props.result, measure, pivotConfig) : [];
36263
36426
  var xField = key([], [], props.xMeasure.field, props.xMeasure["function"]);
36264
36427
  scatterData.map(function (d) {
@@ -37624,7 +37787,7 @@ var PieChartView = function PieChartView(props) {
37624
37787
  }
37625
37788
  if (hasFailed(props.result)) return jsxRuntime.jsx(FailedToLoadDataNotice, {});
37626
37789
  if (isEmpty(props.result)) return jsxRuntime.jsx(NoResultContentToShowNotice, _extends({}, headerProps));
37627
- var pivotConfig = init$c({
37790
+ var pivotConfig = init$d({
37628
37791
  dimension: props.dimension
37629
37792
  });
37630
37793
  var rS = resultSet$1(props.result, pivotConfig, fakeQuery, false, checkForNullValue(props.dataSetId, props.dimension, props.timeDimension, textOverride, valueAlias));
@@ -41782,7 +41945,7 @@ var BubbleChartView = function BubbleChartView(props) {
41782
41945
  var measure = [];
41783
41946
  measure.push(props.xMeasure);
41784
41947
  measure.push(props.yMeasure);
41785
- var pivotConfig = init$c(props);
41948
+ var pivotConfig = init$d(props);
41786
41949
  var bubbleData = props.result ? resultSet(props.result, measure, pivotConfig) : [];
41787
41950
  var xField = key([], [], props.xMeasure.field, props.xMeasure["function"]);
41788
41951
  var zField = props.zMeasure ? key([], [], props.zMeasure.field, props.zMeasure["function"]) : '';
@@ -45272,7 +45435,7 @@ var LineChartV2View = function LineChartV2View(props) {
45272
45435
  var showHeadline = headlineAvailable(props.attributes.order, props.attributes.headline, null);
45273
45436
  var theme = useTheme();
45274
45437
  var LineChartV2Component = getComponentInterface(props.attributes.type);
45275
- var pivotConfig = init$c(props.attributes);
45438
+ var pivotConfig = init$d(props.attributes);
45276
45439
  var chartRepresentation = null;
45277
45440
  if (!isLoading(props.result) && !hasFailed(props.result) && !isEmpty(props.result) && LineChartV2Component.isRunnable(props.attributes)) {
45278
45441
  var _theme$charts$colors, _theme$charts, _props$attributes$goa;
@@ -45439,13 +45602,13 @@ var ComboChartView = function ComboChartView(props) {
45439
45602
  }
45440
45603
  if (isLoading(props.lineResult) || isLoading(props.barResult)) return jsxRuntime.jsx(LoadingComponent, {});
45441
45604
  if (hasFailed(props.lineResult) && hasFailed(props.barResult)) return jsxRuntime.jsx(FailedToLoadDataNotice, {});
45442
- var barPivotConfig = init$c({
45605
+ var barPivotConfig = init$d({
45443
45606
  dimension: props.barDimension,
45444
45607
  timeDimension: props.timeDimension
45445
45608
  });
45446
45609
  var barSeries = props.barResult ? series(barPivotConfig, props.barMeasure, props.barResult) : [];
45447
45610
  var barTimeseriesResultSet = props.barResult ? resultSet(props.barResult, props.barMeasure, barPivotConfig, props.stacked == '100%', checkForNullValue(props.dataSetId, props.barDimension, props.timeDimension, textOverride, valueAlias)) : [];
45448
- var linePivotConfig = init$c({
45611
+ var linePivotConfig = init$d({
45449
45612
  dimension: props.lineDimension,
45450
45613
  timeDimension: props.timeDimension
45451
45614
  });
@@ -45736,7 +45899,7 @@ var FunnelChartView = function FunnelChartView(props) {
45736
45899
  if (isLoading(props.result)) return jsxRuntime.jsx(LoadingComponent, {});
45737
45900
  if (hasFailed(props.result)) return jsxRuntime.jsx(FailedToLoadDataNotice, {});
45738
45901
  if (isEmpty(props.result)) return jsxRuntime.jsx(NoResultContentToShowNotice, _extends({}, headerProps));
45739
- var pivotConfig = init$c(props);
45902
+ var pivotConfig = init$d(props);
45740
45903
  var series$1 = series(pivotConfig, props.measure, props.result);
45741
45904
  var resultSet$1 = resultSet(props.result, props.measure, pivotConfig, false, checkForNullValue(props.dataSetId, props.dimension, props.timeDimension, textOverride, valueAlias));
45742
45905
  var showHeadline = headlineAvailable(props.order, props.headline, props.timeDimension);
@@ -48389,7 +48552,7 @@ var DataTable$2 = function DataTable(props) {
48389
48552
  }));
48390
48553
  };
48391
48554
 
48392
- var validate$2 = function validate(component, dataSets, dashboardBehaviour) {
48555
+ var validate$3 = function validate(component, dataSets, dashboardBehaviour) {
48393
48556
  try {
48394
48557
  var dataSet = find(dataSets, component.attributes.dataSetId);
48395
48558
  if (!dataSet) throw new DataSetNotFound(dataSets, component.attributes.dataSetId);
@@ -48915,7 +49078,7 @@ var BarChartV2View = function BarChartV2View(props) {
48915
49078
  var showHeadline = headlineAvailable(props.attributes.order, props.attributes.headline, null);
48916
49079
  var theme = useTheme();
48917
49080
  var BarChartV2Component = getComponentInterface(props.attributes.type);
48918
- var pivotConfig = init$c(props.attributes);
49081
+ var pivotConfig = init$d(props.attributes);
48919
49082
  var chartRepresentation = React.useMemo(function () {
48920
49083
  if (!isLoading(props.result) && !hasFailed(props.result) && !isEmpty(props.result) && BarChartV2Component.isRunnable(props.attributes)) {
48921
49084
  var _theme$charts$colors, _theme$charts, _props$attributes$goa;
@@ -49965,7 +50128,7 @@ var WaterfallChartView = function WaterfallChartView(props) {
49965
50128
  if (hasFailed(result)) return jsxRuntime.jsx(FailedToLoadDataNotice, {});
49966
50129
  if (isEmpty(result)) return jsxRuntime.jsx(NoResultContentToShowNotice, _extends({}, headerProps));
49967
50130
  var showHeadline = headlineAvailable(order, headline, timeDimension);
49968
- var pivotConfig = init$c(props);
50131
+ var pivotConfig = init$d(props);
49969
50132
  var _buildWaterfallChartR = buildWaterfallChartRepresentation({
49970
50133
  approxYAxisLabelCount: approxYAxisLabelCount === 'auto' ? 10 : approxYAxisLabelCount,
49971
50134
  axisTitles: axisTitles,
@@ -50293,7 +50456,7 @@ var AreaChartV2View = function AreaChartV2View(props) {
50293
50456
  var showHeadline = headlineAvailable(props.attributes.order, props.attributes.headline, null);
50294
50457
  var theme = useTheme();
50295
50458
  var AreaChartV2Component = getComponentInterface(props.attributes.type);
50296
- var pivotConfig = init$c(props.attributes);
50459
+ var pivotConfig = init$d(props.attributes);
50297
50460
  var chartRepresentation = null;
50298
50461
  if (!isLoading(props.result) && !hasFailed(props.result) && !isEmpty(props.result) && AreaChartV2Component.isRunnable(props.attributes)) {
50299
50462
  var _theme$charts$colors, _theme$charts, _props$attributes$goa;
@@ -50786,7 +50949,7 @@ var RadarChartView = function RadarChartView(props) {
50786
50949
  if (hasFailed(result)) return jsxRuntime.jsx(FailedToLoadDataNotice, {});
50787
50950
  if (isEmpty(result)) return jsxRuntime.jsx(NoResultContentToShowNotice, _extends({}, headerProps));
50788
50951
  var showHeadline = headlineAvailable(order, headline, timeDimension);
50789
- var pivotConfig = init$c(props);
50952
+ var pivotConfig = init$d(props);
50790
50953
  var chartRepresentation = buildRadarChartRepresentation({
50791
50954
  result: result,
50792
50955
  xAxisFormat: xAxisFormat,
@@ -50944,7 +51107,7 @@ var Component = function Component(props) {
50944
51107
  var setPartialAttributes = function setPartialAttributes(changes) {
50945
51108
  return props.updateComponentAttributes(componentInterface.setAttributes(props.component.attributes, changes));
50946
51109
  };
50947
- var validationError = validate$2(props.component, dashboard.dataSets, dashboardBehaviour);
51110
+ var validationError = validate$3(props.component, dashboard.dataSets, dashboardBehaviour);
50948
51111
  if (validationError) {
50949
51112
  if (validationError instanceof DataSetNotFound) {
50950
51113
  return jsxRuntime.jsx(Empty, {
@@ -51710,7 +51873,7 @@ var PopulatedComponentOptions = function PopulatedComponentOptions(props) {
51710
51873
  var theme = useTheme();
51711
51874
  var dashboardBehaviour = useDashboardBehaviourContext();
51712
51875
  var componentInterface = getComponentInterface(props.component.attributes.type);
51713
- var validationError = validate$2(props.component, dashboard.dataSets, dashboardBehaviour);
51876
+ var validationError = validate$3(props.component, dashboard.dataSets, dashboardBehaviour);
51714
51877
  var dataSet = find(dashboard.dataSets, props.component.attributes.dataSetId);
51715
51878
  var populatedCellOptions = [];
51716
51879
  var isCustomComponent = props.component.attributes.type === 'custom';
@@ -53719,7 +53882,7 @@ var wrap$1 = function wrap(metric) {
53719
53882
  return metric ? [metric] : [];
53720
53883
  };
53721
53884
  var MeasuresInput = function MeasuresInput(inputProps) {
53722
- var _inputProps$label, _inputProps$testId;
53885
+ var _inputProps$onDeleteI, _inputProps$label, _inputProps$testId;
53723
53886
  var _useState = React.useState(false),
53724
53887
  cannotRemove = _useState[0],
53725
53888
  showCannotRemove = _useState[1];
@@ -53784,7 +53947,7 @@ var MeasuresInput = function MeasuresInput(inputProps) {
53784
53947
  children: [jsxRuntime.jsx(ListView, {
53785
53948
  mode: mode,
53786
53949
  onOrderChange: inputProps.allowsMultiple ? onOrderChange : undefined,
53787
- onDeleteItem: inputProps.disableRemove || inputProps.dataSet.preAggregated ? undefined : onDeleteItem,
53950
+ onDeleteItem: (_inputProps$onDeleteI = inputProps.onDeleteItem) != null ? _inputProps$onDeleteI : inputProps.disableRemove || inputProps.dataSet.preAggregated ? undefined : onDeleteItem,
53788
53951
  items: inputProps.filterOptions ? inputProps.filterOptions(items) : items,
53789
53952
  newItem: {
53790
53953
  callToAction: (_inputProps$label = inputProps == null ? void 0 : inputProps.label) != null ? _inputProps$label : textOverride('add_metric', 'Add metric'),
@@ -54113,6 +54276,10 @@ function customMetricText(key, textOverride) {
54113
54276
  calculatedField: {
54114
54277
  title: textOverride('custom_metric_title.caclulated_field', 'Calculated Field'),
54115
54278
  subtext: textOverride('custom_metric_description.caclulated_field', 'Create a calculated field')
54279
+ },
54280
+ customBuildMetric: {
54281
+ title: textOverride('custom_metric_title.caclulated_field', 'Custom Metric Builder'),
54282
+ subtext: textOverride('custom_metric_description.caclulated_field', 'Create a custom build field')
54116
54283
  }
54117
54284
  };
54118
54285
  return values[key];
@@ -54139,6 +54306,11 @@ var buildInitOptions = function buildInitOptions(featureToggles, componentType,
54139
54306
  logDebug("Simple math custom field not made available, because it is not supported for the view " + componentInterface.title + ".");
54140
54307
  }
54141
54308
  }
54309
+ if (featureToggles.allowCustomBuildField && componentInterface.supportedCustomFields.customBuild) {
54310
+ initValues.push(_extends({}, customMetricText('customBuildMetric', textOverride), {
54311
+ value: 'customBuildMetric'
54312
+ }));
54313
+ }
54142
54314
  if (featureToggles.allowRoundedNumberCustomField && componentInterface.supportedCustomFields.roundedNumbers) {
54143
54315
  initValues.push(_extends({}, customMetricText('roundedNumber', textOverride), {
54144
54316
  value: 'roundedNumber'
@@ -54235,6 +54407,7 @@ var ModalType = /*#__PURE__*/function (ModalType) {
54235
54407
  ModalType["GoalLines"] = "goalLines";
54236
54408
  ModalType["CalculatedField"] = "calculatedField";
54237
54409
  ModalType["ItemPicker"] = "itemPicker";
54410
+ ModalType["CustomMetricBuilder"] = "customMetricBuilder";
54238
54411
  return ModalType;
54239
54412
  }({});
54240
54413
 
@@ -54511,6 +54684,9 @@ function getSubtext(customField, textOverride) {
54511
54684
  if (isMetric(customField)) {
54512
54685
  return customMetricText('calculatedField', textOverride).title;
54513
54686
  }
54687
+ if (isCustomBuildMetric(customField)) {
54688
+ return customMetricText('customBuildMetric', textOverride).title;
54689
+ }
54514
54690
  return '';
54515
54691
  }
54516
54692
  var mapCategoryToModalType = function mapCategoryToModalType(category) {
@@ -54529,6 +54705,8 @@ var mapCategoryToModalType = function mapCategoryToModalType(category) {
54529
54705
  return ModalType.DateCalculationCustomMetric;
54530
54706
  case 'calculatedField':
54531
54707
  return ModalType.CalculatedField;
54708
+ case 'customBuildMetric':
54709
+ return ModalType.CustomMetricBuilder;
54532
54710
  default:
54533
54711
  return undefined;
54534
54712
  }
@@ -62228,7 +62406,8 @@ var ConditionalModal = function ConditionalModal(props) {
62228
62406
  removeRuleGrouping: true,
62229
62407
  removeAggregateMaths: true,
62230
62408
  removeDateCalculations: true,
62231
- removeConditional: true
62409
+ removeConditional: true,
62410
+ removeCustomBuildMetric: true
62232
62411
  };
62233
62412
  return jsxRuntime.jsxs(Modal, {
62234
62413
  width: "4xl",
@@ -62781,7 +62960,8 @@ var PercentageModal = function PercentageModal(props) {
62781
62960
  removeRuleGrouping: true,
62782
62961
  removeAggregateMaths: true,
62783
62962
  removeDateCalculations: true,
62784
- removeConditional: true
62963
+ removeConditional: true,
62964
+ removeCustomBuildMetric: true
62785
62965
  };
62786
62966
  return jsxRuntime.jsxs(Modal, {
62787
62967
  width: "4xl",
@@ -63190,7 +63370,8 @@ var MathModal = function MathModal(props) {
63190
63370
  removeSimpleMaths: true,
63191
63371
  removeAggregateMaths: true,
63192
63372
  removeDateCalculations: true,
63193
- removeConditional: true
63373
+ removeConditional: true,
63374
+ removeCustomBuildMetric: true
63194
63375
  };
63195
63376
  var numberFields = filterFields(props.dataSet.fields, numberFieldsOptions);
63196
63377
  var options = getMathRadioButtonOptions(props.componentType);
@@ -63808,7 +63989,7 @@ var useRoundedNumberBuilder = function useRoundedNumberBuilder(initialValue, que
63808
63989
  var onCreateNewRoundedNumber = function onCreateNewRoundedNumber() {
63809
63990
  if (selected && selected.dataSetField) {
63810
63991
  var _selected$dataSetFiel;
63811
- var newCustomField = init$8(metricName, (_selected$dataSetFiel = selected.dataSetField) == null ? void 0 : _selected$dataSetFiel.id, selected.transformationFunctionKey == 'round_to_0_dp' ? 0 : 2, queryEngineConfig);
63992
+ var newCustomField = init$9(metricName, (_selected$dataSetFiel = selected.dataSetField) == null ? void 0 : _selected$dataSetFiel.id, selected.transformationFunctionKey == 'round_to_0_dp' ? 0 : 2, queryEngineConfig);
63812
63993
  onNewCustomField(_extends({}, newCustomField, {
63813
63994
  id: isEditing ? initialValue.id : newCustomField.id
63814
63995
  }));
@@ -64935,6 +65116,12 @@ function createNewValueFromSelected(selected) {
64935
65116
  fieldId: selected.id,
64936
65117
  "function": 'none'
64937
65118
  };
65119
+ case PropertyType.Aggregate:
65120
+ return {
65121
+ type: PropertyType.Aggregate,
65122
+ fieldId: selected.id,
65123
+ "function": undefined
65124
+ };
64938
65125
  case PropertyType.Operator:
64939
65126
  return initOperator(selected.id);
64940
65127
  case PropertyType.IfLogic:
@@ -64974,35 +65161,6 @@ var buildVariableItems = function buildVariableItems(variables, accepts) {
64974
65161
  };
64975
65162
  };
64976
65163
 
64977
- var buildFieldItems = function buildFieldItems(dataSet) {
64978
- var numberFieldsOptions = {
64979
- onlyFieldTypes: ['number'],
64980
- removePercentage: true,
64981
- removeSimpleMaths: true,
64982
- removeAggregateMaths: true,
64983
- removeDateCalculations: true,
64984
- removeConditional: true
64985
- };
64986
- var numberFields = filterFields(dataSet.fields, numberFieldsOptions);
64987
- var things = numberFields.map(function (field) {
64988
- return {
64989
- type: PropertyType.Field,
64990
- id: field.id,
64991
- title: field.publicName,
64992
- subtext: field.description,
64993
- editIcon: false,
64994
- icon: jsxRuntime.jsx(DataTypeIcon, {
64995
- icon: "number"
64996
- })
64997
- };
64998
- });
64999
- return {
65000
- id: PropertyType.Field,
65001
- title: 'Fields',
65002
- things: things
65003
- };
65004
- };
65005
-
65006
65164
  var DeleteAction = function DeleteAction(props) {
65007
65165
  var _useDashboardBehaviou = useDashboardBehaviourContext();
65008
65166
  var theme = useTheme();
@@ -65048,7 +65206,7 @@ var CustomMetricNumberInput = function CustomMetricNumberInput(props) {
65048
65206
  });
65049
65207
  };
65050
65208
 
65051
- var _formatFormula = function formatFormula(obj, isNested, textOverride) {
65209
+ var _formatFormula = function formatFormula(obj, isNested, textOverride, dataSet) {
65052
65210
  if (isNested === void 0) {
65053
65211
  isNested = false;
65054
65212
  }
@@ -65059,6 +65217,8 @@ var _formatFormula = function formatFormula(obj, isNested, textOverride) {
65059
65217
  return obj.value !== undefined ? obj.value.toString() : toBeDefined;
65060
65218
  case PropertyType.Variable:
65061
65219
  return "{{ " + obj.value + " }}";
65220
+ case PropertyType.Aggregate:
65221
+ return findField(dataSet, obj.fieldId).publicName + " " + (obj["function"] ? "(" + obj["function"] + ")" : '');
65062
65222
  case PropertyType.Field:
65063
65223
  return obj.fieldId;
65064
65224
  case PropertyType.Operator:
@@ -65071,27 +65231,27 @@ var _formatFormula = function formatFormula(obj, isNested, textOverride) {
65071
65231
  if (op === OperatorType.Divide && values.length > 2) {
65072
65232
  var grouped = values.reduce(function (acc, val, index) {
65073
65233
  if (index === 0) {
65074
- return _formatFormula(val, true, textOverride);
65234
+ return _formatFormula(val, true, textOverride, dataSet);
65075
65235
  }
65076
- return "(" + acc + " / " + _formatFormula(val, true, textOverride) + ")";
65236
+ return "(" + acc + " / " + _formatFormula(val, true, textOverride, dataSet) + ")";
65077
65237
  }, '');
65078
65238
  return isNested ? "(" + grouped + ")" : grouped;
65079
65239
  }
65080
65240
  var formattedValues = values.map(function (val) {
65081
- return _formatFormula(val, true, textOverride);
65241
+ return _formatFormula(val, true, textOverride, dataSet);
65082
65242
  }).join(" " + op + " ");
65083
65243
  return isNested ? "(" + formattedValues + ")" : formattedValues;
65084
65244
  }
65085
65245
  case PropertyType.IfLogic:
65086
65246
  {
65087
65247
  var formattedCases = obj.cases.map(function (c) {
65088
- var then = c.returns ? "then " + _formatFormula(c.returns, true, textOverride) : '';
65248
+ var then = c.returns ? "then " + _formatFormula(c.returns, true, textOverride, dataSet) : '';
65089
65249
  if (c.filter.length === 0) return toBeDefined;
65090
65250
  return "if (" + c.filter.map(function (f) {
65091
65251
  return filterCondition(f, c.filter.length > 1, textOverride);
65092
65252
  }).join(' || ') + ") " + then;
65093
65253
  }).join(' else ');
65094
- var elsePart = obj["else"] ? " else " + _formatFormula(obj["else"], true, textOverride) : '';
65254
+ var elsePart = obj["else"] ? " else " + _formatFormula(obj["else"], true, textOverride, dataSet) : '';
65095
65255
  return formattedCases + elsePart;
65096
65256
  }
65097
65257
  default:
@@ -65124,7 +65284,8 @@ var filterCondition = function filterCondition(filter, nested, textOverride) {
65124
65284
  };
65125
65285
 
65126
65286
  var MetricOverview = function MetricOverview(_ref) {
65127
- var metric = _ref.metric;
65287
+ var metric = _ref.metric,
65288
+ dataSet = _ref.dataSet;
65128
65289
  var _useDashboardBehaviou = useDashboardBehaviourContext(),
65129
65290
  textOverride = _useDashboardBehaviou.textOverride;
65130
65291
  if (!metric) {
@@ -65137,7 +65298,7 @@ var MetricOverview = function MetricOverview(_ref) {
65137
65298
  return jsxRuntime.jsx("code", {
65138
65299
  className: "" + code$1,
65139
65300
  "data-testid": "metric-overview",
65140
- children: _formatFormula(metric, false, textOverride)
65301
+ children: _formatFormula(metric, false, textOverride, dataSet)
65141
65302
  });
65142
65303
  };
65143
65304
  var code$1 = /*#__PURE__*/styles({
@@ -65254,6 +65415,152 @@ var availableItems = function availableItems() {
65254
65415
  }];
65255
65416
  };
65256
65417
 
65418
+ var CustomMetricAggregate = function CustomMetricAggregate(props) {
65419
+ var dashboardBehaviour = useDashboardBehaviourContext();
65420
+ var numberFieldsOptions = {
65421
+ onlyFieldTypes: ['number'],
65422
+ removePercentage: true,
65423
+ removeSimpleMaths: true,
65424
+ removeAggregateMaths: true,
65425
+ removeDateCalculations: true,
65426
+ removeConditional: true,
65427
+ removeCustomBuildMetric: true
65428
+ };
65429
+ return jsxRuntime.jsx(MeasuresInput, {
65430
+ id: props.id,
65431
+ testId: props.id,
65432
+ componentType: props.componentType,
65433
+ maxAllowed: 1,
65434
+ allowsMultiple: false,
65435
+ setPartialAttributes: function setPartialAttributes(_ref) {
65436
+ var measure = _ref.measure;
65437
+ return props.onChange(_extends({}, props.measure, {
65438
+ fieldId: measure.field,
65439
+ "function": measure["function"]
65440
+ }));
65441
+ },
65442
+ supportedAggregates: dashboardBehaviour.queryEngineConfig.supportedAggregates,
65443
+ attributes: {
65444
+ measure: {
65445
+ field: props.measure.fieldId,
65446
+ "function": props.measure["function"] || undefined
65447
+ }
65448
+ },
65449
+ dataSet: props.dataSet,
65450
+ fieldFilterOptions: numberFieldsOptions,
65451
+ onDeleteItem: props.onDeleteItem
65452
+ });
65453
+ };
65454
+
65455
+ var buildAggregateItems = function buildAggregateItems(dataSet) {
65456
+ var fieldsOptions = {
65457
+ onlyFieldTypes: ['number', 'string', 'boolean'],
65458
+ removePercentage: true,
65459
+ removeSimpleMaths: true,
65460
+ removeAggregateMaths: true,
65461
+ removeDateCalculations: true,
65462
+ removeConditional: true,
65463
+ removeRuleGrouping: true,
65464
+ removeCustomBuildMetric: true
65465
+ };
65466
+ var fields = filterFields(dataSet.fields, fieldsOptions);
65467
+ var things = fields.map(function (field) {
65468
+ return {
65469
+ type: PropertyType.Aggregate,
65470
+ id: field.id,
65471
+ title: field.publicName,
65472
+ subtext: field.description,
65473
+ editIcon: false,
65474
+ icon: field.dataType
65475
+ };
65476
+ });
65477
+ return {
65478
+ id: PropertyType.Aggregate,
65479
+ title: 'Aggregates',
65480
+ things: things
65481
+ };
65482
+ };
65483
+
65484
+ var buildFieldItems = function buildFieldItems(dataSet) {
65485
+ var numberFieldsOptions = {
65486
+ onlyFieldTypes: ['number'],
65487
+ removePercentage: true,
65488
+ removeSimpleMaths: true,
65489
+ removeAggregateMaths: true,
65490
+ removeDateCalculations: true,
65491
+ removeConditional: true,
65492
+ removeCustomBuildMetric: true
65493
+ };
65494
+ var numberFields = filterFields(dataSet.fields, numberFieldsOptions);
65495
+ var things = numberFields.map(function (field) {
65496
+ return {
65497
+ type: PropertyType.Field,
65498
+ id: field.id,
65499
+ title: field.publicName,
65500
+ subtext: field.description,
65501
+ editIcon: false,
65502
+ icon: field.dataType
65503
+ };
65504
+ });
65505
+ return {
65506
+ id: PropertyType.Field,
65507
+ title: 'Fields',
65508
+ things: things
65509
+ };
65510
+ };
65511
+
65512
+ function buildFieldsAndAggregates(value, dataSet, parentHasAggregate, parentHasField) {
65513
+ var isOperator = value.type === PropertyType.Operator;
65514
+ var isIfLogic = value.type === PropertyType.IfLogic;
65515
+ var hasAggregate = isOperator && value.values.some(function (v) {
65516
+ return v.type === PropertyType.Aggregate;
65517
+ });
65518
+ var hasField = isOperator && value.values.some(function (v) {
65519
+ return v.type === PropertyType.Field;
65520
+ });
65521
+ var hasAggregateCase = isIfLogic && value.cases.some(function (c) {
65522
+ var _c$returns;
65523
+ return ((_c$returns = c.returns) == null ? void 0 : _c$returns.type) === 'aggregate';
65524
+ });
65525
+ var hasFieldCase = isIfLogic && value.cases.some(function (c) {
65526
+ var _c$returns2;
65527
+ return ((_c$returns2 = c.returns) == null ? void 0 : _c$returns2.type) === 'field';
65528
+ });
65529
+ var hasNoReturns = isIfLogic && value.cases.every(function (c) {
65530
+ return !c.returns;
65531
+ });
65532
+ var updatedItems = [];
65533
+ var updatedParentHasAggregate = parentHasAggregate != null ? parentHasAggregate : false;
65534
+ var updatedParentHasField = parentHasField != null ? parentHasField : false;
65535
+ if (hasAggregate) {
65536
+ updatedParentHasAggregate = true;
65537
+ }
65538
+ if (hasField) {
65539
+ updatedParentHasField = true;
65540
+ }
65541
+ if (isOperator) {
65542
+ if (!updatedParentHasField) updatedItems.push(buildAggregateItems(dataSet));
65543
+ if (!updatedParentHasAggregate) updatedItems.push(buildFieldItems(dataSet));
65544
+ }
65545
+ if (isIfLogic) {
65546
+ if (!updatedParentHasField && hasAggregateCase) {
65547
+ updatedItems.push(buildAggregateItems(dataSet));
65548
+ }
65549
+ if (!updatedParentHasAggregate && hasFieldCase) {
65550
+ updatedItems.push(buildFieldItems(dataSet));
65551
+ }
65552
+ if (hasNoReturns) {
65553
+ updatedItems.push(buildAggregateItems(dataSet));
65554
+ updatedItems.push(buildFieldItems(dataSet));
65555
+ }
65556
+ }
65557
+ return {
65558
+ updatedItems: updatedItems,
65559
+ updatedParentHasAggregate: updatedParentHasAggregate,
65560
+ updatedParentHasField: updatedParentHasField
65561
+ };
65562
+ }
65563
+
65257
65564
  var operatorMap = function operatorMap(operator) {
65258
65565
  switch (operator) {
65259
65566
  case OperatorType.Divide:
@@ -65341,13 +65648,25 @@ var _RecursiveMetric = function RecursiveMetric(_ref) {
65341
65648
  index = _ref.index,
65342
65649
  onDeleteItem = _ref.onDeleteItem,
65343
65650
  parentIsIfLogic = _ref.parentIsIfLogic,
65344
- isEditing = _ref.isEditing;
65651
+ isEditing = _ref.isEditing,
65652
+ parentHasAggregate = _ref.parentHasAggregate,
65653
+ parentHasField = _ref.parentHasField;
65345
65654
  var _useDashboardBehaviou2 = useDashboardBehaviourContext(),
65346
65655
  variables = _useDashboardBehaviou2.variables,
65347
65656
  textOverride = _useDashboardBehaviou2.textOverride;
65348
65657
  var handleBuildMetric = function handleBuildMetric(selected) {
65349
65658
  _updateValue(addToOperator(value, selected));
65350
65659
  };
65660
+ if (value.type === PropertyType.Aggregate) {
65661
+ return jsxRuntime.jsx(CustomMetricAggregate, {
65662
+ measure: value,
65663
+ onChange: _updateValue,
65664
+ dataSet: dataSet,
65665
+ id: level + "-measure-" + index,
65666
+ onDeleteItem: onDeleteItem,
65667
+ componentType: "progress"
65668
+ });
65669
+ }
65351
65670
  if (value.type === PropertyType.NumberInput) {
65352
65671
  var handleUpdatingValue = function handleUpdatingValue(event) {
65353
65672
  var itemToUpdate = _extends({}, value);
@@ -65380,8 +65699,14 @@ var _RecursiveMetric = function RecursiveMetric(_ref) {
65380
65699
  operator: [OperatorType.Add, OperatorType.Divide, OperatorType.Subtract, OperatorType.Multiply],
65381
65700
  logic: [PropertyType.NumberInput]
65382
65701
  }));
65383
- if (value.type !== PropertyType.IfLogic && !parentIsIfLogic) {
65384
- items.push(buildFieldItems(dataSet));
65702
+ if (!parentIsIfLogic) {
65703
+ var _buildFieldsAndAggreg = buildFieldsAndAggregates(value, dataSet, parentHasAggregate, parentHasField),
65704
+ updatedItems = _buildFieldsAndAggreg.updatedItems,
65705
+ updatedParentHasAggregate = _buildFieldsAndAggreg.updatedParentHasAggregate,
65706
+ updatedParentHasField = _buildFieldsAndAggreg.updatedParentHasField;
65707
+ items.push.apply(items, updatedItems);
65708
+ parentHasAggregate = updatedParentHasAggregate;
65709
+ parentHasField = updatedParentHasField;
65385
65710
  }
65386
65711
  if (variables != null && variables.variables) {
65387
65712
  var builtVariables = buildVariableItems(variables.variables, 'numbers');
@@ -65450,7 +65775,9 @@ var _RecursiveMetric = function RecursiveMetric(_ref) {
65450
65775
  ifCase.returns = undefined;
65451
65776
  _updateValue(_extends({}, value));
65452
65777
  },
65453
- parentIsIfLogic: parentIsIfLogic
65778
+ parentIsIfLogic: parentIsIfLogic,
65779
+ parentHasAggregate: parentHasAggregate,
65780
+ parentHasField: parentHasField
65454
65781
  }), !ifCase.returns && jsxRuntime.jsx(AddItem, {
65455
65782
  items: items,
65456
65783
  onSelect: handleUpdateCase,
@@ -65473,7 +65800,9 @@ var _RecursiveMetric = function RecursiveMetric(_ref) {
65473
65800
  value["else"] = undefined;
65474
65801
  _updateValue(_extends({}, value));
65475
65802
  },
65476
- parentIsIfLogic: parentIsIfLogic
65803
+ parentIsIfLogic: parentIsIfLogic,
65804
+ parentHasAggregate: parentHasAggregate,
65805
+ parentHasField: parentHasField
65477
65806
  }), !value["else"] && jsxRuntime.jsx(AddItem, {
65478
65807
  items: items,
65479
65808
  onSelect: function onSelect(selected) {
@@ -65516,7 +65845,9 @@ var _RecursiveMetric = function RecursiveMetric(_ref) {
65516
65845
  var newValue = deleteOperatorValue(value, index);
65517
65846
  _updateValue(newValue);
65518
65847
  },
65519
- parentIsIfLogic: parentIsIfLogic
65848
+ parentIsIfLogic: parentIsIfLogic,
65849
+ parentHasAggregate: parentHasAggregate,
65850
+ parentHasField: parentHasField
65520
65851
  })
65521
65852
  }), value.values.length - 1 !== index && jsxRuntime.jsx("div", {
65522
65853
  className: styles({
@@ -65603,7 +65934,8 @@ var CustomMetric = function CustomMetric(props) {
65603
65934
  }), jsxRuntime.jsx(View, {
65604
65935
  marginTop: 20,
65605
65936
  children: jsxRuntime.jsx(MetricOverview, {
65606
- metric: state.wipCustomMetric
65937
+ metric: state.wipCustomMetric,
65938
+ dataSet: props.dataSet
65607
65939
  })
65608
65940
  })]
65609
65941
  })
@@ -65855,6 +66187,117 @@ var ItemPicker = function ItemPicker(props) {
65855
66187
  });
65856
66188
  };
65857
66189
 
66190
+ var emptyConditional$1 = {
66191
+ publicName: '',
66192
+ metric: undefined
66193
+ };
66194
+ var useCustomMetricBuilderModal = function useCustomMetricBuilderModal(queryEngineConfig, customField, onUpdateField) {
66195
+ var isEditing = !!customField;
66196
+ var _useState = React.useState(emptyConditional$1),
66197
+ state = _useState[0],
66198
+ setState = _useState[1];
66199
+ React.useEffect(function () {
66200
+ if (customField) {
66201
+ setState({
66202
+ publicName: customField.publicName,
66203
+ metric: customField.metricAtrributes
66204
+ });
66205
+ } else {
66206
+ setState(emptyConditional$1);
66207
+ }
66208
+ }, [JSON.stringify(customField)]);
66209
+ var handleUpsertField = function handleUpsertField() {
66210
+ if (state.metric) {
66211
+ var _customField$id;
66212
+ var newCustomField = init$8(state.publicName, state.metric, queryEngineConfig);
66213
+ onUpdateField(_extends({}, newCustomField, {
66214
+ id: (_customField$id = customField == null ? void 0 : customField.id) != null ? _customField$id : newCustomField.id
66215
+ }));
66216
+ }
66217
+ };
66218
+ React.useEffect(function () {
66219
+ return logDebug(state.metric);
66220
+ }, [JSON.stringify(state.metric)]);
66221
+ var onChange = function onChange(partial) {
66222
+ setState(_extends({}, state, partial));
66223
+ };
66224
+ return {
66225
+ state: state,
66226
+ handleUpsertField: handleUpsertField,
66227
+ onChange: onChange,
66228
+ isEditing: isEditing,
66229
+ isValid: validate$2(queryEngineConfig, state.metric).isValid && state.publicName.length > 0
66230
+ };
66231
+ };
66232
+
66233
+ var CustomMetricBuilderModal = function CustomMetricBuilderModal(props) {
66234
+ var dataSet = props.dataSet;
66235
+ var _useDashboardBehaviou = useDashboardBehaviourContext(),
66236
+ textOverride = _useDashboardBehaviou.textOverride,
66237
+ queryEngineConfig = _useDashboardBehaviou.queryEngineConfig;
66238
+ var _useCustomMetricBuild = useCustomMetricBuilderModal(queryEngineConfig, props.initialValue, props.onNewCustomField),
66239
+ handleUpsertField = _useCustomMetricBuild.handleUpsertField,
66240
+ state = _useCustomMetricBuild.state,
66241
+ _onChange = _useCustomMetricBuild.onChange,
66242
+ isEditing = _useCustomMetricBuild.isEditing,
66243
+ isValid = _useCustomMetricBuild.isValid;
66244
+ var supportedTypes = function () {
66245
+ var supportedLogicTypes = getComponentInterface(props.componentType).supportedCustomFields.customBuild;
66246
+ if (typeof supportedLogicTypes !== 'boolean') return supportedLogicTypes;
66247
+ return undefined;
66248
+ }();
66249
+ return jsxRuntime.jsxs(Modal, {
66250
+ width: "4xl",
66251
+ isOpen: props.show,
66252
+ onClose: props.onClose,
66253
+ disableDnD: true,
66254
+ children: [jsxRuntime.jsx(Modal.Header, {
66255
+ title: customMetricText('customBuildMetric', textOverride).title
66256
+ }), jsxRuntime.jsxs(Modal.Content, {
66257
+ children: [jsxRuntime.jsx(PanelProperty, {
66258
+ children: jsxRuntime.jsx(Input, {
66259
+ id: "custom-metric-name",
66260
+ placeholder: textOverride('metric_name', 'Metric name'),
66261
+ label: textOverride('metric_name', 'Metric name'),
66262
+ value: state.publicName,
66263
+ onChange: function onChange(event) {
66264
+ return _onChange({
66265
+ publicName: event.target.value
66266
+ });
66267
+ }
66268
+ })
66269
+ }), supportedTypes && jsxRuntime.jsx(CustomMetric, {
66270
+ dataSet: dataSet,
66271
+ metric: state.metric,
66272
+ onChange: function onChange(metric) {
66273
+ return _onChange({
66274
+ metric: metric
66275
+ });
66276
+ },
66277
+ supportedTypes: supportedTypes
66278
+ }, isEditing + "-" + state.publicName)]
66279
+ }), jsxRuntime.jsx(Modal.Footer, {
66280
+ buttons: "end",
66281
+ children: jsxRuntime.jsxs(ButtonGroup, {
66282
+ children: [jsxRuntime.jsx(Button$2, {
66283
+ onClick: function onClick() {
66284
+ return props.onClose();
66285
+ },
66286
+ secondary: true,
66287
+ children: textOverride('cancel', 'Cancel')
66288
+ }), jsxRuntime.jsx(Button$2, {
66289
+ onClick: function onClick() {
66290
+ return handleUpsertField();
66291
+ },
66292
+ disabled: !isValid,
66293
+ testId: (isEditing ? 'update' : 'create') + "-custom-metric-builder",
66294
+ children: isEditing ? textOverride('update', 'Update') : textOverride('create', 'Create')
66295
+ })]
66296
+ })
66297
+ })]
66298
+ });
66299
+ };
66300
+
65858
66301
  var ModalToShow = /*#__PURE__*/function (ModalToShow) {
65859
66302
  ModalToShow[ModalToShow["Neither"] = 0] = "Neither";
65860
66303
  ModalToShow[ModalToShow["Library"] = 1] = "Library";
@@ -65928,6 +66371,8 @@ var ModalRouting = function ModalRouting() {
65928
66371
  }), modalType);
65929
66372
  case ModalType.ConditionalCustomMetric:
65930
66373
  return jsxRuntime.jsx(ConditionalModal, _extends({}, attributes), modalType);
66374
+ case ModalType.CustomMetricBuilder:
66375
+ return jsxRuntime.jsx(CustomMetricBuilderModal, _extends({}, attributes), modalType);
65931
66376
  case ModalType.PercentageCustomMetric:
65932
66377
  return jsxRuntime.jsx(PercentageModal, _extends({}, attributes), modalType);
65933
66378
  case ModalType.MathCustomMetric:
@@ -66629,7 +67074,7 @@ var fromToken = function fromToken(token) {
66629
67074
  });
66630
67075
  };
66631
67076
 
66632
- var init$d = function init(dashboardSessionToken, dataAccessToken, queryEngineAccessToken, dashboardAdminOverrideToken) {
67077
+ var init$e = function init(dashboardSessionToken, dataAccessToken, queryEngineAccessToken, dashboardAdminOverrideToken) {
66633
67078
  var dashboardAccessContent = fromToken(dashboardSessionToken);
66634
67079
  if (!('scope' in dashboardAccessContent)) {
66635
67080
  dashboardAccessContent.scope = 'read_write';
@@ -66695,7 +67140,7 @@ var fetchIdentityConfig = /*#__PURE__*/function () {
66695
67140
  throw new FailedToLoadIdentity('Failed to fetch identity config.');
66696
67141
  case 6:
66697
67142
  dashboardAdminOverride = isClientSide() ? getDashboardAdminOverride(window.location.href) : null;
66698
- identityConfig = init$d(tokens.dashboardAccessToken, tokens.dataAccessToken, tokens.queryEngineAccessToken, dashboardAdminOverride);
67143
+ identityConfig = init$e(tokens.dashboardAccessToken, tokens.dataAccessToken, tokens.queryEngineAccessToken, dashboardAdminOverride);
66699
67144
  return _context.abrupt("return", {
66700
67145
  identityConfig: identityConfig,
66701
67146
  tokens: tokens
@@ -67322,7 +67767,7 @@ var Header = /*#__PURE__*/function () {
67322
67767
  function Header(title) {
67323
67768
  /** The header component. */
67324
67769
  this.component = undefined;
67325
- var newHeader = init$a('New Header');
67770
+ var newHeader = init$b('New Header');
67326
67771
  if (title) {
67327
67772
  newHeader = _extends({}, newHeader, {
67328
67773
  displayTitle: title
@@ -68032,7 +68477,7 @@ function getOptionsOrders(dataSetField) {
68032
68477
  }
68033
68478
 
68034
68479
  var commonToQueries = function commonToQueries(attributes, dataSet, queryEngineConfig, params) {
68035
- var _Query$build = build$a(dataSet, attributes.measure, attributes.order, attributes.dimension,
68480
+ var _Query$build = build$b(dataSet, attributes.measure, attributes.order, attributes.dimension,
68036
68481
  // @ts-ignore
68037
68482
  attributes.timeDimension || null, attributes.limit, attributes.offset, queryEngineConfig, params),
68038
68483
  query = _Query$build.query,
@@ -68065,8 +68510,8 @@ var toQueries$a = commonToQueries;
68065
68510
  var toQueries$b = commonToQueries;
68066
68511
 
68067
68512
  var buildMainQueries = function buildMainQueries(attributes, dataSet, queryEngineConfig, params) {
68068
- var line = build$a(dataSet, attributes.lineMeasure, attributes.order, attributes.lineDimension, attributes.timeDimension, attributes.limit, attributes.offset, queryEngineConfig, params);
68069
- var bar = build$a(dataSet, attributes.barMeasure, attributes.order, attributes.barDimension, attributes.timeDimension, attributes.limit, attributes.offset, queryEngineConfig, params);
68513
+ var line = build$b(dataSet, attributes.lineMeasure, attributes.order, attributes.lineDimension, attributes.timeDimension, attributes.limit, attributes.offset, queryEngineConfig, params);
68514
+ var bar = build$b(dataSet, attributes.barMeasure, attributes.order, attributes.barDimension, attributes.timeDimension, attributes.limit, attributes.offset, queryEngineConfig, params);
68070
68515
  return {
68071
68516
  bar: bar,
68072
68517
  line: line
@@ -68085,7 +68530,7 @@ var toQueries$c = function toQueries(attributes, dataSet, queryEngineConfig, par
68085
68530
  };
68086
68531
 
68087
68532
  var buildMainQuery = function buildMainQuery(attributes, dataSet, queryEngineConfig, params) {
68088
- var _Query$build = build$a(dataSet, attributes.measure, [], [], null, 1, attributes.offset, queryEngineConfig, params),
68533
+ var _Query$build = build$b(dataSet, attributes.measure, [], [], null, 1, attributes.offset, queryEngineConfig, params),
68089
68534
  query = _Query$build.query,
68090
68535
  measureDescription = _Query$build.measureDescription;
68091
68536
 
@@ -68113,7 +68558,7 @@ var buildMainQuery = function buildMainQuery(attributes, dataSet, queryEngineCon
68113
68558
  };
68114
68559
  var buildDeltaQuery = function buildDeltaQuery(dataSet, attributes, queryEngineConfig, params) {
68115
68560
  if (!attributes.deltaTimeDimension) return null;
68116
- return build$a(dataSet, attributes.measure, [{
68561
+ return build$b(dataSet, attributes.measure, [{
68117
68562
  field: attributes.deltaTimeDimension.field,
68118
68563
  direction: 'asc',
68119
68564
  "function": attributes.deltaTimeDimension.truncate
@@ -68145,7 +68590,7 @@ var toQueries$e = function toQueries(attributes, dataSet, queryEngineConfig, par
68145
68590
  var measures = [];
68146
68591
  attributes.xMeasure && measures.push(attributes.xMeasure);
68147
68592
  attributes.yMeasure && measures.push(attributes.yMeasure);
68148
- var _Query$build = build$a(dataSet, measures, attributes.order, attributes.dimension, attributes.timeDimension, attributes.limit, attributes.offset, queryEngineConfig, params),
68593
+ var _Query$build = build$b(dataSet, measures, attributes.order, attributes.dimension, attributes.timeDimension, attributes.limit, attributes.offset, queryEngineConfig, params),
68149
68594
  query = _Query$build.query,
68150
68595
  measureDescription = _Query$build.measureDescription;
68151
68596
  var resultFields = toResultFields([measureDescription], queryEngineConfig);
@@ -68159,7 +68604,7 @@ var toQueries$f = function toQueries(attributes, dataSet, queryEngineConfig, par
68159
68604
  var measures = [];
68160
68605
  attributes.xMeasure && measures.push(attributes.xMeasure);
68161
68606
  attributes.yMeasure && measures.push(attributes.yMeasure);
68162
- var _Query$build = build$a(dataSet, measures, attributes.order, attributes.dimension, attributes.timeDimension, attributes.limit, attributes.offset, queryEngineConfig, params),
68607
+ var _Query$build = build$b(dataSet, measures, attributes.order, attributes.dimension, attributes.timeDimension, attributes.limit, attributes.offset, queryEngineConfig, params),
68163
68608
  query = _Query$build.query,
68164
68609
  measureDescription = _Query$build.measureDescription;
68165
68610
  var resultFields = toResultFields([measureDescription], queryEngineConfig);
@@ -69529,7 +69974,7 @@ var VizzlyServices = /*#__PURE__*/function () {
69529
69974
  }
69530
69975
  return undefined;
69531
69976
  }();
69532
- runQueriesCallback = getRunQueriesCallback(service.identityConfig, service.queryEngineConfig, build$c(defaultText, params == null ? void 0 : params.dateFilterOptions), (params == null ? void 0 : params.variables) || {}, params == null ? void 0 : params.runQueries, params == null ? void 0 : params.data, queryEngineEndpoint);
69977
+ runQueriesCallback = getRunQueriesCallback(service.identityConfig, service.queryEngineConfig, build$d(defaultText, params == null ? void 0 : params.dateFilterOptions), (params == null ? void 0 : params.variables) || {}, params == null ? void 0 : params.runQueries, params == null ? void 0 : params.data, queryEngineEndpoint);
69533
69978
  fetch = /*#__PURE__*/function () {
69534
69979
  var _ref = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee10() {
69535
69980
  var _params$abortControll;
@@ -72473,7 +72918,7 @@ var GlobalProviderContents = function GlobalProviderContents(props) {
72473
72918
  }
72474
72919
  };
72475
72920
  var resolvedDateFilterOptions = (_props$dateFilterOpti = props.dateFilterOptions) != null ? _props$dateFilterOpti : props.dateTimeFilterOptions;
72476
- var runQueriesCallback = getRunQueriesCallback(session.identityConfig, session.queryEngineConfig, build$c(textOverride, resolvedDateFilterOptions), variables.variables, props.runQueries, props.data, props.queryEngineEndpoint, props.timeZone);
72921
+ var runQueriesCallback = getRunQueriesCallback(session.identityConfig, session.queryEngineConfig, build$d(textOverride, resolvedDateFilterOptions), variables.variables, props.runQueries, props.data, props.queryEngineEndpoint, props.timeZone);
72477
72922
  var aiOnAction = /*#__PURE__*/function () {
72478
72923
  var _ref3 = _asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee3(conversationId, messageId, actionOptions) {
72479
72924
  return _regeneratorRuntime().wrap(function _callee3$(_context3) {