Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add sortBy saleAmount #1869

Merged
merged 10 commits into from
Jan 8, 2025
2 changes: 1 addition & 1 deletion apps/web/app/api/customers/[id]/activity/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ export const GET = withWorkspace(async ({ workspace, params }) => {
getEvents({
customerId: customer.id,
event: "sales",
order: "desc",
sortOrder: "desc",
sortBy: "timestamp",
interval: "1y",
page: 1,
Expand Down
2 changes: 2 additions & 0 deletions apps/web/app/api/links/export/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,8 @@ export const GET = withWorkspace(
}),
...(userId && { userId }),
},

// TODO: orderBy is not currently supported
orderBy: {
[sort]: "desc",
},
Expand Down
39 changes: 4 additions & 35 deletions apps/web/app/api/links/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,46 +19,15 @@ import { NextResponse } from "next/server";
export const GET = withWorkspace(
async ({ req, headers, workspace }) => {
const searchParams = getSearchParamsWithArray(req.url);
const params = getLinksQuerySchemaExtended.parse(searchParams);

const {
domain,
tagId,
tagIds,
search,
sort,
page,
pageSize,
userId,
showArchived,
withTags,
includeUser,
includeWebhooks,
includeDashboard,
linkIds,
tenantId,
} = getLinksQuerySchemaExtended.parse(searchParams);

if (domain) {
await getDomainOrThrow({ workspace, domain });
if (params.domain) {
await getDomainOrThrow({ workspace, domain: params.domain });
}

const response = await getLinksForWorkspace({
...params,
workspaceId: workspace.id,
domain,
tagId,
tagIds,
search,
sort,
page,
pageSize,
userId,
showArchived,
withTags,
includeUser,
includeWebhooks,
includeDashboard,
linkIds,
tenantId,
});

return NextResponse.json(response, {
Expand Down
2 changes: 1 addition & 1 deletion apps/web/lib/actions/partners/backfill-link-data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ export const backfillLinkData = async ({
interval: "all",
page: 1,
limit: 5000,
order: "desc",
sortOrder: "desc",
sortBy: "timestamp",
});

Expand Down
8 changes: 8 additions & 0 deletions apps/web/lib/analytics/get-events.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ export const getEvents = async (params: EventsFilters) => {
region,
country,
isDemo,
order,
sortOrder,
} = params;

const { startDate, endDate } = getStartEndDates({
Expand All @@ -57,6 +59,11 @@ export const getEvents = async (params: EventsFilters) => {
region = split[1];
}

// support legacy order param
if (order && order !== "desc") {
sortOrder = order;
}

const pipe = (isDemo ? tbDemo : tb).buildPipe({
pipe: "v2_events",
parameters: eventsFilterTB,
Expand All @@ -75,6 +82,7 @@ export const getEvents = async (params: EventsFilters) => {
qr,
country,
region,
order: sortOrder,
offset: (params.page - 1) * params.limit,
start: startDate.toISOString().replace("T", " ").replace("Z", ""),
end: endDate.toISOString().replace("T", " ").replace("Z", ""),
Expand Down
1 change: 1 addition & 0 deletions apps/web/lib/analytics/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ const partnerEventsSchema = eventsQuerySchema
page: true,
limit: true,
order: true,
sortOrder: true,
sortBy: true,
})
.partial();
Expand Down
11 changes: 9 additions & 2 deletions apps/web/lib/api/links/get-links-for-workspace.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@ export async function getLinksForWorkspace({
tagIds,
tagNames,
search,
sort = "createdAt",
sort, // Deprecated
sortBy,
sortOrder,
page,
pageSize,
userId,
Expand All @@ -27,6 +29,11 @@ export async function getLinksForWorkspace({
}) {
const combinedTagIds = combineTagIds({ tagId, tagIds });

// support legacy sort param
if (sort && sort !== "createdAt") {
sortBy = sort;
}

const links = await prisma.link.findMany({
where: {
projectId: workspaceId,
Expand Down Expand Up @@ -85,7 +92,7 @@ export async function getLinksForWorkspace({
dashboard: includeDashboard,
},
orderBy: {
[sort]: "desc",
[sortBy]: sortOrder,
},
take: pageSize,
skip: (page - 1) * pageSize,
Expand Down
4 changes: 2 additions & 2 deletions apps/web/lib/openapi/links/get-links.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { openApiErrorResponses } from "@/lib/openapi/responses";
import z from "@/lib/zod";
import { getLinksQuerySchema, LinkSchema } from "@/lib/zod/schemas/links";
import { getLinksQuerySchemaBase, LinkSchema } from "@/lib/zod/schemas/links";
import { ZodOpenApiOperationObject } from "zod-openapi";

export const getLinks: ZodOpenApiOperationObject = {
Expand Down Expand Up @@ -28,7 +28,7 @@ export const getLinks: ZodOpenApiOperationObject = {
description:
"Retrieve a paginated list of links for the authenticated workspace.",
requestParams: {
query: getLinksQuerySchema,
query: getLinksQuerySchemaBase,
},
responses: {
"200": {
Expand Down
17 changes: 15 additions & 2 deletions apps/web/lib/zod/schemas/analytics.ts
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,12 @@ export const eventsFilterTB = analyticsFilterTB
}),
);

const sortOrder = z
.enum(["asc", "desc"])
.default("desc")
.optional()
.describe("The sort order. The default is `desc`.");

export const eventsQuerySchema = analyticsQuerySchema
.omit({ groupBy: true })
.extend({
Expand All @@ -259,6 +265,13 @@ export const eventsQuerySchema = analyticsQuerySchema
),
page: z.coerce.number().default(1),
limit: z.coerce.number().default(PAGINATION_LIMIT),
order: z.enum(["asc", "desc"]).default("desc"),
sortBy: z.enum(["timestamp"]).default("timestamp"),
sortOrder,
sortBy: z
.enum(["timestamp"])
.optional()
.default("timestamp")
.describe("The field to sort the events by. The default is `timestamp`."),
order: sortOrder
.describe("DEPRECATED. Use `sortOrder` instead.")
.openapi({ deprecated: true }),
});
26 changes: 17 additions & 9 deletions apps/web/lib/zod/schemas/links.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,15 +78,23 @@ const LinksQuerySchema = z.object({
.openapi({ deprecated: true }),
});

export const getLinksQuerySchema = LinksQuerySchema.merge(
const sortBy = z
.enum(["createdAt", "clicks", "saleAmount", "lastClicked"])
.optional()
.default("createdAt")
.describe("The field to sort the links by. The default is `createdAt`.");

export const getLinksQuerySchemaBase = LinksQuerySchema.merge(
z.object({
sort: z
.enum(["createdAt", "clicks", "lastClicked"])
sortBy,
sortOrder: z
.enum(["asc", "desc"])
.optional()
.default("createdAt")
.describe(
"The field to sort the links by. The default is `createdAt`, and sort order is always descending.",
),
.default("desc")
.describe("The sort order. The default is `desc`."),
sort: sortBy
.openapi({ deprecated: true })
.describe("DEPRECATED. Use `sortBy` instead."),
}),
).merge(getPaginationQuerySchema({ pageSize: 100 }));

Expand All @@ -99,7 +107,7 @@ export const getLinksCountQuerySchema = LinksQuerySchema.merge(
}),
);

export const linksExportQuerySchema = getLinksQuerySchema
export const linksExportQuerySchema = getLinksQuerySchemaBase
.omit({ page: true, pageSize: true })
.merge(
z.object({
Expand Down Expand Up @@ -603,7 +611,7 @@ export const getLinkInfoQuerySchema = domainKeySchema.partial().merge(
}),
);

export const getLinksQuerySchemaExtended = getLinksQuerySchema.merge(
export const getLinksQuerySchemaExtended = getLinksQuerySchemaBase.merge(
z.object({
// Only Dub UI uses the following query parameters
includeUser: booleanQuerySchema.default("false"),
Expand Down
2 changes: 1 addition & 1 deletion apps/web/scripts/backfill-missing-sales.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ async function main() {
interval: "all",
page: 1,
limit: 1000,
order: "desc",
sortOrder: "desc",
sortBy: "timestamp",
})) as unknown as SaleEvent[];

Expand Down
2 changes: 1 addition & 1 deletion apps/web/scripts/backfill-sales.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ async function main() {
interval: "all",
page: 1,
limit: 5000,
order: "desc",
sortOrder: "desc",
sortBy: "timestamp",
});

Expand Down
16 changes: 8 additions & 8 deletions apps/web/ui/analytics/events/events-table.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -65,8 +65,8 @@ export default function EventsTable({

const { columnVisibility, setColumnVisibility } = useColumnVisibility();

const sortBy = searchParams.get("sort") || "timestamp";
const order = searchParams.get("order") === "asc" ? "asc" : "desc";
const sortBy = searchParams.get("sortBy") || "timestamp";
const sortOrder = searchParams.get("sortOrder") === "asc" ? "asc" : "desc";

const columns = useMemo<ColumnDef<EventDatum, any>[]>(
() =>
Expand Down Expand Up @@ -440,9 +440,9 @@ export default function EventsTable({
event: tab,
page: pagination.pageIndex.toString(),
sortBy,
order,
sortOrder,
}).toString(),
[originalQueryString, tab, pagination, sortBy, order],
[originalQueryString, tab, pagination, sortBy, sortOrder],
);

// Update export query string
Expand Down Expand Up @@ -482,13 +482,13 @@ export default function EventsTable({
columnVisibility: columnVisibility[tab],
onColumnVisibilityChange: (args) => setColumnVisibility(tab, args),
sortableColumns: ["timestamp"],
sortBy: sortBy,
sortOrder: order,
sortBy,
sortOrder,
onSortChange: ({ sortBy, sortOrder }) =>
queryParams({
set: {
...(sortBy && { sort: sortBy }),
...(sortOrder && { order: sortOrder }),
...(sortBy && { sortBy }),
...(sortOrder && { sortOrder }),
},
}),
columnPinning: { right: ["menu"] },
Expand Down
4 changes: 3 additions & 1 deletion apps/web/ui/layout/sidebar/app-sidebar-nav.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -264,7 +264,9 @@ export function AppSidebarNav({
currentArea={currentArea}
data={{
slug: slug || "",
queryString: getQueryString(),
queryString: getQueryString(undefined, {
ignore: ["sortBy", "sortOrder"],
}),
flags,
programs,
session: session || undefined,
Expand Down
6 changes: 3 additions & 3 deletions apps/web/ui/links/link-sort.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ export default function LinkSort() {

const [openPopover, setOpenPopover] = useState(false);

const { sort: sortSlug, setSort } = useContext(LinksDisplayContext);
const { sortBy, setSort } = useContext(LinksDisplayContext);
const selectedSort =
sortOptions.find((s) => s.slug === sortSlug) ?? sortOptions[0];
sortOptions.find((s) => s.slug === sortBy) ?? sortOptions[0];

return (
<Popover
Expand All @@ -36,7 +36,7 @@ export default function LinkSort() {
text={display}
icon={<SortDesc className="h-4 w-4" />}
/>
{sortSlug === slug && (
{sortBy === slug && (
<Tick className="h-4 w-4" aria-hidden="true" />
)}
</button>
Expand Down
4 changes: 2 additions & 2 deletions apps/web/ui/links/links-container.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,9 @@ export default function LinksContainer({
}: {
CreateLinkButton: () => JSX.Element;
}) {
const { viewMode, sort, showArchived } = useContext(LinksDisplayContext);
const { viewMode, sortBy, showArchived } = useContext(LinksDisplayContext);

const { links, isValidating } = useLinks({ sort, showArchived });
const { links, isValidating } = useLinks({ sortBy, showArchived });
const { data: count } = useLinksCount<number>({ showArchived });

return (
Expand Down
Loading
Loading