@malloy-publisher/sdk 0.0.137 → 0.0.139
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/README.md +122 -1
- package/dist/ServerProvider-Bzid56gJ.cjs.js +1 -0
- package/dist/{ServerProvider-BGGK1ZQ_.es.js → ServerProvider-D-y63tG0.es.js} +550 -478
- package/dist/client/api.d.ts +144 -53
- package/dist/client/index.cjs.js +1 -1
- package/dist/client/index.es.js +22 -21
- package/dist/components/Notebook/Notebook.d.ts +4 -1
- package/dist/components/Notebook/NotebookCell.d.ts +2 -2
- package/dist/components/Notebook/types.d.ts +21 -0
- package/dist/components/filter/DimensionFilter.d.ts +43 -0
- package/dist/components/filter/index.d.ts +4 -0
- package/dist/components/filter/utils.d.ts +75 -0
- package/dist/components/index.d.ts +7 -6
- package/dist/components/styles.d.ts +3 -3
- package/dist/hooks/index.d.ts +4 -0
- package/dist/hooks/useDimensionFilters.d.ts +84 -0
- package/dist/hooks/useDimensionFiltersFromSpec.d.ts +52 -0
- package/dist/hooks/useDimensionFiltersQuery.d.ts +79 -0
- package/dist/hooks/useDimensionalFilterRangeData.d.ts +106 -0
- package/dist/index.cjs.js +141 -112
- package/dist/index.d.ts +3 -2
- package/dist/index.es.js +47903 -39798
- package/dist/sdk.css +1 -1
- package/package.json +16 -11
- package/src/components/Home/Home.tsx +15 -11
- package/src/components/Notebook/Notebook.tsx +391 -6
- package/src/components/Notebook/NotebookCell.tsx +2 -2
- package/src/components/Notebook/types.ts +24 -0
- package/src/components/Package/Connections.tsx +3 -6
- package/src/components/RenderedResult/RenderedResult.tsx +22 -3
- package/src/components/filter/DimensionFilter.tsx +738 -0
- package/src/components/filter/index.ts +20 -0
- package/src/components/filter/utils.ts +354 -0
- package/src/components/highlighter.ts +14 -6
- package/src/components/index.ts +7 -6
- package/src/hooks/index.ts +31 -0
- package/src/hooks/useDimensionFilters.ts +322 -0
- package/src/hooks/useDimensionFiltersFromSpec.ts +117 -0
- package/src/hooks/useDimensionFiltersQuery.ts +300 -0
- package/src/hooks/useDimensionalFilterRangeData.ts +758 -0
- package/src/index.ts +3 -2
- package/dist/ServerProvider-lXAaPKBb.cjs.js +0 -1
- package/dist/abap-BmBUA35e.es.js +0 -6
- package/dist/abap-Dwt2rH6y.cjs.js +0 -1
- package/dist/actionscript-3-mj8Uhnsc.cjs.js +0 -1
- package/dist/actionscript-3-zFUbzQa9.es.js +0 -6
- package/dist/ada-CBvPkFpZ.es.js +0 -6
- package/dist/ada-DZM58Vqs.cjs.js +0 -1
- package/dist/andromeeda-BXc5FOIb.cjs.js +0 -1
- package/dist/andromeeda-uXNdzNpk.es.js +0 -4
- package/dist/angular-html-B60m4jt-.cjs.js +0 -1
- package/dist/angular-html-D3aW1y6T.es.js +0 -32
- package/dist/angular-ts-Jud40GrY.es.js +0 -21
- package/dist/angular-ts-SIlYrqkG.cjs.js +0 -1
- package/dist/apache-CVNlsSDc.es.js +0 -6
- package/dist/apache-D7v5fxtZ.cjs.js +0 -1
- package/dist/apex-4hrAnw0a.cjs.js +0 -1
- package/dist/apex-DFk3KRB1.es.js +0 -6
- package/dist/apl-CKSaOFbt.cjs.js +0 -1
- package/dist/apl-pE3PRTDr.es.js +0 -16
- package/dist/applescript-CYMR_y0g.es.js +0 -6
- package/dist/applescript-Cnd3Dxju.cjs.js +0 -1
- package/dist/ara-4QmU5e04.es.js +0 -6
- package/dist/ara-BQ2aGbFQ.cjs.js +0 -1
- package/dist/asciidoc-C6nYvw8K.cjs.js +0 -1
- package/dist/asciidoc-v_1bjgUg.es.js +0 -6
- package/dist/asm-CQnBVCj-.cjs.js +0 -1
- package/dist/asm-RC0Yh-NZ.es.js +0 -6
- package/dist/astro-Be6fybGX.es.js +0 -16
- package/dist/astro-KhYkz6Xu.cjs.js +0 -1
- package/dist/aurora-x-BwoVEUWZ.es.js +0 -4
- package/dist/aurora-x-C5IpmIOG.cjs.js +0 -1
- package/dist/awk-DUx4h__E.cjs.js +0 -1
- package/dist/awk-gPH8MVMW.es.js +0 -6
- package/dist/ayu-dark-Cv7nTiif.cjs.js +0 -1
- package/dist/ayu-dark-CxPZkpb2.es.js +0 -4
- package/dist/ballerina-CXlzbmzl.cjs.js +0 -1
- package/dist/ballerina-kvLnRU_e.es.js +0 -6
- package/dist/bat-BHYy44sT.es.js +0 -6
- package/dist/bat-DlMT9sut.cjs.js +0 -1
- package/dist/beancount-CyyiuUzM.cjs.js +0 -1
- package/dist/beancount-D-MADTs_.es.js +0 -6
- package/dist/berry-B0EjuzrL.cjs.js +0 -1
- package/dist/berry-Ci9U0o4h.es.js +0 -6
- package/dist/bibtex-CX618D15.es.js +0 -6
- package/dist/bibtex-CfoG9xRq.cjs.js +0 -1
- package/dist/bicep-D6PH_9IY.cjs.js +0 -1
- package/dist/bicep-iuYiPopT.es.js +0 -6
- package/dist/blade-C0tMuk8f.cjs.js +0 -1
- package/dist/blade-DmXp5Zcz.es.js +0 -18
- package/dist/bsl-CfHcite8.cjs.js +0 -1
- package/dist/bsl-NPX_d-bb.es.js +0 -8
- package/dist/c-C4sXGJZM.cjs.js +0 -1
- package/dist/c-DASdrs7p.es.js +0 -6
- package/dist/cadence-BDALQi26.es.js +0 -6
- package/dist/cadence-Dq2CYzXG.cjs.js +0 -1
- package/dist/cairo-17kO8-kb.es.js +0 -8
- package/dist/cairo-CcKpJkyf.cjs.js +0 -1
- package/dist/catppuccin-frappe-BrTOiad2.es.js +0 -4
- package/dist/catppuccin-frappe-DXAedND3.cjs.js +0 -1
- package/dist/catppuccin-latte-D-dc_R4m.es.js +0 -4
- package/dist/catppuccin-latte-mwGw3-Ej.cjs.js +0 -1
- package/dist/catppuccin-macchiato-DN4jOp0G.es.js +0 -4
- package/dist/catppuccin-macchiato-cQCk9ADg.cjs.js +0 -1
- package/dist/catppuccin-mocha-B8yCE3-3.es.js +0 -4
- package/dist/catppuccin-mocha-ClSzDZSl.cjs.js +0 -1
- package/dist/clarity-CNgV2Ths.es.js +0 -6
- package/dist/clarity-ytMkUD5Q.cjs.js +0 -1
- package/dist/clojure-B_Wv414H.cjs.js +0 -1
- package/dist/clojure-CsKKFGwv.es.js +0 -6
- package/dist/cmake-Dr-A3iJx.es.js +0 -6
- package/dist/cmake-TBUaQXYY.cjs.js +0 -1
- package/dist/cobol-BzcJm6ie.es.js +0 -10
- package/dist/cobol-DXFNH4EH.cjs.js +0 -1
- package/dist/codeowners-Bt9yU6NX.es.js +0 -6
- package/dist/codeowners-QhPK6lIJ.cjs.js +0 -1
- package/dist/codeql-B7Q9tkDJ.cjs.js +0 -1
- package/dist/codeql-DBNTqJi1.es.js +0 -6
- package/dist/coffee-GRRSkgX1.cjs.js +0 -1
- package/dist/coffee-q2iaxUnQ.es.js +0 -8
- package/dist/common-lisp-Ced3ctK5.cjs.js +0 -1
- package/dist/common-lisp-r7ZEOG7T.es.js +0 -6
- package/dist/coq-BTRB4iqi.cjs.js +0 -1
- package/dist/coq-CB6Pv_W9.es.js +0 -6
- package/dist/cpp-CPOvHZqs.cjs.js +0 -1
- package/dist/cpp-CPQtoCcU.es.js +0 -18
- package/dist/crystal-BY_Cg265.es.js +0 -18
- package/dist/crystal-C6AG-iew.cjs.js +0 -1
- package/dist/csharp-CYWRhZ2R.es.js +0 -6
- package/dist/csharp-TKds-MhG.cjs.js +0 -1
- package/dist/css-B0kbn78J.cjs.js +0 -1
- package/dist/css-D1aVdRIU.es.js +0 -6
- package/dist/csv-BVJjiaC3.cjs.js +0 -1
- package/dist/csv-DvCncUGQ.es.js +0 -6
- package/dist/cue-BXMrmvay.es.js +0 -6
- package/dist/cue-Cz4J-rnd.cjs.js +0 -1
- package/dist/cypher-DTm5zNR1.es.js +0 -6
- package/dist/cypher-DuKTiyez.cjs.js +0 -1
- package/dist/d-BW9Wd7aK.cjs.js +0 -1
- package/dist/d-D6ZXmn3l.es.js +0 -6
- package/dist/dark-plus-Cd5emcYO.cjs.js +0 -1
- package/dist/dark-plus-pUHDTVV0.es.js +0 -4
- package/dist/dart-CWs-er6b.cjs.js +0 -1
- package/dist/dart-Dz59Is3F.es.js +0 -6
- package/dist/dax-CDxFL2Kb.cjs.js +0 -1
- package/dist/dax-DTVGzydb.es.js +0 -6
- package/dist/desktop-CFgo0jo7.cjs.js +0 -1
- package/dist/desktop-Db9vb-dl.es.js +0 -6
- package/dist/diff-BsEkKwI8.cjs.js +0 -1
- package/dist/diff-XmNrvgM1.es.js +0 -6
- package/dist/docker-DWH2onkn.es.js +0 -6
- package/dist/docker-hwiw4W8I.cjs.js +0 -1
- package/dist/dotenv-4337wvzu.es.js +0 -6
- package/dist/dotenv-CJ5o3G1C.cjs.js +0 -1
- package/dist/dracula-BNgwAJ-d.cjs.js +0 -1
- package/dist/dracula-BtZx2Kac.es.js +0 -4
- package/dist/dracula-soft-BHZ7sHFu.cjs.js +0 -1
- package/dist/dracula-soft-BKa-aqBv.es.js +0 -4
- package/dist/dream-maker-CvvfrJSx.es.js +0 -6
- package/dist/dream-maker-DBharE9Q.cjs.js +0 -1
- package/dist/edge-DI6_BHKG.es.js +0 -12
- package/dist/edge-i77KJtJz.cjs.js +0 -1
- package/dist/elixir-D00NoPSM.cjs.js +0 -1
- package/dist/elixir-ic9y5jcd.es.js +0 -8
- package/dist/elm-Bhj5Vf-e.cjs.js +0 -1
- package/dist/elm-DxnUqUaW.es.js +0 -8
- package/dist/emacs-lisp-BAefI874.es.js +0 -6
- package/dist/emacs-lisp-CDDyFsvQ.cjs.js +0 -1
- package/dist/erb-Cbj2YePa.es.js +0 -10
- package/dist/erb-Dybaw01v.cjs.js +0 -1
- package/dist/erlang-3VgdrQXV.cjs.js +0 -1
- package/dist/erlang-CmIiwF3I.es.js +0 -6
- package/dist/everforest-dark-DMCBqXCK.es.js +0 -4
- package/dist/everforest-dark-_sBMomR1.cjs.js +0 -1
- package/dist/everforest-light-BbXl82Em.es.js +0 -4
- package/dist/everforest-light-H0xoYxl0.cjs.js +0 -1
- package/dist/fennel-BvcDRFAV.cjs.js +0 -1
- package/dist/fennel-DNqkz9pE.es.js +0 -6
- package/dist/fish-CnamI0Ar.cjs.js +0 -1
- package/dist/fish-DIm72t2T.es.js +0 -6
- package/dist/fluent-BapTxJsC.es.js +0 -6
- package/dist/fluent-DFpT66K8.cjs.js +0 -1
- package/dist/fortran-fixed-form-DECY15PY.es.js +0 -8
- package/dist/fortran-fixed-form-u_RcUPMu.cjs.js +0 -1
- package/dist/fortran-free-form-CNDsBFUj.es.js +0 -6
- package/dist/fortran-free-form-IaGrWIda.cjs.js +0 -1
- package/dist/fsharp-B-aK2rr3.cjs.js +0 -1
- package/dist/fsharp-D2ZqviWP.es.js +0 -8
- package/dist/gdresource-BBAqNWe4.cjs.js +0 -1
- package/dist/gdresource-RIsK8sku.es.js +0 -10
- package/dist/gdscript-5N_43TPQ.cjs.js +0 -1
- package/dist/gdscript-D7aheHm-.es.js +0 -6
- package/dist/gdshader-BGJEsM2Z.es.js +0 -6
- package/dist/gdshader-Bl85Hrm5.cjs.js +0 -1
- package/dist/genie-C9gPjc6J.es.js +0 -6
- package/dist/genie-DGsxMAbQ.cjs.js +0 -1
- package/dist/gherkin-CVV6nEUH.cjs.js +0 -1
- package/dist/gherkin-bka1Exbx.es.js +0 -6
- package/dist/git-commit-BRJ1E4Bx.es.js +0 -8
- package/dist/git-commit-CwfgI4fD.cjs.js +0 -1
- package/dist/git-rebase-C3X7aMpn.es.js +0 -8
- package/dist/git-rebase-DUvbIQDw.cjs.js +0 -1
- package/dist/github-dark-BKL9xNgN.cjs.js +0 -1
- package/dist/github-dark-DenFmJkN.es.js +0 -4
- package/dist/github-dark-default-BJPUVz4H.es.js +0 -4
- package/dist/github-dark-default-Dsv5MuSi.cjs.js +0 -1
- package/dist/github-dark-dimmed-CtB9hz8U.cjs.js +0 -1
- package/dist/github-dark-dimmed-DUshB20C.es.js +0 -4
- package/dist/github-dark-high-contrast-BqZVM-jF.cjs.js +0 -1
- package/dist/github-dark-high-contrast-D3aGCnF8.es.js +0 -4
- package/dist/github-light-BFTOhCbz.cjs.js +0 -1
- package/dist/github-light-JYsPkUQd.es.js +0 -4
- package/dist/github-light-default-BZoWH9dH.cjs.js +0 -1
- package/dist/github-light-default-D99KPAby.es.js +0 -4
- package/dist/github-light-high-contrast-BbmZE-Mp.es.js +0 -4
- package/dist/github-light-high-contrast-Ks3kPGJU.cjs.js +0 -1
- package/dist/gleam-B4k9YFGD.es.js +0 -6
- package/dist/gleam-nR4mjrhK.cjs.js +0 -1
- package/dist/glimmer-js-C4MQf3Na.es.js +0 -14
- package/dist/glimmer-js-CNfyUqSb.cjs.js +0 -1
- package/dist/glimmer-ts-Bp7_dELi.cjs.js +0 -1
- package/dist/glimmer-ts-CoYpqZrZ.es.js +0 -14
- package/dist/glsl-BYTq1Tfl.es.js +0 -8
- package/dist/glsl-CIu1PL9X.cjs.js +0 -1
- package/dist/gnuplot-CurtDYoJ.cjs.js +0 -1
- package/dist/gnuplot-DnWoRZt-.es.js +0 -6
- package/dist/go-BErP6iv1.es.js +0 -6
- package/dist/go-CM9_GlwL.cjs.js +0 -1
- package/dist/graphql-BnnSMMC2.cjs.js +0 -1
- package/dist/graphql-g3nHRc0M.es.js +0 -14
- package/dist/groovy-BaVp9Il5.cjs.js +0 -1
- package/dist/groovy-IWs5-NIO.es.js +0 -6
- package/dist/hack-BVxH3fsq.cjs.js +0 -1
- package/dist/hack-wPAsyujS.es.js +0 -10
- package/dist/haml-4TJ757dz.es.js +0 -10
- package/dist/haml-vutdexHh.cjs.js +0 -1
- package/dist/handlebars-7GDLw__F.es.js +0 -14
- package/dist/handlebars-COmZnO8P.cjs.js +0 -1
- package/dist/haskell-CtlGos0K.es.js +0 -6
- package/dist/haskell-suhyCHEm.cjs.js +0 -1
- package/dist/haxe-BIQU1qHi.cjs.js +0 -1
- package/dist/haxe-CZZ33vZw.es.js +0 -6
- package/dist/hcl-6hOg9WP4.es.js +0 -6
- package/dist/hcl-CbQ1yCnz.cjs.js +0 -1
- package/dist/hjson-CgwED-oz.es.js +0 -6
- package/dist/hjson-Ddklb4QM.cjs.js +0 -1
- package/dist/hlsl-3-lv4gi7.es.js +0 -6
- package/dist/hlsl-B4NkiBfC.cjs.js +0 -1
- package/dist/houston-BDYrDoDW.es.js +0 -4
- package/dist/houston-T57H3gQZ.cjs.js +0 -1
- package/dist/html-Dc-Bg17s.cjs.js +0 -1
- package/dist/html-PSPajZka.es.js +0 -10
- package/dist/html-derivative-Brb3b4aI.es.js +0 -8
- package/dist/html-derivative-CY9mJeT0.cjs.js +0 -1
- package/dist/http-BrKsebcH.cjs.js +0 -1
- package/dist/http-CWBcr-Ch.es.js +0 -14
- package/dist/hxml-DLduiIv3.es.js +0 -8
- package/dist/hxml-DbGPHkY4.cjs.js +0 -1
- package/dist/hy-C2xHhR6I.es.js +0 -6
- package/dist/hy-DpyTdO3T.cjs.js +0 -1
- package/dist/imba-BEYqRZzB.es.js +0 -8
- package/dist/imba-CAIkF-GD.cjs.js +0 -1
- package/dist/ini-BUcvsX-U.es.js +0 -6
- package/dist/ini-CymULaw_.cjs.js +0 -1
- package/dist/java-B7odJ7Ap.es.js +0 -6
- package/dist/java-Bn1Lvoni.cjs.js +0 -1
- package/dist/javascript-Bnnicc83.cjs.js +0 -1
- package/dist/javascript-fa8UlHZE.es.js +0 -6
- package/dist/jinja-BoeZymy4.cjs.js +0 -1
- package/dist/jinja-DKLHYjK0.es.js +0 -11
- package/dist/jison-C0DlFEjB.cjs.js +0 -1
- package/dist/jison-CzPfUIvM.es.js +0 -8
- package/dist/json-71t8ZF9g.es.js +0 -6
- package/dist/json-y-J1j5EW.cjs.js +0 -1
- package/dist/json5-CzvlWgZ7.cjs.js +0 -1
- package/dist/json5-Z7F6rA6a.es.js +0 -6
- package/dist/jsonc-BnhWfmQw.cjs.js +0 -1
- package/dist/jsonc-Dphhs4m2.es.js +0 -6
- package/dist/jsonl-BbGkWPJz.cjs.js +0 -1
- package/dist/jsonl-D9jj92Gg.es.js +0 -6
- package/dist/jsonnet-Bn--UDZ1.cjs.js +0 -1
- package/dist/jsonnet-DEQ7IUoJ.es.js +0 -6
- package/dist/jssm-4CSVp8lc.cjs.js +0 -1
- package/dist/jssm-j74e88UX.es.js +0 -6
- package/dist/jsx-Bkesy5tT.es.js +0 -6
- package/dist/jsx-D8YwVp-7.cjs.js +0 -1
- package/dist/julia-B_r6juN7.es.js +0 -16
- package/dist/julia-DLxGoAlk.cjs.js +0 -1
- package/dist/kanagawa-dragon-BJZF7xDr.cjs.js +0 -1
- package/dist/kanagawa-dragon-CiKur4Hl.es.js +0 -4
- package/dist/kanagawa-lotus-BKu-smKu.es.js +0 -4
- package/dist/kanagawa-lotus-BhgzmRV4.cjs.js +0 -1
- package/dist/kanagawa-wave-BgJip59C.cjs.js +0 -1
- package/dist/kanagawa-wave-CQwozSzG.es.js +0 -4
- package/dist/kotlin-DCgZY7Ii.es.js +0 -6
- package/dist/kotlin-DDI6myF6.cjs.js +0 -1
- package/dist/kusto-Cw029H-v.es.js +0 -6
- package/dist/kusto-OZxALJZT.cjs.js +0 -1
- package/dist/laserwave--izBLY1I.cjs.js +0 -1
- package/dist/laserwave-6a00oqik.es.js +0 -4
- package/dist/latex-CXOK56Uv.cjs.js +0 -1
- package/dist/latex-GxBxlqbc.es.js +0 -8
- package/dist/lean-CYSet4vs.es.js +0 -6
- package/dist/lean-D1iY-35j.cjs.js +0 -1
- package/dist/less-DIaY7vQJ.cjs.js +0 -1
- package/dist/less-DQA4v-Nm.es.js +0 -6
- package/dist/light-plus-B5D0le0o.cjs.js +0 -1
- package/dist/light-plus-CZuVqSLX.es.js +0 -4
- package/dist/liquid-BYouVITI.cjs.js +0 -1
- package/dist/liquid-BxBkR-z5.es.js +0 -14
- package/dist/log-BIXUeBaj.cjs.js +0 -1
- package/dist/log-D2eRfqDn.es.js +0 -6
- package/dist/logo-B2d3b27P.cjs.js +0 -1
- package/dist/logo-QEAtGWZ9.es.js +0 -6
- package/dist/lua-B2_GGnC5.cjs.js +0 -1
- package/dist/lua-DeXVjwzF.es.js +0 -8
- package/dist/luau-BjYGiqID.es.js +0 -6
- package/dist/luau-CvqAeq4F.cjs.js +0 -1
- package/dist/make-BjuHP00g.es.js +0 -6
- package/dist/make-Oob5Z9Pk.cjs.js +0 -1
- package/dist/markdown-B6guhLWd.es.js +0 -6
- package/dist/markdown-BGBuj4LZ.cjs.js +0 -1
- package/dist/marko-CS7eEGs3.cjs.js +0 -1
- package/dist/marko-DwPYPpB3.es.js +0 -14
- package/dist/material-theme-D6KBX41T.es.js +0 -4
- package/dist/material-theme-Dj0-OyRN.cjs.js +0 -1
- package/dist/material-theme-darker-CkRroheE.es.js +0 -4
- package/dist/material-theme-darker-Dvfs29ir.cjs.js +0 -1
- package/dist/material-theme-lighter-BUBw43Yz.es.js +0 -4
- package/dist/material-theme-lighter-EU3ZGl_r.cjs.js +0 -1
- package/dist/material-theme-ocean-ClGX14Ja.es.js +0 -4
- package/dist/material-theme-ocean-px_3Pwqa.cjs.js +0 -1
- package/dist/material-theme-palenight-38jxvsGX.cjs.js +0 -1
- package/dist/material-theme-palenight-C1RVm8K1.es.js +0 -4
- package/dist/matlab-BpQlIJiw.es.js +0 -6
- package/dist/matlab-CbN2rF6P.cjs.js +0 -1
- package/dist/mdc-Bkl-bu_Z.cjs.js +0 -1
- package/dist/mdc-X4YjkufV.es.js +0 -12
- package/dist/mdx-Cl31h8mi.cjs.js +0 -1
- package/dist/mdx-DIoECIFU.es.js +0 -6
- package/dist/mermaid-BZ7WHNIe.es.js +0 -6
- package/dist/mermaid-CSogK_LM.cjs.js +0 -1
- package/dist/min-dark-C7ak0t6c.es.js +0 -4
- package/dist/min-dark-tt5o_I5e.cjs.js +0 -1
- package/dist/min-light-CKFxVcPp.es.js +0 -4
- package/dist/min-light-tmTHl_CQ.cjs.js +0 -1
- package/dist/mipsasm-BseoYJQp.cjs.js +0 -1
- package/dist/mipsasm-DusDYkFc.es.js +0 -6
- package/dist/mojo-CY9jaezJ.es.js +0 -6
- package/dist/mojo-D8QAG3Ze.cjs.js +0 -1
- package/dist/monokai-C1KBYcO0.es.js +0 -4
- package/dist/monokai-DMIxv6MM.cjs.js +0 -1
- package/dist/move-ChphFumd.es.js +0 -6
- package/dist/move-DaBrcjat.cjs.js +0 -1
- package/dist/narrat-Dz4d7OmN.es.js +0 -6
- package/dist/narrat-oOfAO4q8.cjs.js +0 -1
- package/dist/nextflow-BxJSKvPb.cjs.js +0 -1
- package/dist/nextflow-DW0Yq9a2.es.js +0 -6
- package/dist/nginx-ChI-VqNT.es.js +0 -8
- package/dist/nginx-LuyFICzP.cjs.js +0 -1
- package/dist/night-owl-BN78kThQ.cjs.js +0 -1
- package/dist/night-owl-Bm2rzalh.es.js +0 -4
- package/dist/nim-BiJA-5u7.es.js +0 -20
- package/dist/nim-DkC83hsN.cjs.js +0 -1
- package/dist/nix-Cg5uV_xg.es.js +0 -6
- package/dist/nix-DNME0Ea7.cjs.js +0 -1
- package/dist/nord-CC5OiUXg.es.js +0 -4
- package/dist/nord-Ca5AGUWc.cjs.js +0 -1
- package/dist/nushell-BfRnzRWn.es.js +0 -6
- package/dist/nushell-DI9Z3l3M.cjs.js +0 -1
- package/dist/objective-c-BGg9R27G.es.js +0 -6
- package/dist/objective-c-DVx8Rcni.cjs.js +0 -1
- package/dist/objective-cpp-CJ3y3V_5.es.js +0 -6
- package/dist/objective-cpp-s6XI7Jvk.cjs.js +0 -1
- package/dist/ocaml-BZLsfx_o.es.js +0 -6
- package/dist/ocaml-kUzDDUf2.cjs.js +0 -1
- package/dist/one-dark-pro-D7-kP8fv.es.js +0 -4
- package/dist/one-dark-pro-JOzzHStv.cjs.js +0 -1
- package/dist/one-light-020-h_lv.cjs.js +0 -1
- package/dist/one-light-D9sNaUtq.es.js +0 -4
- package/dist/pascal-D509_I72.cjs.js +0 -1
- package/dist/pascal-l2bqd7Dz.es.js +0 -6
- package/dist/perl-CkXYjL3t.es.js +0 -16
- package/dist/perl-DUnCLRB_.cjs.js +0 -1
- package/dist/php-D0k1sQr6.cjs.js +0 -1
- package/dist/php-q40Yjh5d.es.js +0 -18
- package/dist/plastic-CSTz3KZp.es.js +0 -4
- package/dist/plastic-r5piqq-S.cjs.js +0 -1
- package/dist/plsql-C_qH_YOK.cjs.js +0 -1
- package/dist/plsql-oVq_K_wH.es.js +0 -6
- package/dist/po-5jaeIyVd.es.js +0 -6
- package/dist/po-CBsLQIcu.cjs.js +0 -1
- package/dist/poimandres-BLP3NNjc.cjs.js +0 -1
- package/dist/poimandres-C-VADXHD.es.js +0 -4
- package/dist/polar-De-CDeYv.cjs.js +0 -1
- package/dist/polar-wcLp8ci7.es.js +0 -6
- package/dist/postcss-BZ3MNRIJ.es.js +0 -6
- package/dist/postcss-BtcsgaYj.cjs.js +0 -1
- package/dist/powerquery-B0rHn13V.cjs.js +0 -1
- package/dist/powerquery-CgRa2XRw.es.js +0 -6
- package/dist/powershell-Diwyv8Eh.es.js +0 -6
- package/dist/powershell-rCX2OYXT.cjs.js +0 -1
- package/dist/prisma-BaaUHYMp.cjs.js +0 -1
- package/dist/prisma-COL_v1x4.es.js +0 -6
- package/dist/prolog-CuvJOxqT.es.js +0 -6
- package/dist/prolog-DrXD2tGS.cjs.js +0 -1
- package/dist/proto-BtmQjBQu.cjs.js +0 -1
- package/dist/proto-o9HLmF90.es.js +0 -6
- package/dist/pug-Br4hpvIv.es.js +0 -12
- package/dist/pug-CFQMpTUe.cjs.js +0 -1
- package/dist/puppet-cIrXIuy8.cjs.js +0 -1
- package/dist/puppet-wpGOnQp5.es.js +0 -6
- package/dist/purescript-B_1NgE2N.es.js +0 -6
- package/dist/purescript-CX9QPs2N.cjs.js +0 -1
- package/dist/python-B9x3euv6.cjs.js +0 -1
- package/dist/python-xYxLFJY-.es.js +0 -6
- package/dist/qml-CzqrIM5W.cjs.js +0 -1
- package/dist/qml-D5gi21kK.es.js +0 -8
- package/dist/qmldir-BInDYbpo.es.js +0 -6
- package/dist/qmldir-DNF9H2ir.cjs.js +0 -1
- package/dist/qss-C744dLby.cjs.js +0 -1
- package/dist/qss-D-h4NdUG.es.js +0 -6
- package/dist/r-DgOc9oMe.cjs.js +0 -1
- package/dist/r-F-9I-ITZ.es.js +0 -6
- package/dist/racket-BoD1TBFT.es.js +0 -6
- package/dist/racket-Do9_vqnd.cjs.js +0 -1
- package/dist/raku-BW8wAUIz.cjs.js +0 -1
- package/dist/raku-IaYcw19m.es.js +0 -6
- package/dist/razor-Bt_t1YJb.es.js +0 -10
- package/dist/razor-COQhlwWF.cjs.js +0 -1
- package/dist/red-7y8PH7HH.es.js +0 -4
- package/dist/red-BQGOv1D5.cjs.js +0 -1
- package/dist/reg-CGWN_v-z.cjs.js +0 -1
- package/dist/reg-CMUdAgIP.es.js +0 -6
- package/dist/regexp-GiFkbxS-.es.js +0 -6
- package/dist/regexp-N7Z4hEeU.cjs.js +0 -1
- package/dist/rel-BYqA7mnV.cjs.js +0 -1
- package/dist/rel-BaRn3QX7.es.js +0 -6
- package/dist/riscv-B9V3SsvW.es.js +0 -6
- package/dist/riscv-ayQMUpo9.cjs.js +0 -1
- package/dist/rose-pine-DKEdv1Oe.cjs.js +0 -1
- package/dist/rose-pine-DhT-HZE9.es.js +0 -4
- package/dist/rose-pine-dawn-Bvt6DtVH.cjs.js +0 -1
- package/dist/rose-pine-dawn-DiCjL2i4.es.js +0 -4
- package/dist/rose-pine-moon-BNmGHlcn.es.js +0 -4
- package/dist/rose-pine-moon-cHuJy0Ng.cjs.js +0 -1
- package/dist/rst-BmKw97ch.es.js +0 -22
- package/dist/rst-Bq-h_T5U.cjs.js +0 -1
- package/dist/ruby-Bw5IEIKD.cjs.js +0 -1
- package/dist/ruby-cs7BSa_9.es.js +0 -30
- package/dist/rust-BnFKGEfa.cjs.js +0 -1
- package/dist/rust-Pc7DCsZD.es.js +0 -6
- package/dist/sas-BWKaSYkZ.cjs.js +0 -1
- package/dist/sas-DgvHx4mL.es.js +0 -8
- package/dist/sass-B9gYryDE.cjs.js +0 -1
- package/dist/sass-iCyS6eP9.es.js +0 -6
- package/dist/scala-C85dOwSU.cjs.js +0 -1
- package/dist/scala-Cly-fENF.es.js +0 -6
- package/dist/scheme-B_XUaARm.cjs.js +0 -1
- package/dist/scheme-Zi24oEYu.es.js +0 -6
- package/dist/scss-B_hSZppj.es.js +0 -8
- package/dist/scss-CV3c8_Y7.cjs.js +0 -1
- package/dist/sdbl-7Y5u0OW0.cjs.js +0 -1
- package/dist/sdbl-BBamrXFL.es.js +0 -6
- package/dist/shaderlab-CJ8U2E2w.cjs.js +0 -1
- package/dist/shaderlab-U9mqcu_f.es.js +0 -8
- package/dist/shellscript-3DYM9fut.cjs.js +0 -1
- package/dist/shellscript-Dn0-btNd.es.js +0 -6
- package/dist/shellsession-CbKmorC3.cjs.js +0 -1
- package/dist/shellsession-LvXGClmj.es.js +0 -8
- package/dist/slack-dark-akqwQ7ED.cjs.js +0 -1
- package/dist/slack-dark-i7wN4OET.es.js +0 -4
- package/dist/slack-ochin-BoQQWmTv.cjs.js +0 -1
- package/dist/slack-ochin-ndHf0LoP.es.js +0 -4
- package/dist/smalltalk-CCvytUuW.cjs.js +0 -1
- package/dist/smalltalk-Cns31tKw.es.js +0 -6
- package/dist/snazzy-light-BlSJXAu4.es.js +0 -4
- package/dist/snazzy-light-D_IwRieF.cjs.js +0 -1
- package/dist/solarized-dark-UTmkh7lw.es.js +0 -4
- package/dist/solarized-dark-gmm-WbDC.cjs.js +0 -1
- package/dist/solarized-light-BheCkDPT.es.js +0 -4
- package/dist/solarized-light-DzcxRSZP.cjs.js +0 -1
- package/dist/solidity-BG_k8fA_.es.js +0 -6
- package/dist/solidity-BcNcjFC4.cjs.js +0 -1
- package/dist/soy-B2d9ZydM.cjs.js +0 -1
- package/dist/soy-C0yEn39K.es.js +0 -8
- package/dist/sparql-CiBxIK0g.cjs.js +0 -1
- package/dist/sparql-CuZaxpno.es.js +0 -8
- package/dist/splunk-CTqDjQdo.es.js +0 -6
- package/dist/splunk-CzITjJj7.cjs.js +0 -1
- package/dist/sql-BqWZrLHB.cjs.js +0 -1
- package/dist/sql-DCkt643-.es.js +0 -6
- package/dist/ssh-config-DHHGll-v.es.js +0 -6
- package/dist/ssh-config-DUPeuEdB.cjs.js +0 -1
- package/dist/stata-B8m3qL-x.cjs.js +0 -1
- package/dist/stata-Dv81f34z.es.js +0 -8
- package/dist/stylus-ByHs6N-o.cjs.js +0 -1
- package/dist/stylus-n_9f0QQ5.es.js +0 -6
- package/dist/svelte-CfLoBBrI.cjs.js +0 -1
- package/dist/svelte-SoJd35Jr.es.js +0 -14
- package/dist/swift-BAWqNR8A.es.js +0 -6
- package/dist/swift-C5DnOriA.cjs.js +0 -1
- package/dist/synthwave-84-BBRLOmNT.cjs.js +0 -1
- package/dist/synthwave-84-NU3C_KFZ.es.js +0 -4
- package/dist/system-verilog-ClPLYLwh.cjs.js +0 -1
- package/dist/system-verilog-Cui-g-ut.es.js +0 -6
- package/dist/systemd-BASX0DlX.cjs.js +0 -1
- package/dist/systemd-CsKYQIQK.es.js +0 -6
- package/dist/talonscript-D2dGh8FO.es.js +0 -6
- package/dist/talonscript-DkCSnLHD.cjs.js +0 -1
- package/dist/tasl-BAQJK7KZ.cjs.js +0 -1
- package/dist/tasl-D3W8HMV6.es.js +0 -6
- package/dist/tcl-2y0Fuc4S.es.js +0 -6
- package/dist/tcl-CwJAYTvh.cjs.js +0 -1
- package/dist/templ-BSMv2wKZ.cjs.js +0 -1
- package/dist/templ-C7he2afp.es.js +0 -12
- package/dist/terraform-BGW6Oerf.es.js +0 -6
- package/dist/terraform-s-pzyVvp.cjs.js +0 -1
- package/dist/tex-B0y3cEZp.es.js +0 -8
- package/dist/tex-DwtFCA08.cjs.js +0 -1
- package/dist/tokyo-night-9T7_vGSy.cjs.js +0 -1
- package/dist/tokyo-night-LhP3hHhi.es.js +0 -4
- package/dist/toml-CQSfOn0e.es.js +0 -6
- package/dist/toml-CyMM7IXy.cjs.js +0 -1
- package/dist/ts-tags-C5-4VQhf.es.js +0 -41
- package/dist/ts-tags-MIr66hKK.cjs.js +0 -1
- package/dist/tsv-BtvSkaG0.es.js +0 -6
- package/dist/tsv-DqNGnuVj.cjs.js +0 -1
- package/dist/tsx-DiGsgWT8.es.js +0 -6
- package/dist/tsx-DpBRUnKC.cjs.js +0 -1
- package/dist/turtle-BJ2wmjPc.es.js +0 -6
- package/dist/turtle-DfO3eAsu.cjs.js +0 -1
- package/dist/twig-BzjoX4ZJ.cjs.js +0 -1
- package/dist/twig-OmkATFdv.es.js +0 -18
- package/dist/typescript-BqvpT6pB.cjs.js +0 -1
- package/dist/typescript-buWNZFwO.es.js +0 -6
- package/dist/typespec-P-ZVy8yC.cjs.js +0 -1
- package/dist/typespec-bLbdsxJL.es.js +0 -6
- package/dist/typst-BVh2IsT9.cjs.js +0 -1
- package/dist/typst-Y9_SmXTs.es.js +0 -6
- package/dist/v-BUlE9136.cjs.js +0 -1
- package/dist/v-wa8Orrdd.es.js +0 -6
- package/dist/vala-BIymb2K_.cjs.js +0 -1
- package/dist/vala-DRdriFr_.es.js +0 -6
- package/dist/vb-E2_-jk4M.es.js +0 -6
- package/dist/vb-IXOh8mqV.cjs.js +0 -1
- package/dist/verilog-B1iBoR5_.es.js +0 -6
- package/dist/verilog-BiglCqvO.cjs.js +0 -1
- package/dist/vesper-CJsaOsSM.es.js +0 -4
- package/dist/vesper-DqLWLxOu.cjs.js +0 -1
- package/dist/vhdl-CJUzuS2t.cjs.js +0 -1
- package/dist/vhdl-CRVaAhXk.es.js +0 -6
- package/dist/viml-B-zWOd7Z.es.js +0 -6
- package/dist/viml-B1nKLcgt.cjs.js +0 -1
- package/dist/vitesse-black-BoGvW84i.es.js +0 -4
- package/dist/vitesse-black-MF-1S1MG.cjs.js +0 -1
- package/dist/vitesse-dark-Cym-eLtO.es.js +0 -4
- package/dist/vitesse-dark-SIffJYSe.cjs.js +0 -1
- package/dist/vitesse-light-CcmG315c.es.js +0 -4
- package/dist/vitesse-light-U63SkYGT.cjs.js +0 -1
- package/dist/vue-DCwwWMGI.es.js +0 -31
- package/dist/vue-DYZqcRaZ.cjs.js +0 -1
- package/dist/vue-html-CdPbyrq1.cjs.js +0 -1
- package/dist/vue-html-sRE_Ny23.es.js +0 -10
- package/dist/vyper-CO9xUkIY.cjs.js +0 -1
- package/dist/vyper-DWutKXpa.es.js +0 -6
- package/dist/wasm-Bv5f0gKv.es.js +0 -6
- package/dist/wasm-CdIThIat.cjs.js +0 -1
- package/dist/wenyan-BMYnfus1.es.js +0 -6
- package/dist/wenyan-BSJ3fk7e.cjs.js +0 -1
- package/dist/wgsl-DnPoPGDU.es.js +0 -6
- package/dist/wgsl-d3zZE7ZN.cjs.js +0 -1
- package/dist/wikitext-BRCqXN2g.cjs.js +0 -1
- package/dist/wikitext-CntM04PE.es.js +0 -6
- package/dist/wolfram-C3rR92zj.cjs.js +0 -1
- package/dist/wolfram-Ws5qPlX9.es.js +0 -6
- package/dist/xml-BRLTD55J.cjs.js +0 -1
- package/dist/xml-Ch1q_kJp.es.js +0 -8
- package/dist/xsl-DyL8yqXw.es.js +0 -8
- package/dist/xsl-ETbYGV_-.cjs.js +0 -1
- package/dist/yaml-7DV6pRKj.cjs.js +0 -1
- package/dist/yaml-Bbg74JKr.es.js +0 -6
- package/dist/zenscript-BWMxwjeH.cjs.js +0 -1
- package/dist/zenscript-C0RKE4nU.es.js +0 -6
- package/dist/zig-D6SXBGNm.es.js +0 -6
- package/dist/zig-yAcNfpgW.cjs.js +0 -1
|
@@ -0,0 +1,758 @@
|
|
|
1
|
+
import { useMemo } from "react";
|
|
2
|
+
import { useServer } from "../components/ServerProvider";
|
|
3
|
+
import { FilterSelection, FilterValuePrimitive } from "./useDimensionFilters";
|
|
4
|
+
import { useQueryWithApiError } from "./useQueryWithApiError";
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Filter types for dimensions
|
|
8
|
+
*/
|
|
9
|
+
export type FilterType =
|
|
10
|
+
| "NONE"
|
|
11
|
+
| "Star"
|
|
12
|
+
| "MinMax"
|
|
13
|
+
| "DateMinMax"
|
|
14
|
+
| "Retrieval"
|
|
15
|
+
| "Boolean";
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Specification for a dimension to filter
|
|
19
|
+
*/
|
|
20
|
+
export interface DimensionSpec {
|
|
21
|
+
/** Name of the dimension field */
|
|
22
|
+
dimensionName: string;
|
|
23
|
+
/** Type of filter to apply */
|
|
24
|
+
filterType: FilterType;
|
|
25
|
+
/** Source name within the model */
|
|
26
|
+
source: string;
|
|
27
|
+
/** Model path */
|
|
28
|
+
model: string;
|
|
29
|
+
/** Minimum similarity score for Retrieval filter type (default: 0.1) */
|
|
30
|
+
minSimilarityScore?: number;
|
|
31
|
+
/** Optional list of static values to use for the dropdown instead of querying */
|
|
32
|
+
values?: string[];
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Value information for a dimension
|
|
37
|
+
*/
|
|
38
|
+
export interface DimensionValue {
|
|
39
|
+
value: FilterValuePrimitive;
|
|
40
|
+
count?: number;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Result type mapping dimension names to their values
|
|
45
|
+
*/
|
|
46
|
+
export type DimensionValues = Map<string, DimensionValue[]>;
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Parameters for the useDimensionalFilterRangeData hook
|
|
50
|
+
*/
|
|
51
|
+
export interface UseDimensionalFilterRangeDataParams {
|
|
52
|
+
/** Project name */
|
|
53
|
+
project: string;
|
|
54
|
+
/** Package name */
|
|
55
|
+
package: string;
|
|
56
|
+
/** List of dimension specifications (each includes source and model) */
|
|
57
|
+
dimensionSpecs: DimensionSpec[];
|
|
58
|
+
/** Version ID (optional) */
|
|
59
|
+
versionId?: string;
|
|
60
|
+
/** Whether the query should be enabled */
|
|
61
|
+
enabled?: boolean;
|
|
62
|
+
/** Maximum number of index results to return (default: 1000) */
|
|
63
|
+
indexLimit?: number;
|
|
64
|
+
/** Active filter selections to apply when fetching dimension values (optional) */
|
|
65
|
+
activeFilters?: FilterSelection[];
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Result from the useDimensionalFilterRangeData hook
|
|
70
|
+
*/
|
|
71
|
+
export interface DimensionalFilterRangeDataResult {
|
|
72
|
+
/** Map of dimension names to their values */
|
|
73
|
+
data: DimensionValues | undefined;
|
|
74
|
+
/** Whether no rows matched the filter */
|
|
75
|
+
noRowsMatchedFilter: boolean;
|
|
76
|
+
/** Whether the query is loading */
|
|
77
|
+
isLoading: boolean;
|
|
78
|
+
/** Whether the query encountered an error */
|
|
79
|
+
isError: boolean;
|
|
80
|
+
/** Error object if query failed */
|
|
81
|
+
error: Error | null;
|
|
82
|
+
/** Refetch function to manually trigger the query */
|
|
83
|
+
refetch: () => void;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Escapes special characters in strings for Malloy queries
|
|
88
|
+
*/
|
|
89
|
+
function escapeMalloyString(value: string): string {
|
|
90
|
+
return value.replace(/'/g, "\\'").replace(/\\/g, "\\\\");
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Formats a value for use in Malloy query
|
|
95
|
+
*/
|
|
96
|
+
function formatMalloyValue(
|
|
97
|
+
value: FilterValuePrimitive | null | undefined,
|
|
98
|
+
isDate: boolean = false,
|
|
99
|
+
): string {
|
|
100
|
+
if (value === null || value === undefined) {
|
|
101
|
+
return "null";
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
if (isDate) {
|
|
105
|
+
if (value instanceof Date) {
|
|
106
|
+
// Format as YYYY-MM-DD
|
|
107
|
+
return `@${value.getFullYear()}-${String(value.getMonth() + 1).padStart(2, "0")}-${String(value.getDate()).padStart(2, "0")}`;
|
|
108
|
+
}
|
|
109
|
+
// If it's a string, assume it's already in ISO format
|
|
110
|
+
return `@${value}`;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
if (typeof value === "string") {
|
|
114
|
+
return `'${escapeMalloyString(value)}'`;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
if (typeof value === "number") {
|
|
118
|
+
return String(value);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
if (typeof value === "boolean") {
|
|
122
|
+
return value ? "true" : "false";
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
return String(value);
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* Generates a Malloy filter condition for a single filter selection
|
|
130
|
+
*/
|
|
131
|
+
function generateFilterCondition(selection: FilterSelection): string {
|
|
132
|
+
const { dimensionName, matchType, value, value2 } = selection;
|
|
133
|
+
const fieldName = `\`${dimensionName}\``;
|
|
134
|
+
|
|
135
|
+
// Determine if this is a date field based on the value
|
|
136
|
+
const isDate = value instanceof Date;
|
|
137
|
+
|
|
138
|
+
switch (matchType) {
|
|
139
|
+
case "Equals":
|
|
140
|
+
case "Concept Search":
|
|
141
|
+
if (Array.isArray(value) && value.length > 0) {
|
|
142
|
+
// Handle multi-select: (field = val1 or field = val2)
|
|
143
|
+
const conditions = value.map(
|
|
144
|
+
(v) => `${fieldName} = ${formatMalloyValue(v, isDate)}`,
|
|
145
|
+
);
|
|
146
|
+
return `(${conditions.join(" or ")})`;
|
|
147
|
+
}
|
|
148
|
+
// Empty array or single value
|
|
149
|
+
if (Array.isArray(value)) return "";
|
|
150
|
+
return `${fieldName} = ${formatMalloyValue(value, isDate)}`;
|
|
151
|
+
|
|
152
|
+
case "Contains":
|
|
153
|
+
if (typeof value === "string") {
|
|
154
|
+
return `${fieldName} ~ f'%${escapeMalloyString(value)}%'`;
|
|
155
|
+
}
|
|
156
|
+
if (Array.isArray(value)) return "";
|
|
157
|
+
return `${fieldName} = ${formatMalloyValue(value)}`;
|
|
158
|
+
|
|
159
|
+
case "After":
|
|
160
|
+
if (Array.isArray(value)) return "";
|
|
161
|
+
return `${fieldName} > ${formatMalloyValue(value, isDate)}`;
|
|
162
|
+
|
|
163
|
+
case "Before":
|
|
164
|
+
if (Array.isArray(value)) return "";
|
|
165
|
+
return `${fieldName} < ${formatMalloyValue(value, isDate)}`;
|
|
166
|
+
|
|
167
|
+
case "Greater Than":
|
|
168
|
+
if (Array.isArray(value)) return "";
|
|
169
|
+
return `${fieldName} > ${formatMalloyValue(value)}`;
|
|
170
|
+
|
|
171
|
+
case "Less Than":
|
|
172
|
+
if (Array.isArray(value)) return "";
|
|
173
|
+
return `${fieldName} < ${formatMalloyValue(value)}`;
|
|
174
|
+
|
|
175
|
+
case "Between":
|
|
176
|
+
if (Array.isArray(value)) return "";
|
|
177
|
+
if (value2 !== undefined) {
|
|
178
|
+
return `${fieldName} >= ${formatMalloyValue(value, isDate)} and ${fieldName} <= ${formatMalloyValue(value2, isDate)}`;
|
|
179
|
+
}
|
|
180
|
+
return `${fieldName} >= ${formatMalloyValue(value, isDate)}`;
|
|
181
|
+
|
|
182
|
+
default:
|
|
183
|
+
return "";
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
/**
|
|
188
|
+
* Groups dimension specs by source/model combination
|
|
189
|
+
* Returns a map where key is "source|model" and value is array of specs for that combo
|
|
190
|
+
*/
|
|
191
|
+
function groupSpecsBySourceModel(
|
|
192
|
+
dimensionSpecs: DimensionSpec[],
|
|
193
|
+
): Map<string, DimensionSpec[]> {
|
|
194
|
+
const groups = new Map<string, DimensionSpec[]>();
|
|
195
|
+
|
|
196
|
+
for (const spec of dimensionSpecs) {
|
|
197
|
+
const key = `${spec.source}|${spec.model}`;
|
|
198
|
+
const existing = groups.get(key) || [];
|
|
199
|
+
existing.push(spec);
|
|
200
|
+
groups.set(key, existing);
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
return groups;
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
/**
|
|
207
|
+
* Builds a Malloy index query to fetch dimension values for a single source
|
|
208
|
+
* Uses Malloy's built-in index operator for dimensional search
|
|
209
|
+
* Reference: https://docs.malloydata.dev/documentation/patterns/dim_index
|
|
210
|
+
*/
|
|
211
|
+
function buildDimensionalIndexQuery(
|
|
212
|
+
source: string,
|
|
213
|
+
dimensionSpecs: DimensionSpec[],
|
|
214
|
+
indexLimit: number,
|
|
215
|
+
activeFilters?: FilterSelection[],
|
|
216
|
+
): string {
|
|
217
|
+
// Filter out specs that don't need data fetching
|
|
218
|
+
const specsToFetch = dimensionSpecs.filter(
|
|
219
|
+
(spec) =>
|
|
220
|
+
(spec.filterType === "Star" ||
|
|
221
|
+
spec.filterType === "MinMax" ||
|
|
222
|
+
spec.filterType === "DateMinMax") &&
|
|
223
|
+
!spec.values,
|
|
224
|
+
);
|
|
225
|
+
|
|
226
|
+
if (specsToFetch.length === 0) {
|
|
227
|
+
return "";
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
// Build list of dimensions to index
|
|
231
|
+
const dimensionsToIndex = specsToFetch
|
|
232
|
+
.map((spec) => `\`${spec.dimensionName}\``)
|
|
233
|
+
.join(", ");
|
|
234
|
+
|
|
235
|
+
// Filter activeFilters to only include those for this source
|
|
236
|
+
const filtersForSource =
|
|
237
|
+
activeFilters?.filter((f) => {
|
|
238
|
+
// Find the spec for this filter's dimension
|
|
239
|
+
const spec = dimensionSpecs.find(
|
|
240
|
+
(s) => s.dimensionName === f.dimensionName,
|
|
241
|
+
);
|
|
242
|
+
return spec?.source === source;
|
|
243
|
+
}) || [];
|
|
244
|
+
|
|
245
|
+
// Generate WHERE conditions from active filters (without 'where' keyword)
|
|
246
|
+
const whereConditions =
|
|
247
|
+
filtersForSource.length > 0
|
|
248
|
+
? filtersForSource
|
|
249
|
+
.map((selection) => generateFilterCondition(selection))
|
|
250
|
+
.filter((condition) => condition.length > 0)
|
|
251
|
+
.join(" and ")
|
|
252
|
+
: "";
|
|
253
|
+
|
|
254
|
+
// Use Malloy's index operator to create a dimensional search index
|
|
255
|
+
// The index operator returns: fieldName, fieldPath, fieldType, fieldValue, weight
|
|
256
|
+
// For strings: returns distinct values with weights (counts)
|
|
257
|
+
// For numbers/dates: returns ranges (min to max)
|
|
258
|
+
//
|
|
259
|
+
// Important: where clause and index must be in the SAME query stage
|
|
260
|
+
// Use a two-stage query: first stage creates the filtered index, second stage orders by weight
|
|
261
|
+
return `
|
|
262
|
+
run: ${source} -> {
|
|
263
|
+
${whereConditions ? `where: ${whereConditions}` : ""}
|
|
264
|
+
index: ${dimensionsToIndex}
|
|
265
|
+
} -> {
|
|
266
|
+
select: *
|
|
267
|
+
order_by: weight desc
|
|
268
|
+
|
|
269
|
+
limit: ${indexLimit}
|
|
270
|
+
}
|
|
271
|
+
`;
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
/**
|
|
275
|
+
* Cell types from Malloy query results
|
|
276
|
+
*/
|
|
277
|
+
interface MalloyCell {
|
|
278
|
+
kind: string;
|
|
279
|
+
string_value?: string;
|
|
280
|
+
number_value?: number;
|
|
281
|
+
boolean_value?: boolean;
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
/**
|
|
285
|
+
* Record cell from Malloy query results
|
|
286
|
+
*/
|
|
287
|
+
interface MalloyRecordCell {
|
|
288
|
+
kind: "record_cell";
|
|
289
|
+
record_value: MalloyCell[];
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
/**
|
|
293
|
+
* Schema field from Malloy query results
|
|
294
|
+
*/
|
|
295
|
+
interface MalloySchemaField {
|
|
296
|
+
name: string;
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
/**
|
|
300
|
+
* Malloy index query result entry
|
|
301
|
+
*/
|
|
302
|
+
interface MalloyIndexEntry {
|
|
303
|
+
fieldName?: string;
|
|
304
|
+
fieldPath?: string;
|
|
305
|
+
fieldType?: string;
|
|
306
|
+
fieldValue?: string;
|
|
307
|
+
weight?: number;
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
/**
|
|
311
|
+
* Parsed Malloy query result structure
|
|
312
|
+
*/
|
|
313
|
+
interface MalloyQueryResult {
|
|
314
|
+
schema: {
|
|
315
|
+
fields: MalloySchemaField[];
|
|
316
|
+
};
|
|
317
|
+
data?: {
|
|
318
|
+
array_value?: MalloyRecordCell[];
|
|
319
|
+
};
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
/**
|
|
323
|
+
* Parses the Malloy index query result and converts it to a DimensionValues map
|
|
324
|
+
* The index operator returns: fieldName, fieldPath, fieldType, fieldValue, weight
|
|
325
|
+
* Reference: https://docs.malloydata.dev/documentation/patterns/dim_index
|
|
326
|
+
*/
|
|
327
|
+
function parseIndexQueryResult(
|
|
328
|
+
result: string,
|
|
329
|
+
dimensionSpecs: DimensionSpec[],
|
|
330
|
+
): { values: DimensionValues; noRowsMatchedFilter: boolean } {
|
|
331
|
+
const dimensionValues = new Map<string, DimensionValue[]>();
|
|
332
|
+
|
|
333
|
+
// Initialize empty arrays for all dimensions
|
|
334
|
+
for (const spec of dimensionSpecs) {
|
|
335
|
+
dimensionValues.set(spec.dimensionName, []);
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
// Parse the result JSON if it's a string
|
|
339
|
+
const parsedResult = JSON.parse(result) as MalloyQueryResult;
|
|
340
|
+
|
|
341
|
+
// Parse schema to understand field positions
|
|
342
|
+
const schema = parsedResult.schema.fields;
|
|
343
|
+
const fieldMap = new Map<string, number>();
|
|
344
|
+
|
|
345
|
+
schema.forEach((field: MalloySchemaField, index: number) => {
|
|
346
|
+
fieldMap.set(field.name, index);
|
|
347
|
+
});
|
|
348
|
+
|
|
349
|
+
// Helper function to extract value from a cell based on its kind
|
|
350
|
+
const extractCellValue = (
|
|
351
|
+
cell: MalloyCell | undefined,
|
|
352
|
+
): string | number | boolean | null => {
|
|
353
|
+
if (!cell) return null;
|
|
354
|
+
|
|
355
|
+
switch (cell.kind) {
|
|
356
|
+
case "string_cell":
|
|
357
|
+
return cell.string_value ?? null;
|
|
358
|
+
case "number_cell":
|
|
359
|
+
return cell.number_value ?? null;
|
|
360
|
+
case "boolean_cell":
|
|
361
|
+
return cell.boolean_value ?? null;
|
|
362
|
+
default:
|
|
363
|
+
console.log("Unknown cell kind: " + cell.kind);
|
|
364
|
+
return null;
|
|
365
|
+
}
|
|
366
|
+
};
|
|
367
|
+
|
|
368
|
+
// Convert array_value records to objects using schema
|
|
369
|
+
const rawData = parsedResult.data?.array_value || [];
|
|
370
|
+
const indexData: MalloyIndexEntry[] = rawData.map(
|
|
371
|
+
(record: MalloyRecordCell) => {
|
|
372
|
+
const obj: MalloyIndexEntry = {};
|
|
373
|
+
|
|
374
|
+
if (record.kind === "record_cell" && record.record_value) {
|
|
375
|
+
record.record_value.forEach((cell: MalloyCell, index: number) => {
|
|
376
|
+
const fieldName = schema[index]?.name;
|
|
377
|
+
if (fieldName) {
|
|
378
|
+
const value = extractCellValue(cell);
|
|
379
|
+
if (fieldName === "fieldName" && typeof value === "string") {
|
|
380
|
+
obj.fieldName = value;
|
|
381
|
+
} else if (
|
|
382
|
+
fieldName === "fieldPath" &&
|
|
383
|
+
typeof value === "string"
|
|
384
|
+
) {
|
|
385
|
+
obj.fieldPath = value;
|
|
386
|
+
} else if (
|
|
387
|
+
fieldName === "fieldType" &&
|
|
388
|
+
typeof value === "string"
|
|
389
|
+
) {
|
|
390
|
+
obj.fieldType = value;
|
|
391
|
+
} else if (
|
|
392
|
+
fieldName === "fieldValue" &&
|
|
393
|
+
typeof value === "string"
|
|
394
|
+
) {
|
|
395
|
+
obj.fieldValue = value;
|
|
396
|
+
} else if (
|
|
397
|
+
fieldName === "weight" &&
|
|
398
|
+
typeof value === "number"
|
|
399
|
+
) {
|
|
400
|
+
obj.weight = value;
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
});
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
return obj;
|
|
407
|
+
},
|
|
408
|
+
);
|
|
409
|
+
|
|
410
|
+
const noRowsMatchedFilter =
|
|
411
|
+
indexData.length === 0 ||
|
|
412
|
+
indexData.every((entry: MalloyIndexEntry) => !entry.fieldName);
|
|
413
|
+
|
|
414
|
+
// Group index results by fieldName/dimensionName
|
|
415
|
+
for (const spec of dimensionSpecs) {
|
|
416
|
+
if (spec.filterType === "NONE" || spec.filterType === "Retrieval") {
|
|
417
|
+
// These types don't fetch values
|
|
418
|
+
continue;
|
|
419
|
+
}
|
|
420
|
+
|
|
421
|
+
// Find all index entries for this dimension
|
|
422
|
+
// Try multiple matching strategies since field naming can vary
|
|
423
|
+
const dimensionEntries = indexData.filter((entry: MalloyIndexEntry) => {
|
|
424
|
+
const fieldName = entry.fieldName || "";
|
|
425
|
+
const fieldPath = entry.fieldPath || "";
|
|
426
|
+
|
|
427
|
+
// Try exact match
|
|
428
|
+
if (
|
|
429
|
+
fieldName === spec.dimensionName ||
|
|
430
|
+
fieldPath === spec.dimensionName
|
|
431
|
+
) {
|
|
432
|
+
return true;
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
// Try case-insensitive match
|
|
436
|
+
if (
|
|
437
|
+
fieldName.toLowerCase() === spec.dimensionName.toLowerCase() ||
|
|
438
|
+
fieldPath.toLowerCase() === spec.dimensionName.toLowerCase()
|
|
439
|
+
) {
|
|
440
|
+
return true;
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
// Try matching the last part of a path (e.g., "source.field" matches "field")
|
|
444
|
+
const lastPathPart = fieldPath.split(".").pop() || "";
|
|
445
|
+
if (
|
|
446
|
+
lastPathPart === spec.dimensionName ||
|
|
447
|
+
lastPathPart.toLowerCase() === spec.dimensionName.toLowerCase()
|
|
448
|
+
) {
|
|
449
|
+
return true;
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
return false;
|
|
453
|
+
});
|
|
454
|
+
|
|
455
|
+
if (dimensionEntries.length === 0) {
|
|
456
|
+
continue;
|
|
457
|
+
}
|
|
458
|
+
|
|
459
|
+
if (spec.filterType === "Star") {
|
|
460
|
+
// For Star filter, we want all distinct values with their weights
|
|
461
|
+
// String fields return individual fieldValue entries
|
|
462
|
+
const values = dimensionEntries
|
|
463
|
+
.filter((entry: MalloyIndexEntry) => entry.fieldType === "string")
|
|
464
|
+
.map((entry: MalloyIndexEntry) => ({
|
|
465
|
+
value: entry.fieldValue ?? "",
|
|
466
|
+
count: entry.weight,
|
|
467
|
+
}))
|
|
468
|
+
.sort(
|
|
469
|
+
(a: DimensionValue, b: DimensionValue) =>
|
|
470
|
+
(b.count ?? 0) - (a.count ?? 0),
|
|
471
|
+
); // Sort by count descending
|
|
472
|
+
|
|
473
|
+
dimensionValues.set(spec.dimensionName, values);
|
|
474
|
+
} else if (spec.filterType === "MinMax") {
|
|
475
|
+
// For MinMax filter, numeric fields return a range in fieldValue
|
|
476
|
+
// Format is typically "min to max"
|
|
477
|
+
console.log(
|
|
478
|
+
"MinMax dimensionEntries: " +
|
|
479
|
+
JSON.stringify(dimensionEntries, null, 2),
|
|
480
|
+
);
|
|
481
|
+
console.log(
|
|
482
|
+
"All MinMax dimension entries fieldTypes:",
|
|
483
|
+
dimensionEntries.map((e: MalloyIndexEntry) => e.fieldType),
|
|
484
|
+
);
|
|
485
|
+
|
|
486
|
+
const numericEntry = dimensionEntries.find(
|
|
487
|
+
(entry: MalloyIndexEntry) => entry.fieldType === "number",
|
|
488
|
+
);
|
|
489
|
+
|
|
490
|
+
console.log("numericEntry: " + JSON.stringify(numericEntry, null, 2));
|
|
491
|
+
if (numericEntry?.fieldValue) {
|
|
492
|
+
const rangeString = numericEntry.fieldValue;
|
|
493
|
+
// Parse "min to max" format
|
|
494
|
+
const rangeParts = rangeString.split(" to ");
|
|
495
|
+
|
|
496
|
+
console.log("rangeParts: " + rangeParts);
|
|
497
|
+
|
|
498
|
+
if (rangeParts.length === 2) {
|
|
499
|
+
const values = [
|
|
500
|
+
{ value: parseFloat(rangeParts[0]) },
|
|
501
|
+
{ value: parseFloat(rangeParts[1]) },
|
|
502
|
+
];
|
|
503
|
+
dimensionValues.set(spec.dimensionName, values);
|
|
504
|
+
} else {
|
|
505
|
+
console.warn(
|
|
506
|
+
`Could not parse numeric range for ${spec.dimensionName}: ${rangeString}`,
|
|
507
|
+
);
|
|
508
|
+
}
|
|
509
|
+
} else {
|
|
510
|
+
console.warn(
|
|
511
|
+
`No numeric entry found for ${spec.dimensionName}. Available entries:`,
|
|
512
|
+
dimensionEntries,
|
|
513
|
+
);
|
|
514
|
+
}
|
|
515
|
+
} else if (spec.filterType === "DateMinMax") {
|
|
516
|
+
// For DateMinMax filter, date/timestamp fields return a range in fieldValue
|
|
517
|
+
// Format is typically "YYYY-MM-DD to YYYY-MM-DD"
|
|
518
|
+
|
|
519
|
+
// Look for date, timestamp, or string type entries (dates can come back in various formats)
|
|
520
|
+
const dateEntry = dimensionEntries.find(
|
|
521
|
+
(entry: MalloyIndexEntry) =>
|
|
522
|
+
entry.fieldType === "date" ||
|
|
523
|
+
entry.fieldType === "timestamp" ||
|
|
524
|
+
entry.fieldType === "string",
|
|
525
|
+
);
|
|
526
|
+
|
|
527
|
+
console.log("dateEntry: " + JSON.stringify(dateEntry, null, 2));
|
|
528
|
+
console.log(
|
|
529
|
+
"All date dimension entries fieldTypes:",
|
|
530
|
+
dimensionEntries.map((e: MalloyIndexEntry) => e.fieldType),
|
|
531
|
+
);
|
|
532
|
+
|
|
533
|
+
if (dateEntry?.fieldValue) {
|
|
534
|
+
const rangeString = dateEntry.fieldValue;
|
|
535
|
+
// Parse "YYYY-MM-DD to YYYY-MM-DD" format
|
|
536
|
+
const rangeParts = rangeString.split(" to ");
|
|
537
|
+
|
|
538
|
+
console.log("date rangeParts: " + rangeParts);
|
|
539
|
+
|
|
540
|
+
if (rangeParts.length === 2) {
|
|
541
|
+
const values = [
|
|
542
|
+
{ value: new Date(rangeParts[0].trim()) },
|
|
543
|
+
{ value: new Date(rangeParts[1].trim()) },
|
|
544
|
+
];
|
|
545
|
+
dimensionValues.set(spec.dimensionName, values);
|
|
546
|
+
} else {
|
|
547
|
+
console.warn(
|
|
548
|
+
`Could not parse date range for ${spec.dimensionName}: ${rangeString}`,
|
|
549
|
+
);
|
|
550
|
+
}
|
|
551
|
+
} else {
|
|
552
|
+
console.warn(
|
|
553
|
+
`No date entry found for ${spec.dimensionName}. Available entries:`,
|
|
554
|
+
dimensionEntries,
|
|
555
|
+
);
|
|
556
|
+
}
|
|
557
|
+
}
|
|
558
|
+
}
|
|
559
|
+
|
|
560
|
+
return { values: dimensionValues, noRowsMatchedFilter };
|
|
561
|
+
}
|
|
562
|
+
|
|
563
|
+
/**
|
|
564
|
+
* Custom hook to fetch dimensional filter values from a Malloy model
|
|
565
|
+
*
|
|
566
|
+
* This hook uses Malloy's built-in `index` operator to create dimensional search indexes
|
|
567
|
+
* for the specified dimensions. The index operator efficiently returns distinct values
|
|
568
|
+
* and ranges for dimensions in a single query.
|
|
569
|
+
*
|
|
570
|
+
* Filter types:
|
|
571
|
+
* - NONE: Display only, no values fetched
|
|
572
|
+
* - Star: Fetches all distinct values with counts (for string fields)
|
|
573
|
+
* - MinMax: Fetches minimum and maximum values (for numeric fields as ranges)
|
|
574
|
+
* - DateMinMax: Fetches minimum and maximum values (for date fields as Date objects)
|
|
575
|
+
* - Retrieval: Uses retrieval, no values fetched
|
|
576
|
+
*
|
|
577
|
+
* Reference: https://docs.malloydata.dev/documentation/patterns/dim_index
|
|
578
|
+
*
|
|
579
|
+
* The hook groups dimension specs by source/model combination and runs separate
|
|
580
|
+
* index queries for each group, then merges the results.
|
|
581
|
+
*
|
|
582
|
+
* @param params - Parameters including project, package, and dimension specs (each with source/model)
|
|
583
|
+
* @returns Query result with dimension values map, loading state, and error information
|
|
584
|
+
*
|
|
585
|
+
* @example
|
|
586
|
+
* ```tsx
|
|
587
|
+
* const { data, isLoading, error } = useDimensionalFilterRangeData({
|
|
588
|
+
* project: "my-project",
|
|
589
|
+
* package: "my-package",
|
|
590
|
+
* dimensionSpecs: [
|
|
591
|
+
* { dimensionName: "category", filterType: "Star", source: "my_source", model: "model.malloy" },
|
|
592
|
+
* { dimensionName: "price", filterType: "MinMax", source: "my_source", model: "model.malloy" },
|
|
593
|
+
* { dimensionName: "status", filterType: "Star", source: "other_source", model: "other.malloy" },
|
|
594
|
+
* ],
|
|
595
|
+
* indexLimit: 1000, // Optional: set higher if needed for many Star dimensions
|
|
596
|
+
* });
|
|
597
|
+
* ```
|
|
598
|
+
*/
|
|
599
|
+
export function useDimensionalFilterRangeData(
|
|
600
|
+
params: UseDimensionalFilterRangeDataParams,
|
|
601
|
+
): DimensionalFilterRangeDataResult {
|
|
602
|
+
const {
|
|
603
|
+
project,
|
|
604
|
+
package: packageName,
|
|
605
|
+
dimensionSpecs,
|
|
606
|
+
versionId,
|
|
607
|
+
enabled = true,
|
|
608
|
+
indexLimit = 10000,
|
|
609
|
+
activeFilters = [],
|
|
610
|
+
} = params;
|
|
611
|
+
|
|
612
|
+
// Group dimension specs by source/model combination
|
|
613
|
+
const sourceModelGroups = useMemo(
|
|
614
|
+
() => groupSpecsBySourceModel(dimensionSpecs),
|
|
615
|
+
[dimensionSpecs],
|
|
616
|
+
);
|
|
617
|
+
|
|
618
|
+
// Build query strings for each source/model combo
|
|
619
|
+
const queryConfigs = useMemo(() => {
|
|
620
|
+
const configs: Array<{
|
|
621
|
+
key: string;
|
|
622
|
+
source: string;
|
|
623
|
+
model: string;
|
|
624
|
+
query: string;
|
|
625
|
+
specs: DimensionSpec[];
|
|
626
|
+
}> = [];
|
|
627
|
+
|
|
628
|
+
for (const [key, specs] of sourceModelGroups) {
|
|
629
|
+
const [source, model] = key.split("|");
|
|
630
|
+
const query = buildDimensionalIndexQuery(
|
|
631
|
+
source,
|
|
632
|
+
specs,
|
|
633
|
+
indexLimit,
|
|
634
|
+
activeFilters,
|
|
635
|
+
);
|
|
636
|
+
if (query) {
|
|
637
|
+
configs.push({ key, source, model, query, specs });
|
|
638
|
+
} else {
|
|
639
|
+
console.log("No query for source: ", source, "model: ", model);
|
|
640
|
+
}
|
|
641
|
+
}
|
|
642
|
+
|
|
643
|
+
return configs;
|
|
644
|
+
}, [sourceModelGroups, indexLimit, activeFilters]);
|
|
645
|
+
|
|
646
|
+
// Determine if we need to execute queries
|
|
647
|
+
const shouldExecuteQuery = useMemo(() => {
|
|
648
|
+
return (
|
|
649
|
+
enabled &&
|
|
650
|
+
queryConfigs.length > 0 &&
|
|
651
|
+
dimensionSpecs.some(
|
|
652
|
+
(spec) =>
|
|
653
|
+
spec.filterType === "Star" ||
|
|
654
|
+
spec.filterType === "MinMax" ||
|
|
655
|
+
spec.filterType === "DateMinMax",
|
|
656
|
+
)
|
|
657
|
+
);
|
|
658
|
+
}, [enabled, queryConfigs, dimensionSpecs]);
|
|
659
|
+
|
|
660
|
+
// Execute the query using the API client
|
|
661
|
+
const { apiClients } = useServer();
|
|
662
|
+
|
|
663
|
+
const queryResult = useQueryWithApiError({
|
|
664
|
+
queryKey: [
|
|
665
|
+
"dimensionalFilter",
|
|
666
|
+
project,
|
|
667
|
+
packageName,
|
|
668
|
+
dimensionSpecs,
|
|
669
|
+
versionId,
|
|
670
|
+
activeFilters,
|
|
671
|
+
],
|
|
672
|
+
queryFn: async () => {
|
|
673
|
+
if (!shouldExecuteQuery) {
|
|
674
|
+
// Return empty map if no query needed
|
|
675
|
+
const emptyMap = new Map<string, DimensionValue[]>();
|
|
676
|
+
for (const spec of dimensionSpecs) {
|
|
677
|
+
emptyMap.set(spec.dimensionName, []);
|
|
678
|
+
}
|
|
679
|
+
return { values: emptyMap, noRowsMatchedFilter: false };
|
|
680
|
+
}
|
|
681
|
+
|
|
682
|
+
// Execute queries for each source/model combo in parallel
|
|
683
|
+
const results = await Promise.all(
|
|
684
|
+
queryConfigs.map(async (config) => {
|
|
685
|
+
const response = await apiClients.models.executeQueryModel(
|
|
686
|
+
project,
|
|
687
|
+
packageName,
|
|
688
|
+
config.model,
|
|
689
|
+
{
|
|
690
|
+
query: config.query,
|
|
691
|
+
versionId: versionId,
|
|
692
|
+
},
|
|
693
|
+
);
|
|
694
|
+
return {
|
|
695
|
+
config,
|
|
696
|
+
result: parseIndexQueryResult(
|
|
697
|
+
response.data.result,
|
|
698
|
+
config.specs,
|
|
699
|
+
),
|
|
700
|
+
};
|
|
701
|
+
}),
|
|
702
|
+
);
|
|
703
|
+
|
|
704
|
+
// Merge all results into a single DimensionValues map
|
|
705
|
+
const mergedValues = new Map<string, DimensionValue[]>();
|
|
706
|
+
let anyNoRowsMatched = false;
|
|
707
|
+
|
|
708
|
+
for (const { result } of results) {
|
|
709
|
+
for (const [key, val] of result.values) {
|
|
710
|
+
mergedValues.set(key, val);
|
|
711
|
+
}
|
|
712
|
+
if (result.noRowsMatchedFilter) {
|
|
713
|
+
anyNoRowsMatched = true;
|
|
714
|
+
}
|
|
715
|
+
}
|
|
716
|
+
|
|
717
|
+
return { values: mergedValues, noRowsMatchedFilter: anyNoRowsMatched };
|
|
718
|
+
},
|
|
719
|
+
enabled: shouldExecuteQuery,
|
|
720
|
+
staleTime: 5 * 60 * 1000, // 5 minutes
|
|
721
|
+
placeholderData: (previousData) => previousData, // Keep showing previous data during refetch
|
|
722
|
+
});
|
|
723
|
+
const fetchedValues = queryResult.data?.values;
|
|
724
|
+
const mergedData = useMemo(() => {
|
|
725
|
+
const result = new Map<string, DimensionValue[]>();
|
|
726
|
+
|
|
727
|
+
// Initialize with static values or empty arrays
|
|
728
|
+
for (const spec of dimensionSpecs) {
|
|
729
|
+
if (spec.values) {
|
|
730
|
+
result.set(
|
|
731
|
+
spec.dimensionName,
|
|
732
|
+
spec.values.map((v) => ({ value: v })),
|
|
733
|
+
);
|
|
734
|
+
} else {
|
|
735
|
+
result.set(spec.dimensionName, []);
|
|
736
|
+
}
|
|
737
|
+
}
|
|
738
|
+
|
|
739
|
+
// Merge fetched values
|
|
740
|
+
if (fetchedValues) {
|
|
741
|
+
for (const [key, val] of fetchedValues) {
|
|
742
|
+
if (val.length > 0) {
|
|
743
|
+
result.set(key, val);
|
|
744
|
+
}
|
|
745
|
+
}
|
|
746
|
+
}
|
|
747
|
+
return result;
|
|
748
|
+
}, [dimensionSpecs, fetchedValues]);
|
|
749
|
+
|
|
750
|
+
return {
|
|
751
|
+
data: mergedData,
|
|
752
|
+
noRowsMatchedFilter: queryResult.data?.noRowsMatchedFilter ?? false,
|
|
753
|
+
isLoading: shouldExecuteQuery ? queryResult.isPending : false,
|
|
754
|
+
isError: shouldExecuteQuery ? queryResult.isError : false,
|
|
755
|
+
error: shouldExecuteQuery ? (queryResult.error as Error | null) : null,
|
|
756
|
+
refetch: queryResult.refetch,
|
|
757
|
+
};
|
|
758
|
+
}
|