diff --git a/frontend/src/metabase-lib/order_by.ts b/frontend/src/metabase-lib/order_by.ts index de2d8d5a809a01b5b8a235460fe3fc3766791cca..c9fec15c8eb3906ca13ef28f272f8de557edd98a 100644 --- a/frontend/src/metabase-lib/order_by.ts +++ b/frontend/src/metabase-lib/order_by.ts @@ -20,10 +20,19 @@ declare function OrderByFn( export const orderBy: typeof OrderByFn = ML.order_by; -export function orderByClause( +type OrderByDirection = "asc" | "desc"; + +declare function OrderByClauseFn( query: Query, stageNumber: number, field: Field, -): Field { - return ML.order_by_clause(query, stageNumber, field); -} + direction?: OrderByDirection, +): OrderByClause; +declare function OrderByClauseFn( + query: Query, + stageNumber: number, + field: Field, + direction?: OrderByDirection, +): OrderByClause; + +export const orderByClause: typeof OrderByClauseFn = ML.order_by_clause; diff --git a/frontend/src/metabase-lib/order_by.unit.spec.ts b/frontend/src/metabase-lib/order_by.unit.spec.ts index 467fcb2a38499f127b55f6b0b556c0223e86968d..1befda4610b7ca567042cbf753b54b9f2ed20c3a 100644 --- a/frontend/src/metabase-lib/order_by.unit.spec.ts +++ b/frontend/src/metabase-lib/order_by.unit.spec.ts @@ -79,11 +79,11 @@ describe("order by", () => { const nextQuery = ML.replaceClause( orderedQuery, orderBys[0], - ML.orderByClause(orderedQuery, -1, productCategory as Field) as Field, + ML.orderByClause(orderedQuery, -1, productCategory as Field, "desc"), ); const nextOrderBys = ML.orderBys(nextQuery); expect(ML.displayName(nextQuery, nextOrderBys[0])).toBe( - "Category ascending", + "Category descending", ); expect(orderBys[0]).not.toEqual(nextOrderBys[0]); }); diff --git a/frontend/src/metabase-lib/query.ts b/frontend/src/metabase-lib/query.ts index 824dbd687e95b23045696406073507c980a5928c..99af10d039c572b2e959bfd931f799e2e81662c5 100644 --- a/frontend/src/metabase-lib/query.ts +++ b/frontend/src/metabase-lib/query.ts @@ -1,5 +1,5 @@ import * as ML from "cljs/metabase.lib.js"; -import type { DatabaseId, DatasetQuery, Field } from "metabase-types/api"; +import type { DatabaseId, DatasetQuery } from "metabase-types/api"; import type { Clause, MetadataProvider, Query } from "./types"; export function fromLegacyQuery( @@ -30,13 +30,13 @@ export const removeClause: typeof RemoveClauseFn = ML.remove_clause; declare function ReplaceClauseFn( query: Query, targetClause: Clause, - newClause: Field, + newClause: Clause, ): Query; declare function ReplaceClauseFn( query: Query, stageIndex: number, targetClause: Clause, - newClause: Field, + newClause: Clause, ): Query; export const replaceClause: typeof ReplaceClauseFn = ML.replace_clause; diff --git a/src/metabase/lib/js.cljs b/src/metabase/lib/js.cljs index 782917d771fea68ed87b5abecb9767b71be15bf6..79dffcd0562dad6de4f1550e83ed4b38979bf662 100644 --- a/src/metabase/lib/js.cljs +++ b/src/metabase/lib/js.cljs @@ -106,8 +106,10 @@ (defn ^:export order-by-clause "Create an order-by clause independently of a query, e.g. for `replace` or whatever." - [a-query stage-number x] - (lib.order-by/order-by-clause a-query stage-number (lib.normalize/normalize (js->clj x :keywordize-keys true)))) + ([a-query stage-number x] + (order-by-clause a-query stage-number x nil)) + ([a-query stage-number x direction] + (lib.order-by/order-by-clause a-query stage-number (lib.normalize/normalize (js->clj x :keywordize-keys true)) direction))) (defn ^:export order-by "Add an `order-by` clause to `a-query`. Returns updated query." diff --git a/src/metabase/lib/order_by.cljc b/src/metabase/lib/order_by.cljc index 8edcbc7eadc68da58032ced3d67ed3b48d034e40..93d0b1c790581e4a1c85c2acb7ddb3cf2969cc17 100644 --- a/src/metabase/lib/order_by.cljc +++ b/src/metabase/lib/order_by.cljc @@ -56,20 +56,32 @@ [_query _stage-number x] (lib.options/ensure-uuid [:asc (lib.ref/ref x)])) -(defn order-by-clause - "Create an order-by clause independently of a query, e.g. for `replace` or whatever." - ([x] - (fn [query stage-number] - (order-by-clause query stage-number x))) - ([query stage-number x] - (->order-by-clause query stage-number x))) - (mu/defn ^:private with-direction :- ::lib.schema.order-by/order-by "Update the direction of an order by clause." [clause :- ::lib.schema.order-by/order-by direction :- ::lib.schema.order-by/direction] (assoc (vec clause) 0 direction)) +(mu/defn order-by-clause + "Create an order-by clause independently of a query, e.g. for `replace` or whatever." + ([x] + (fn [query stage-number] + (order-by-clause query stage-number x nil))) + ([x + direction :- [:maybe [:enum :asc :desc]]] + (fn [query stage-number] + (order-by-clause query stage-number x direction))) + ([query :- ::lib.schema/query + stage-number :- [:maybe :int] + x] + (order-by-clause query stage-number x nil)) + ([query :- ::lib.schema/query + stage-number :- [:maybe :int] + x + direction :- [:maybe [:enum :asc :desc]]] + (-> (->order-by-clause query (or stage-number -1) x) + (with-direction (or direction :asc))))) + (mu/defn order-by "Add an MBQL order-by clause (i.e., `:asc` or `:desc`) from something that you can theoretically sort by -- maybe a Field, or `:field` clause, or expression of some sort, etc. diff --git a/test/metabase/lib/order_by_test.cljc b/test/metabase/lib/order_by_test.cljc index 32e72626d93e99e1871f6ca9544eeb6350116363..4623dff745978be563b21cbcbe41dda43ead60fa 100644 --- a/test/metabase/lib/order_by_test.cljc +++ b/test/metabase/lib/order_by_test.cljc @@ -72,10 +72,15 @@ (deftest ^:parallel order-by-field-metadata-test (testing "Should be able to create an order by using raw Field metadata" - (is (=? [:asc - {:lib/uuid string?} - [:field {:lib/uuid string?} (meta/id :venues :id)]] - (lib/order-by-clause {} -1 (lib.metadata/field meta/metadata-provider nil "VENUES" "ID")))))) + (let [query (lib/query-for-table-name meta/metadata-provider "VENUES")] + (is (=? [:asc + {:lib/uuid string?} + [:field {:lib/uuid string?} (meta/id :venues :id)]] + (lib/order-by-clause query -1 (lib.metadata/field meta/metadata-provider nil "VENUES" "ID")))) + (is (=? [:desc + {:lib/uuid string?} + [:field {:lib/uuid string?} (meta/id :venues :id)]] + (lib/order-by-clause query -1 (lib.metadata/field meta/metadata-provider nil "VENUES" "ID") :desc)))))) (deftest ^:parallel append-order-by-field-metadata-test (testing "Should be able to add an order by using raw Field metadata"