Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion web/apps/admin/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
"@hookform/resolvers": "^3.0.1",
"@radix-ui/react-form": "^0.1.8",
"@radix-ui/react-icons": "^1.3.0",
"@raystack/apsara": "1.0.0-rc.9",
"@raystack/apsara": "1.0.0-rc.12",
"@raystack/frontier": "workspace:^",
"@raystack/proton": "0.1.0-859ba765e6cfd44736ddcf42664b742fe7fd916e",
"@stitches/react": "^1.2.8",
Expand Down
64 changes: 55 additions & 9 deletions web/apps/admin/src/utils/transform-query.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
RQLSortSchema
} from '@raystack/proton/frontier';
import { create } from '@bufbuild/protobuf';
import dayjs from 'dayjs';

// Extract DataTableFilter type from DataTableQuery since it's not exported
type DataTableFilter = NonNullable<DataTableQuery['filters']>[number];
Expand Down Expand Up @@ -39,10 +40,55 @@ function convertFilterValue(value: unknown): RQLFilter['value'] {
/**
* Transforms a DataTableFilter to RQLFilter
*/
/**
* Expands a date filter into RQLFilter(s) anchored to the user's local day.
* The date picker emits local midnight, and `eq` on a timestamp column can
* never match a calendar day — so expand it to a [start of day, next day)
* range. Other operators compare against the local start of day.
*/
function transformDateFilter(
filter: DataTableFilter,
fieldName: string
): RQLFilter[] {
const startOfDay = dayjs(filter.value as Date).startOf('day');

if (filter.operator === 'eq') {
return [
create(RQLFilterSchema, {
name: fieldName,
operator: 'gte',
value: { case: 'stringValue', value: startOfDay.toISOString() }
}),
create(RQLFilterSchema, {
name: fieldName,
operator: 'lt',
value: {
case: 'stringValue',
value: startOfDay.add(1, 'day').toISOString()
}
})
];
}

return [
create(RQLFilterSchema, {
name: fieldName,
operator: filter.operator,
value: { case: 'stringValue', value: startOfDay.toISOString() }
})
];
}

function transformFilter(
filter: DataTableFilter,
fieldNameMapping?: Record<string, string>
): RQLFilter {
): RQLFilter[] {
const fieldName = fieldNameMapping?.[filter.name] ?? filter.name;

if (filter.value instanceof Date) {
return transformDateFilter(filter, fieldName);
}

// Priority: typed values > generic value field
let value: RQLFilter['value'];

Expand All @@ -56,13 +102,13 @@ function transformFilter(
value = convertFilterValue(filter.value);
}

const fieldName = fieldNameMapping?.[filter.name] ?? filter.name;

return create(RQLFilterSchema, {
name: fieldName,
operator: filter.operator,
value
});
return [
create(RQLFilterSchema, {
name: fieldName,
operator: filter.operator,
value
})
];
}

/**
Expand Down Expand Up @@ -92,7 +138,7 @@ export function transformDataTableQueryToRQLRequest(

// Transform DataTable filters
const filters: RQLFilter[] = query.filters?.length
? query.filters.map(filter => transformFilter(filter, fieldNameMapping))
? query.filters.flatMap(filter => transformFilter(filter, fieldNameMapping))
: [];

// Build the RQLRequest with snake_case properties
Expand Down
2 changes: 1 addition & 1 deletion web/apps/client-demo/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
},
"dependencies": {
"@radix-ui/react-icons": "^1.3.0",
"@raystack/apsara": "1.0.0-rc.9",
"@raystack/apsara": "1.0.0-rc.12",
"@raystack/frontier": "workspace:^",
"react": "^19.2.1",
"react-dom": "^19.2.1",
Expand Down
18 changes: 9 additions & 9 deletions web/pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion web/sdk/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@
"@connectrpc/connect-query": "2.1.1",
"@connectrpc/connect-web": "2.1.1",
"@hookform/resolvers": "^3.10.0",
"@raystack/apsara-v1": "npm:@raystack/apsara@1.0.0-rc.9",
"@raystack/apsara-v1": "npm:@raystack/apsara@1.0.0-rc.12",
"@raystack/proton": "0.1.0-859ba765e6cfd44736ddcf42664b742fe7fd916e",
"@tanstack/react-query": "^5.90.2",
"@tanstack/react-router": "^1.168.3",
Expand Down
64 changes: 55 additions & 9 deletions web/sdk/react/utils/transform-query.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
RQLSortSchema
} from '@raystack/proton/frontier';
import { create } from '@bufbuild/protobuf';
import dayjs from 'dayjs';

// Extract DataTableFilter type from DataTableQuery since it's not exported
type DataTableFilter = NonNullable<DataTableQuery['filters']>[number];
Expand Down Expand Up @@ -42,10 +43,55 @@ function convertFilterValue(value: unknown): RQLFilter['value'] {
/**
* Transforms a DataTableFilter to RQLFilter
*/
/**
* Expands a date filter into RQLFilter(s) anchored to the user's local day.
* The date picker emits local midnight, and `eq` on a timestamp column can
* never match a calendar day — so expand it to a [start of day, next day)
* range. Other operators compare against the local start of day.
*/
function transformDateFilter(
filter: DataTableFilter,
fieldName: string
): RQLFilter[] {
const startOfDay = dayjs(filter.value as Date).startOf('day');

if (filter.operator === 'eq') {
return [
create(RQLFilterSchema, {
name: fieldName,
operator: 'gte',
value: { case: 'stringValue', value: startOfDay.toISOString() }
}),
create(RQLFilterSchema, {
name: fieldName,
operator: 'lt',
value: {
case: 'stringValue',
value: startOfDay.add(1, 'day').toISOString()
}
})
];
}

return [
create(RQLFilterSchema, {
name: fieldName,
operator: filter.operator,
value: { case: 'stringValue', value: startOfDay.toISOString() }
})
];
}

function transformFilter(
filter: DataTableFilter,
fieldNameMapping?: Record<string, string>
): RQLFilter {
): RQLFilter[] {
const fieldName = fieldNameMapping?.[filter.name] ?? filter.name;

if (filter.value instanceof Date) {
return transformDateFilter(filter, fieldName);
}

// Priority: typed values > generic value field
let value: RQLFilter['value'];

Expand All @@ -59,13 +105,13 @@ function transformFilter(
value = convertFilterValue(filter.value);
}

const fieldName = fieldNameMapping?.[filter.name] ?? filter.name;

return create(RQLFilterSchema, {
name: fieldName,
operator: filter.operator,
value
});
return [
create(RQLFilterSchema, {
name: fieldName,
operator: filter.operator,
value
})
];
}

/**
Expand Down Expand Up @@ -99,7 +145,7 @@ export function transformDataTableQueryToRQLRequest(

// Transform DataTable filters
const filters: RQLFilter[] = query.filters?.length
? query.filters.map(filter => transformFilter(filter, fieldNameMapping))
? query.filters.flatMap(filter => transformFilter(filter, fieldNameMapping))
: [];

// Build the RQLRequest with snake_case properties
Expand Down
6 changes: 5 additions & 1 deletion web/sdk/react/views-new/general/general-view.module.css
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
.section {
padding: var(--rs-space-9) 0;
border-bottom: 1px solid var(--rs-color-border-base-primary);
border-bottom: 0.5px solid var(--rs-color-border-base-primary);
}

.section:last-child {
border-bottom: none;
}

.formFields {
Expand Down
4 changes: 4 additions & 0 deletions web/sdk/react/views-new/pat/pat-details-view.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,7 @@
.callout {
width: 100%;
}

.expiredTooltip {
max-width: 220px;
}
Loading
Loading