@malloydata/malloy-explorer 0.0.277-dev250515002611 → 0.0.278-dev250516210719
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/index.cjs +362 -163
- package/dist/cjs/index.cjs.map +1 -1
- package/dist/esm/index.js +363 -164
- package/dist/esm/index.js.map +1 -1
- package/dist/types/components/QueryPanel/FilterLiteralEditor.d.ts +10 -0
- package/dist/types/components/QueryPanel/LiteralValueEditor.d.ts +4 -2
- package/dist/types/components/SourcePanel/hooks/useOperations.d.ts +4 -0
- package/dist/types/components/utils/filters.d.ts +5 -0
- package/dist/types/components/utils/segment.d.ts +4 -0
- package/package.json +10 -8
package/dist/cjs/index.cjs
CHANGED
|
@@ -19,6 +19,7 @@ const jsxRuntime = require("react/jsx-runtime");
|
|
|
19
19
|
const React = require("react");
|
|
20
20
|
const QB = require("@malloydata/malloy-query-builder");
|
|
21
21
|
const malloyTag = require("@malloydata/malloy-tag");
|
|
22
|
+
const malloyFilter = require("@malloydata/malloy-filter");
|
|
22
23
|
require("@malloydata/render/webcomponent");
|
|
23
24
|
const ReactDOM = require("react-dom");
|
|
24
25
|
function _interopNamespaceDefault(e) {
|
|
@@ -29949,6 +29950,11 @@ function getViewDefinition(parent) {
|
|
|
29949
29950
|
return parent instanceof QB.ASTArrowQueryDefinition ? parent.view : parent.definition;
|
|
29950
29951
|
}
|
|
29951
29952
|
function getInputSchemaFromViewParent(parent) {
|
|
29953
|
+
if (!parent) {
|
|
29954
|
+
return {
|
|
29955
|
+
fields: []
|
|
29956
|
+
};
|
|
29957
|
+
}
|
|
29952
29958
|
const definition = getViewDefinition(parent);
|
|
29953
29959
|
return definition.getInputSchema();
|
|
29954
29960
|
}
|
|
@@ -32399,12 +32405,49 @@ const styles$g = {
|
|
|
32399
32405
|
$$css: true
|
|
32400
32406
|
}
|
|
32401
32407
|
};
|
|
32408
|
+
function toFullName(path, name) {
|
|
32409
|
+
return [...path || [], name].join(".");
|
|
32410
|
+
}
|
|
32402
32411
|
function segmentHasLimit(segment) {
|
|
32403
32412
|
return segment.operations.items.find((operation) => operation instanceof QB.ASTLimitViewOperation) !== void 0;
|
|
32404
32413
|
}
|
|
32405
32414
|
function segmentHasOrderBy(segment, name) {
|
|
32406
32415
|
return segment.operations.items.find((operation) => operation instanceof QB.ASTOrderByViewOperation && operation.name === name) !== void 0;
|
|
32407
32416
|
}
|
|
32417
|
+
function getOutputNameToInputNameMap(segment) {
|
|
32418
|
+
const nameMap = /* @__PURE__ */ new Map();
|
|
32419
|
+
for (const operation of segment.operations.items) {
|
|
32420
|
+
if (operation instanceof QB.ASTGroupByViewOperation || operation instanceof QB.ASTAggregateViewOperation) {
|
|
32421
|
+
const reference = operation.field.getReference();
|
|
32422
|
+
nameMap.set(operation.name, toFullName(reference.path, reference.name));
|
|
32423
|
+
}
|
|
32424
|
+
}
|
|
32425
|
+
return nameMap;
|
|
32426
|
+
}
|
|
32427
|
+
function segmentHasOrderBySourceField(segment, path, name) {
|
|
32428
|
+
const nameMap = getOutputNameToInputNameMap(segment);
|
|
32429
|
+
const fullInputName = toFullName(path, name);
|
|
32430
|
+
return !!segment.operations.items.find((operation) => {
|
|
32431
|
+
if (operation instanceof QB.ASTOrderByViewOperation && nameMap.has(operation.name)) {
|
|
32432
|
+
return fullInputName === nameMap.get(operation.name);
|
|
32433
|
+
}
|
|
32434
|
+
return false;
|
|
32435
|
+
});
|
|
32436
|
+
}
|
|
32437
|
+
function areReferencesEqual(path1, name1, path2, name2) {
|
|
32438
|
+
return name1 === name2 && (path1 || []).join(".") === (path2 || []).join(".");
|
|
32439
|
+
}
|
|
32440
|
+
function segmentHasFieldInOutputSpace(segment, path, name) {
|
|
32441
|
+
const match = segment.operations.items.find((operation) => {
|
|
32442
|
+
if (operation instanceof QB.ASTGroupByViewOperation || operation instanceof QB.ASTAggregateViewOperation) {
|
|
32443
|
+
const reference = operation.field.getReference();
|
|
32444
|
+
const isEqual = areReferencesEqual(path, name, reference.path, reference.name);
|
|
32445
|
+
return isEqual;
|
|
32446
|
+
}
|
|
32447
|
+
return false;
|
|
32448
|
+
});
|
|
32449
|
+
return !!match;
|
|
32450
|
+
}
|
|
32408
32451
|
function segmentNestNo(segment, name) {
|
|
32409
32452
|
return segment.operations.items.reduce((acc, operation) => {
|
|
32410
32453
|
if (operation instanceof QB.ASTNestViewOperation) {
|
|
@@ -32459,6 +32502,19 @@ function addNest(view, field) {
|
|
|
32459
32502
|
}
|
|
32460
32503
|
segment.addNest(field.name, rename);
|
|
32461
32504
|
}
|
|
32505
|
+
function addOrderByFromSource(view, path, name, direction = "desc") {
|
|
32506
|
+
const fullInputName = toFullName(path, name);
|
|
32507
|
+
let orderByName = name;
|
|
32508
|
+
const segment = view.getOrAddDefaultSegment();
|
|
32509
|
+
const nameMap = getOutputNameToInputNameMap(segment);
|
|
32510
|
+
for (const entry of nameMap.entries()) {
|
|
32511
|
+
if (entry[1] === fullInputName) {
|
|
32512
|
+
orderByName = entry[0];
|
|
32513
|
+
break;
|
|
32514
|
+
}
|
|
32515
|
+
}
|
|
32516
|
+
segment.addOrderBy(orderByName, direction);
|
|
32517
|
+
}
|
|
32462
32518
|
function addOrderBy(view, field, direction = "desc") {
|
|
32463
32519
|
const segment = view.getOrAddDefaultSegment();
|
|
32464
32520
|
segment.addOrderBy(field.name, direction);
|
|
@@ -32472,6 +32528,9 @@ function addFilter(view, field, path, filter) {
|
|
|
32472
32528
|
}
|
|
32473
32529
|
}
|
|
32474
32530
|
function getSegmentIfPresent(parent) {
|
|
32531
|
+
if (!parent) {
|
|
32532
|
+
return void 0;
|
|
32533
|
+
}
|
|
32475
32534
|
const definition = getViewDefinition(parent);
|
|
32476
32535
|
if (definition instanceof QB.ASTSegmentViewDefinition) {
|
|
32477
32536
|
return definition;
|
|
@@ -33272,94 +33331,6 @@ class ErrorElement extends React__namespace.Component {
|
|
|
33272
33331
|
return this.props.children;
|
|
33273
33332
|
}
|
|
33274
33333
|
}
|
|
33275
|
-
function FilterOperations({
|
|
33276
|
-
rootQuery,
|
|
33277
|
-
filters
|
|
33278
|
-
}) {
|
|
33279
|
-
const {
|
|
33280
|
-
setQuery
|
|
33281
|
-
} = React.useContext(QueryEditorContext);
|
|
33282
|
-
if (filters.length === 0) {
|
|
33283
|
-
return null;
|
|
33284
|
-
}
|
|
33285
|
-
return /* @__PURE__ */ jsxRuntime.jsxs("div", {
|
|
33286
|
-
children: [/* @__PURE__ */ jsxRuntime.jsx("div", {
|
|
33287
|
-
..._stylex.props(styles$s.title),
|
|
33288
|
-
children: "filter by"
|
|
33289
|
-
}), /* @__PURE__ */ jsxRuntime.jsx("div", {
|
|
33290
|
-
..._stylex.props(styles$s.tokenContainer),
|
|
33291
|
-
children: filters.map((filterOperation, key2) => {
|
|
33292
|
-
return /* @__PURE__ */ jsxRuntime.jsx(ErrorElement, {
|
|
33293
|
-
fallback: /* @__PURE__ */ jsxRuntime.jsxs("div", {
|
|
33294
|
-
children: ["Invalid filter", /* @__PURE__ */ jsxRuntime.jsx(ClearButton, {
|
|
33295
|
-
onClick: () => {
|
|
33296
|
-
filterOperation.delete();
|
|
33297
|
-
setQuery == null ? void 0 : setQuery(rootQuery.build());
|
|
33298
|
-
}
|
|
33299
|
-
})]
|
|
33300
|
-
}),
|
|
33301
|
-
children: /* @__PURE__ */ jsxRuntime.jsx(SingleFilterOperation, {
|
|
33302
|
-
filterOperation,
|
|
33303
|
-
rootQuery
|
|
33304
|
-
})
|
|
33305
|
-
}, key2);
|
|
33306
|
-
})
|
|
33307
|
-
})]
|
|
33308
|
-
});
|
|
33309
|
-
}
|
|
33310
|
-
function SingleFilterOperation({
|
|
33311
|
-
rootQuery,
|
|
33312
|
-
filterOperation
|
|
33313
|
-
}) {
|
|
33314
|
-
const {
|
|
33315
|
-
fieldReference,
|
|
33316
|
-
filterString
|
|
33317
|
-
} = filterOperation.filter;
|
|
33318
|
-
const filter = filterOperation.filter.getFilter();
|
|
33319
|
-
const fieldInfo = fieldReference.getFieldInfo();
|
|
33320
|
-
const {
|
|
33321
|
-
setQuery
|
|
33322
|
-
} = React.useContext(QueryEditorContext);
|
|
33323
|
-
if (fieldInfo.kind !== "dimension" && fieldInfo.kind !== "measure") {
|
|
33324
|
-
throw new Error(`Invalid filter field kind: ${fieldInfo.kind}`);
|
|
33325
|
-
}
|
|
33326
|
-
const setFilter = React.useCallback((filter2) => {
|
|
33327
|
-
filterOperation.filter.setFilter(filter2);
|
|
33328
|
-
setQuery == null ? void 0 : setQuery(rootQuery.build());
|
|
33329
|
-
}, [filterOperation.filter, rootQuery, setQuery]);
|
|
33330
|
-
const {
|
|
33331
|
-
op,
|
|
33332
|
-
value
|
|
33333
|
-
} = parsedToLabels(filter, filterString);
|
|
33334
|
-
const label = `${fieldInfo.name} ${op} ${value}`;
|
|
33335
|
-
return /* @__PURE__ */ jsxRuntime.jsxs("div", {
|
|
33336
|
-
..._stylex.props(hoverStyles.main),
|
|
33337
|
-
children: [/* @__PURE__ */ jsxRuntime.jsx(FilterPopover, {
|
|
33338
|
-
fieldInfo,
|
|
33339
|
-
path: fieldReference.path ?? [],
|
|
33340
|
-
filter,
|
|
33341
|
-
setFilter,
|
|
33342
|
-
trigger: /* @__PURE__ */ jsxRuntime.jsx(Token, {
|
|
33343
|
-
icon: "filter",
|
|
33344
|
-
color: "cyan",
|
|
33345
|
-
label
|
|
33346
|
-
}),
|
|
33347
|
-
layoutProps: {
|
|
33348
|
-
align: "start",
|
|
33349
|
-
side: "bottom",
|
|
33350
|
-
sideOffset: 1
|
|
33351
|
-
}
|
|
33352
|
-
}), /* @__PURE__ */ jsxRuntime.jsx("div", {
|
|
33353
|
-
..._stylex.props(hoverStyles.hoverActions),
|
|
33354
|
-
children: /* @__PURE__ */ jsxRuntime.jsx(ClearButton, {
|
|
33355
|
-
onClick: () => {
|
|
33356
|
-
filterOperation.delete();
|
|
33357
|
-
setQuery == null ? void 0 : setQuery(rootQuery.build());
|
|
33358
|
-
}
|
|
33359
|
-
})
|
|
33360
|
-
})]
|
|
33361
|
-
});
|
|
33362
|
-
}
|
|
33363
33334
|
const parsedToLabels = (parsed, filterString) => {
|
|
33364
33335
|
if (parsed.parsed === null) {
|
|
33365
33336
|
return {
|
|
@@ -33539,6 +33510,94 @@ function displayTimeFromMoment(momentObj) {
|
|
|
33539
33510
|
}
|
|
33540
33511
|
return momentObj.moment;
|
|
33541
33512
|
}
|
|
33513
|
+
function FilterOperations({
|
|
33514
|
+
rootQuery,
|
|
33515
|
+
filters
|
|
33516
|
+
}) {
|
|
33517
|
+
const {
|
|
33518
|
+
setQuery
|
|
33519
|
+
} = React.useContext(QueryEditorContext);
|
|
33520
|
+
if (filters.length === 0) {
|
|
33521
|
+
return null;
|
|
33522
|
+
}
|
|
33523
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", {
|
|
33524
|
+
children: [/* @__PURE__ */ jsxRuntime.jsx("div", {
|
|
33525
|
+
..._stylex.props(styles$s.title),
|
|
33526
|
+
children: "filter by"
|
|
33527
|
+
}), /* @__PURE__ */ jsxRuntime.jsx("div", {
|
|
33528
|
+
..._stylex.props(styles$s.tokenContainer),
|
|
33529
|
+
children: filters.map((filterOperation, key2) => {
|
|
33530
|
+
return /* @__PURE__ */ jsxRuntime.jsx(ErrorElement, {
|
|
33531
|
+
fallback: /* @__PURE__ */ jsxRuntime.jsxs("div", {
|
|
33532
|
+
children: ["Invalid filter", /* @__PURE__ */ jsxRuntime.jsx(ClearButton, {
|
|
33533
|
+
onClick: () => {
|
|
33534
|
+
filterOperation.delete();
|
|
33535
|
+
setQuery == null ? void 0 : setQuery(rootQuery.build());
|
|
33536
|
+
}
|
|
33537
|
+
})]
|
|
33538
|
+
}),
|
|
33539
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(SingleFilterOperation, {
|
|
33540
|
+
filterOperation,
|
|
33541
|
+
rootQuery
|
|
33542
|
+
})
|
|
33543
|
+
}, key2);
|
|
33544
|
+
})
|
|
33545
|
+
})]
|
|
33546
|
+
});
|
|
33547
|
+
}
|
|
33548
|
+
function SingleFilterOperation({
|
|
33549
|
+
rootQuery,
|
|
33550
|
+
filterOperation
|
|
33551
|
+
}) {
|
|
33552
|
+
const {
|
|
33553
|
+
fieldReference,
|
|
33554
|
+
filterString
|
|
33555
|
+
} = filterOperation.filter;
|
|
33556
|
+
const filter = filterOperation.filter.getFilter();
|
|
33557
|
+
const fieldInfo = fieldReference.getFieldInfo();
|
|
33558
|
+
const {
|
|
33559
|
+
setQuery
|
|
33560
|
+
} = React.useContext(QueryEditorContext);
|
|
33561
|
+
if (fieldInfo.kind !== "dimension" && fieldInfo.kind !== "measure") {
|
|
33562
|
+
throw new Error(`Invalid filter field kind: ${fieldInfo.kind}`);
|
|
33563
|
+
}
|
|
33564
|
+
const setFilter = React.useCallback((filter2) => {
|
|
33565
|
+
filterOperation.filter.setFilter(filter2);
|
|
33566
|
+
setQuery == null ? void 0 : setQuery(rootQuery.build());
|
|
33567
|
+
}, [filterOperation.filter, rootQuery, setQuery]);
|
|
33568
|
+
const {
|
|
33569
|
+
op,
|
|
33570
|
+
value
|
|
33571
|
+
} = parsedToLabels(filter, filterString);
|
|
33572
|
+
const label = `${fieldInfo.name} ${op} ${value}`;
|
|
33573
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("div", {
|
|
33574
|
+
..._stylex.props(hoverStyles.main),
|
|
33575
|
+
children: [/* @__PURE__ */ jsxRuntime.jsx(FilterPopover, {
|
|
33576
|
+
fieldInfo,
|
|
33577
|
+
path: fieldReference.path ?? [],
|
|
33578
|
+
filter,
|
|
33579
|
+
setFilter,
|
|
33580
|
+
trigger: /* @__PURE__ */ jsxRuntime.jsx(Token, {
|
|
33581
|
+
icon: "filter",
|
|
33582
|
+
color: "cyan",
|
|
33583
|
+
label
|
|
33584
|
+
}),
|
|
33585
|
+
layoutProps: {
|
|
33586
|
+
align: "start",
|
|
33587
|
+
side: "bottom",
|
|
33588
|
+
sideOffset: 1
|
|
33589
|
+
}
|
|
33590
|
+
}), /* @__PURE__ */ jsxRuntime.jsx("div", {
|
|
33591
|
+
..._stylex.props(hoverStyles.hoverActions),
|
|
33592
|
+
children: /* @__PURE__ */ jsxRuntime.jsx(ClearButton, {
|
|
33593
|
+
onClick: () => {
|
|
33594
|
+
filterOperation.delete();
|
|
33595
|
+
setQuery == null ? void 0 : setQuery(rootQuery.build());
|
|
33596
|
+
}
|
|
33597
|
+
})
|
|
33598
|
+
})]
|
|
33599
|
+
});
|
|
33600
|
+
}
|
|
33542
33601
|
function LimitOperation({
|
|
33543
33602
|
rootQuery,
|
|
33544
33603
|
limit
|
|
@@ -34644,8 +34703,128 @@ const styles$a = {
|
|
|
34644
34703
|
$$css: true
|
|
34645
34704
|
}
|
|
34646
34705
|
};
|
|
34706
|
+
function FilterLiteralEditor({
|
|
34707
|
+
filterType,
|
|
34708
|
+
value,
|
|
34709
|
+
setValue
|
|
34710
|
+
}) {
|
|
34711
|
+
let filter = null;
|
|
34712
|
+
switch (filterType) {
|
|
34713
|
+
case "string_type":
|
|
34714
|
+
{
|
|
34715
|
+
const {
|
|
34716
|
+
parsed
|
|
34717
|
+
} = malloyFilter.StringFilterExpression.parse(value.filter_expression_value);
|
|
34718
|
+
filter = {
|
|
34719
|
+
kind: "string",
|
|
34720
|
+
parsed
|
|
34721
|
+
};
|
|
34722
|
+
}
|
|
34723
|
+
break;
|
|
34724
|
+
case "number_type":
|
|
34725
|
+
{
|
|
34726
|
+
const {
|
|
34727
|
+
parsed
|
|
34728
|
+
} = malloyFilter.NumberFilterExpression.parse(value.filter_expression_value);
|
|
34729
|
+
filter = {
|
|
34730
|
+
kind: "number",
|
|
34731
|
+
parsed
|
|
34732
|
+
};
|
|
34733
|
+
}
|
|
34734
|
+
break;
|
|
34735
|
+
case "boolean_type":
|
|
34736
|
+
{
|
|
34737
|
+
const {
|
|
34738
|
+
parsed
|
|
34739
|
+
} = malloyFilter.BooleanFilterExpression.parse(value.filter_expression_value);
|
|
34740
|
+
filter = {
|
|
34741
|
+
kind: "boolean",
|
|
34742
|
+
parsed
|
|
34743
|
+
};
|
|
34744
|
+
}
|
|
34745
|
+
break;
|
|
34746
|
+
case "date_type":
|
|
34747
|
+
{
|
|
34748
|
+
const {
|
|
34749
|
+
parsed
|
|
34750
|
+
} = malloyFilter.TemporalFilterExpression.parse(value.filter_expression_value);
|
|
34751
|
+
filter = {
|
|
34752
|
+
kind: "date",
|
|
34753
|
+
parsed
|
|
34754
|
+
};
|
|
34755
|
+
}
|
|
34756
|
+
break;
|
|
34757
|
+
case "timestamp_type":
|
|
34758
|
+
{
|
|
34759
|
+
const {
|
|
34760
|
+
parsed
|
|
34761
|
+
} = malloyFilter.TemporalFilterExpression.parse(value.filter_expression_value);
|
|
34762
|
+
filter = {
|
|
34763
|
+
kind: "timestamp",
|
|
34764
|
+
parsed
|
|
34765
|
+
};
|
|
34766
|
+
}
|
|
34767
|
+
break;
|
|
34768
|
+
}
|
|
34769
|
+
const {
|
|
34770
|
+
op,
|
|
34771
|
+
value: filterValue
|
|
34772
|
+
} = parsedToLabels(filter, value.filter_expression_value);
|
|
34773
|
+
const label = `${op} ${filterValue}`;
|
|
34774
|
+
const fieldInfo = {
|
|
34775
|
+
kind: "dimension",
|
|
34776
|
+
name: "parameter",
|
|
34777
|
+
type: {
|
|
34778
|
+
kind: filterType
|
|
34779
|
+
}
|
|
34780
|
+
};
|
|
34781
|
+
const setFilter = (parsed) => {
|
|
34782
|
+
switch (parsed.kind) {
|
|
34783
|
+
case "string":
|
|
34784
|
+
setValue({
|
|
34785
|
+
kind: "filter_expression_literal",
|
|
34786
|
+
filter_expression_value: malloyFilter.StringFilterExpression.unparse(parsed.parsed)
|
|
34787
|
+
});
|
|
34788
|
+
break;
|
|
34789
|
+
case "boolean":
|
|
34790
|
+
setValue({
|
|
34791
|
+
kind: "filter_expression_literal",
|
|
34792
|
+
filter_expression_value: malloyFilter.BooleanFilterExpression.unparse(parsed.parsed)
|
|
34793
|
+
});
|
|
34794
|
+
break;
|
|
34795
|
+
case "number":
|
|
34796
|
+
setValue({
|
|
34797
|
+
kind: "filter_expression_literal",
|
|
34798
|
+
filter_expression_value: malloyFilter.NumberFilterExpression.unparse(parsed.parsed)
|
|
34799
|
+
});
|
|
34800
|
+
break;
|
|
34801
|
+
case "date":
|
|
34802
|
+
case "timestamp":
|
|
34803
|
+
setValue({
|
|
34804
|
+
kind: "filter_expression_literal",
|
|
34805
|
+
filter_expression_value: malloyFilter.TemporalFilterExpression.unparse(parsed.parsed)
|
|
34806
|
+
});
|
|
34807
|
+
break;
|
|
34808
|
+
}
|
|
34809
|
+
};
|
|
34810
|
+
return /* @__PURE__ */ jsxRuntime.jsx(FilterPopover, {
|
|
34811
|
+
fieldInfo,
|
|
34812
|
+
path: [],
|
|
34813
|
+
filter,
|
|
34814
|
+
setFilter,
|
|
34815
|
+
trigger: /* @__PURE__ */ jsxRuntime.jsx(Token, {
|
|
34816
|
+
label
|
|
34817
|
+
}),
|
|
34818
|
+
layoutProps: {
|
|
34819
|
+
align: "start",
|
|
34820
|
+
side: "bottom",
|
|
34821
|
+
sideOffset: 1
|
|
34822
|
+
}
|
|
34823
|
+
});
|
|
34824
|
+
}
|
|
34647
34825
|
function LiteralValueEditor({
|
|
34648
34826
|
value,
|
|
34827
|
+
filterType,
|
|
34649
34828
|
setValue,
|
|
34650
34829
|
customStyle
|
|
34651
34830
|
}) {
|
|
@@ -34700,12 +34879,10 @@ function LiteralValueEditor({
|
|
|
34700
34879
|
customStyle
|
|
34701
34880
|
});
|
|
34702
34881
|
case "filter_expression_literal":
|
|
34703
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
34704
|
-
value
|
|
34705
|
-
|
|
34706
|
-
|
|
34707
|
-
filter_expression_value: value2
|
|
34708
|
-
}),
|
|
34882
|
+
return /* @__PURE__ */ jsxRuntime.jsx(FilterLiteralEditor, {
|
|
34883
|
+
value,
|
|
34884
|
+
filterType,
|
|
34885
|
+
setValue,
|
|
34709
34886
|
customStyle
|
|
34710
34887
|
});
|
|
34711
34888
|
}
|
|
@@ -34736,6 +34913,7 @@ function Parameters({
|
|
|
34736
34913
|
icon: atomicTypeToIcon(parameter.type.kind),
|
|
34737
34914
|
label: parameter.name
|
|
34738
34915
|
}), /* @__PURE__ */ jsxRuntime.jsx(LiteralValueEditor, {
|
|
34916
|
+
filterType: parameter.type.kind === "filter_expression_type" ? parameter.type.filter_type.kind : "string_type",
|
|
34739
34917
|
value: ((_a2 = source.tryGetParameter(parameter.name)) == null ? void 0 : _a2.parameter.value) ?? parameter.default_value,
|
|
34740
34918
|
setValue: (value) => {
|
|
34741
34919
|
source.setParameter(parameter.name, value);
|
|
@@ -35794,62 +35972,83 @@ const FIELD_KIND_TO_TITLE = {
|
|
|
35794
35972
|
dimension: "Dimensions"
|
|
35795
35973
|
};
|
|
35796
35974
|
function useOperations(view, field, path) {
|
|
35797
|
-
const
|
|
35798
|
-
|
|
35799
|
-
fields
|
|
35800
|
-
} = getInputSchemaFromViewParent(view);
|
|
35801
|
-
return new Set(flattenFieldsTree(fields).filter(({
|
|
35802
|
-
field: field2
|
|
35803
|
-
}) => field2.kind === "dimension").map(({
|
|
35804
|
-
field: field2
|
|
35805
|
-
}) => field2.name));
|
|
35806
|
-
}, [view]);
|
|
35807
|
-
const measureFields = React.useMemo(() => {
|
|
35975
|
+
const fullName = toFullName(path, field.name);
|
|
35976
|
+
const flattenedFields = React.useMemo(() => {
|
|
35808
35977
|
const {
|
|
35809
35978
|
fields
|
|
35810
35979
|
} = getInputSchemaFromViewParent(view);
|
|
35811
|
-
|
|
35812
|
-
|
|
35813
|
-
|
|
35814
|
-
|
|
35815
|
-
|
|
35816
|
-
|
|
35817
|
-
const
|
|
35818
|
-
if (!view) {
|
|
35819
|
-
return false;
|
|
35820
|
-
}
|
|
35980
|
+
const inputPath = path.join(".");
|
|
35981
|
+
return flattenFieldsTree(fields).filter((fieldItem) => {
|
|
35982
|
+
return fieldItem.path.join(".") === inputPath;
|
|
35983
|
+
});
|
|
35984
|
+
}, [path, view]);
|
|
35985
|
+
const matchingFieldItem = flattenedFields.find((fieldItem) => field.name === fieldItem.field.name);
|
|
35986
|
+
const groupByDisabledReason = React.useMemo(() => {
|
|
35821
35987
|
const segment = getSegmentIfPresent(view);
|
|
35822
|
-
|
|
35823
|
-
|
|
35824
|
-
|
|
35825
|
-
if (
|
|
35826
|
-
return
|
|
35988
|
+
if ((matchingFieldItem == null ? void 0 : matchingFieldItem.field.kind) !== "dimension") {
|
|
35989
|
+
return "Grouping is only available on a dimenion.";
|
|
35990
|
+
}
|
|
35991
|
+
if (segment == null ? void 0 : segment.hasField(field.name, path)) {
|
|
35992
|
+
return "Cannot group by a field already in the view.";
|
|
35993
|
+
}
|
|
35994
|
+
if (!isNotAnnotatedFilteredField(field)) {
|
|
35995
|
+
return "This field is annotated with #NO_UI.";
|
|
35996
|
+
}
|
|
35997
|
+
return "";
|
|
35998
|
+
}, [view, matchingFieldItem == null ? void 0 : matchingFieldItem.field.kind, field, path]);
|
|
35999
|
+
const aggregateDisabledReason = React.useMemo(() => {
|
|
36000
|
+
if ((matchingFieldItem == null ? void 0 : matchingFieldItem.field.kind) !== "measure") {
|
|
36001
|
+
return "Aggregation only supports measure fields.";
|
|
35827
36002
|
}
|
|
35828
36003
|
const segment = getSegmentIfPresent(view);
|
|
35829
|
-
|
|
35830
|
-
|
|
35831
|
-
const isFilterAllowed = React.useMemo(() => {
|
|
35832
|
-
if (!view) {
|
|
35833
|
-
return false;
|
|
36004
|
+
if (segment == null ? void 0 : segment.hasField(field.name, path)) {
|
|
36005
|
+
return "This field is already used in the query.";
|
|
35834
36006
|
}
|
|
35835
|
-
|
|
35836
|
-
|
|
35837
|
-
|
|
35838
|
-
|
|
35839
|
-
|
|
35840
|
-
|
|
35841
|
-
|
|
36007
|
+
if (!isNotAnnotatedFilteredField(field)) {
|
|
36008
|
+
return "This field is annotated with #NO_UI.";
|
|
36009
|
+
}
|
|
36010
|
+
return "";
|
|
36011
|
+
}, [matchingFieldItem == null ? void 0 : matchingFieldItem.field.kind, view, field, path]);
|
|
36012
|
+
const filterDisabledReason = React.useMemo(() => {
|
|
36013
|
+
if (!matchingFieldItem) {
|
|
36014
|
+
return `Unexpected Error: Could not find a field ${fullName}.`;
|
|
36015
|
+
}
|
|
36016
|
+
if (!["dimension", "measure"].includes(matchingFieldItem.field.kind)) {
|
|
36017
|
+
return `Filtering is only available for a dimension or measure.`;
|
|
36018
|
+
}
|
|
36019
|
+
if (!FILTERABLE_TYPES.includes(matchingFieldItem.field.type.kind)) {
|
|
36020
|
+
return "Filtering only supports string, boolean, number, date and time fields.";
|
|
36021
|
+
}
|
|
36022
|
+
return "";
|
|
36023
|
+
}, [fullName, matchingFieldItem]);
|
|
36024
|
+
const orderByDisabledReason = React.useMemo(() => {
|
|
36025
|
+
if (!matchingFieldItem) {
|
|
36026
|
+
return `Unexpected Error: Could not find a field ${fullName}.`;
|
|
35842
36027
|
}
|
|
35843
|
-
const fieldName = field.name;
|
|
35844
|
-
const outputSchemaFields = view.getOutputSchema().fields;
|
|
35845
36028
|
const segment = getSegmentIfPresent(view);
|
|
35846
|
-
|
|
35847
|
-
|
|
36029
|
+
if (segment && segmentHasOrderBySourceField(segment, path, field.name)) {
|
|
36030
|
+
return "Query is already ordered by this field.";
|
|
36031
|
+
}
|
|
36032
|
+
if (!segment || !segmentHasFieldInOutputSpace(segment, path, field.name)) {
|
|
36033
|
+
return "Order by is only available for fields in the output.";
|
|
36034
|
+
}
|
|
36035
|
+
if (!["dimension", "measure"].includes(matchingFieldItem.field.kind)) {
|
|
36036
|
+
return "Order By is only available for dimension or measure fields.";
|
|
36037
|
+
}
|
|
36038
|
+
if (!ORDERABLE_TYPES.includes(matchingFieldItem.field.type.kind)) {
|
|
36039
|
+
return "Order By only supports string, boolean, number, date and time fields.";
|
|
36040
|
+
}
|
|
36041
|
+
return "";
|
|
36042
|
+
}, [matchingFieldItem, view, path, field.name, fullName]);
|
|
35848
36043
|
return {
|
|
35849
|
-
isGroupByAllowed,
|
|
35850
|
-
|
|
35851
|
-
|
|
35852
|
-
|
|
36044
|
+
isGroupByAllowed: !groupByDisabledReason,
|
|
36045
|
+
groupByDisabledReason,
|
|
36046
|
+
isAggregateAllowed: !aggregateDisabledReason,
|
|
36047
|
+
aggregateDisabledReason,
|
|
36048
|
+
isFilterAllowed: !filterDisabledReason,
|
|
36049
|
+
filterDisabledReason,
|
|
36050
|
+
isOrderByAllowed: !orderByDisabledReason,
|
|
36051
|
+
orderByDisabledReason
|
|
35853
36052
|
};
|
|
35854
36053
|
}
|
|
35855
36054
|
const FILTERABLE_TYPES = ["string_type", "boolean_type", "number_type", "date_type", "timestamp_type"];
|
|
@@ -35866,22 +36065,22 @@ function FieldTokenWithActions({
|
|
|
35866
36065
|
} = React.useContext(QueryEditorContext);
|
|
35867
36066
|
const view = currentNestView ?? viewDef;
|
|
35868
36067
|
const {
|
|
35869
|
-
|
|
35870
|
-
|
|
35871
|
-
|
|
35872
|
-
|
|
36068
|
+
groupByDisabledReason,
|
|
36069
|
+
aggregateDisabledReason,
|
|
36070
|
+
filterDisabledReason,
|
|
36071
|
+
orderByDisabledReason
|
|
35873
36072
|
} = useOperations(view, field, path);
|
|
35874
36073
|
const [isFilterPopoverOpen, setIsFilterPopoverOpen] = React.useState();
|
|
35875
36074
|
const [isTooltipOpen, setIsTooltipOpen] = React.useState(false);
|
|
35876
36075
|
const handleAddOperationAction = (operation, filter) => {
|
|
35877
36076
|
if (field.kind === "dimension" || field.kind === "measure") {
|
|
35878
|
-
if (operation === "groupBy" &&
|
|
36077
|
+
if (operation === "groupBy" && !groupByDisabledReason) {
|
|
35879
36078
|
addGroupBy(view, field, path);
|
|
35880
|
-
} else if (operation === "aggregate" &&
|
|
36079
|
+
} else if (operation === "aggregate" && !aggregateDisabledReason) {
|
|
35881
36080
|
addAggregate(view, field, path);
|
|
35882
|
-
} else if (operation === "orderBy" &&
|
|
35883
|
-
|
|
35884
|
-
} else if (operation === "filter" &&
|
|
36081
|
+
} else if (operation === "orderBy" && !orderByDisabledReason) {
|
|
36082
|
+
addOrderByFromSource(view, path, field.name);
|
|
36083
|
+
} else if (operation === "filter" && !filterDisabledReason && filter) {
|
|
35885
36084
|
addFilter(view, field, path, filter);
|
|
35886
36085
|
}
|
|
35887
36086
|
setQuery == null ? void 0 : setQuery(rootQuery == null ? void 0 : rootQuery.build());
|
|
@@ -35906,7 +36105,7 @@ function FieldTokenWithActions({
|
|
|
35906
36105
|
icon: "insert",
|
|
35907
36106
|
disabled: !(rootQuery == null ? void 0 : rootQuery.isEmpty()),
|
|
35908
36107
|
onClick: handleSetView,
|
|
35909
|
-
tooltip: "Add view",
|
|
36108
|
+
tooltip: !(rootQuery == null ? void 0 : rootQuery.isEmpty()) ? "Can only add a view to an empty query." : "Add view",
|
|
35910
36109
|
onTooltipOpenChange: setIsTooltipOpen
|
|
35911
36110
|
}), /* @__PURE__ */ jsxRuntime.jsx(ActionButton, {
|
|
35912
36111
|
icon: "nest",
|
|
@@ -35917,8 +36116,8 @@ function FieldTokenWithActions({
|
|
|
35917
36116
|
}) : field.kind === "measure" ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, {
|
|
35918
36117
|
children: [/* @__PURE__ */ jsxRuntime.jsx(ActionButton, {
|
|
35919
36118
|
icon: "aggregate",
|
|
35920
|
-
tooltip: "Add as aggregate",
|
|
35921
|
-
disabled:
|
|
36119
|
+
tooltip: aggregateDisabledReason || "Add as aggregate",
|
|
36120
|
+
disabled: !!aggregateDisabledReason,
|
|
35922
36121
|
onClick: () => handleAddOperationAction("aggregate"),
|
|
35923
36122
|
onTooltipOpenChange: setIsTooltipOpen
|
|
35924
36123
|
}), /* @__PURE__ */ jsxRuntime.jsx(FilterPopover, {
|
|
@@ -35927,23 +36126,23 @@ function FieldTokenWithActions({
|
|
|
35927
36126
|
setFilter: (filter) => handleAddOperationAction("filter", filter),
|
|
35928
36127
|
trigger: /* @__PURE__ */ jsxRuntime.jsx(ActionButton, {
|
|
35929
36128
|
icon: "filter",
|
|
35930
|
-
tooltip: "Add as filter",
|
|
35931
|
-
disabled:
|
|
36129
|
+
tooltip: filterDisabledReason || "Add as filter",
|
|
36130
|
+
disabled: !!filterDisabledReason,
|
|
35932
36131
|
onTooltipOpenChange: setIsTooltipOpen
|
|
35933
36132
|
}),
|
|
35934
36133
|
onOpenChange: setIsFilterPopoverOpen
|
|
35935
36134
|
}), /* @__PURE__ */ jsxRuntime.jsx(ActionButton, {
|
|
35936
36135
|
icon: "orderBy",
|
|
35937
|
-
tooltip: "Add as order by",
|
|
35938
|
-
disabled:
|
|
36136
|
+
tooltip: orderByDisabledReason || "Add as order by",
|
|
36137
|
+
disabled: !!orderByDisabledReason,
|
|
35939
36138
|
onClick: () => handleAddOperationAction("orderBy"),
|
|
35940
36139
|
onTooltipOpenChange: setIsTooltipOpen
|
|
35941
36140
|
})]
|
|
35942
36141
|
}) : field.kind === "dimension" ? /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, {
|
|
35943
36142
|
children: [/* @__PURE__ */ jsxRuntime.jsx(ActionButton, {
|
|
35944
36143
|
icon: "groupBy",
|
|
35945
|
-
tooltip: "Add as group by",
|
|
35946
|
-
disabled:
|
|
36144
|
+
tooltip: groupByDisabledReason || "Add as group by",
|
|
36145
|
+
disabled: !!groupByDisabledReason,
|
|
35947
36146
|
onClick: () => handleAddOperationAction("groupBy"),
|
|
35948
36147
|
onTooltipOpenChange: setIsTooltipOpen
|
|
35949
36148
|
}), /* @__PURE__ */ jsxRuntime.jsx(FilterPopover, {
|
|
@@ -35952,20 +36151,20 @@ function FieldTokenWithActions({
|
|
|
35952
36151
|
setFilter: (filter) => handleAddOperationAction("filter", filter),
|
|
35953
36152
|
trigger: /* @__PURE__ */ jsxRuntime.jsx(ActionButton, {
|
|
35954
36153
|
icon: "filter",
|
|
35955
|
-
tooltip: "Add as filter",
|
|
35956
|
-
disabled:
|
|
36154
|
+
tooltip: filterDisabledReason || "Add as filter",
|
|
36155
|
+
disabled: !!filterDisabledReason,
|
|
35957
36156
|
onTooltipOpenChange: setIsTooltipOpen
|
|
35958
36157
|
}),
|
|
35959
36158
|
onOpenChange: setIsFilterPopoverOpen
|
|
35960
36159
|
}), /* @__PURE__ */ jsxRuntime.jsx(ActionButton, {
|
|
35961
36160
|
icon: "orderBy",
|
|
35962
|
-
tooltip: "Add as order by",
|
|
35963
|
-
disabled:
|
|
36161
|
+
tooltip: orderByDisabledReason || "Add as order by",
|
|
36162
|
+
disabled: !!orderByDisabledReason,
|
|
35964
36163
|
onClick: () => handleAddOperationAction("orderBy"),
|
|
35965
36164
|
onTooltipOpenChange: setIsTooltipOpen
|
|
35966
36165
|
})]
|
|
35967
36166
|
}) : null,
|
|
35968
|
-
onClick: field.kind === "dimension" &&
|
|
36167
|
+
onClick: field.kind === "dimension" && !groupByDisabledReason ? () => handleAddOperationAction("groupBy") : field.kind === "measure" && !aggregateDisabledReason ? () => handleAddOperationAction("aggregate") : field.kind === "view" ? () => handleAddView() : void 0,
|
|
35969
36168
|
hoverActionsVisible: isFilterPopoverOpen || isTooltipOpen,
|
|
35970
36169
|
tooltip: /* @__PURE__ */ jsxRuntime.jsx(FieldHoverCard, {
|
|
35971
36170
|
field,
|