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

release: september 2024 #6253

Merged
merged 12 commits into from
Sep 3, 2024
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
9 changes: 9 additions & 0 deletions .changeset/few-turkeys-dance.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
"@refinedev/supabase": patch
---

fix(supabase): issue with parsed values when using conditional filters

Fixed conditional filter's parsed values while using `contains`, `containss`, `startswith` and `endswith`.

[Fixes #6239](https://github.com/refinedev/refine/issues/6239)
9 changes: 9 additions & 0 deletions .changeset/friendly-panthers-beam.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
"@refinedev/antd": patch
---

fix(antd): rtl support for mobile sider trigger and drawer placement

`<ThemedLayoutV2 />` has RTL support but it lacks the mobile sider trigger and drawer placement. This change places the drawer depending on the preferred direction. It also adds RTL support for the styling of the mobile sider trigger.

[Fixes #6263](https://github.com/refinedev/refine/issues/6263)
8 changes: 8 additions & 0 deletions .changeset/grumpy-lions-exercise.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
"@refinedev/devtools-server": patch
---

chore(devtools-server): replace `preferred-pm` with `package-manager-detector` #6242

`preferred-pm` has 24 dependencies: https://npmgraph.js.org/?q=preferred-pm
`package-manager-detector` has no dependencies: https://npmgraph.js.org/?q=package-manager-detector
9 changes: 9 additions & 0 deletions .changeset/honest-peaches-deny.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
"@refinedev/core": patch
---

fix(core): `useResourceParams` not reflecting `id` prop changes immediately

`useResourceParams` hook was not reflecting the changes in the `id` prop immediately. This was due to the `id` state being set in the `useEffect` hook. This PR fixes the issue by setting the `id` state properly during render rather than after the render is complete.

[Fixes #6259](https://github.com/refinedev/refine/issues/6259)
9 changes: 9 additions & 0 deletions .changeset/nasty-glasses-care.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
"@refinedev/mui": minor
---

feat(mui): added loading spinner to `<Create />`, `<Edit />` and `<Show />` components

This change introduces a loading spinner to the `<Create />`, `<Edit />` and `<Show />` components in the `@refinedev/mui` package. The spinner provides a visual indication that data is being loaded, improving the user experience bym giving clear feedback during loading states.

[Resolves #5668](https://github.com/refinedev/refine/issues/5668)
8 changes: 8 additions & 0 deletions .changeset/six-shrimps-hide.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
---
"@refinedev/hasura": patch
"@refinedev/core": patch
---

feat: added support for meta.gqlVariables to hasura dataProvider. Updated GraphQLQueryOptions to include optional field gqlVariables

[Feat #5864](https://github.com/refinedev/refine/issues/5864)
11 changes: 11 additions & 0 deletions .changeset/wicked-cherries-grow.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
---
"@refinedev/cli": patch
---

feat: added scripts for Remix SPA Mode

It is now possible to execute the Remix SPA Mode script by selecting it from the platform options.

Two new project types are added `remix-vite` and `remix-spa`. `remix-vite` is Remix + Vite and `remix-spa` is Remix + Vite SPA Mode. While `remix-vite` type can be inferred from the project configuration without needing to specify it in the command, `remix-spa` type needs to be specified explicitly.

[Resolves #6127](https://github.com/refinedev/refine/issues/6127)
9 changes: 9 additions & 0 deletions .changeset/wicked-rats-breathe.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
---
"@refinedev/appwrite": patch
---

feat(appwrite): add support to conditional filters and missing logical filters

Add Support to `and`, `or`, `between`, `null`, `nnull`, `startswith` and `endswith` operators

[Resolves #6252](https://github.com/refinedev/refine/issues/6252)
Original file line number Diff line number Diff line change
Expand Up @@ -275,3 +275,92 @@ Data providers that support `or` and `and` filtering logic are as follows:
- [Hasura](https://github.com/refinedev/refine/tree/master/packages/hasura)

:::

## Handle Custom GraphQL Variables

The [GraphQLQueryOptions](https://refine.dev/docs/core/interface-references/#graphqlqueryoptions) property `gqlVariables` enables dynamic GraphQL variables to be passed to the data provider for more advanced GraphQL queries.

Packages that support custom GraphQL variables for more advanced filtering are as follows:

- [Hasura](https://github.com/refinedev/refine/tree/master/packages/hasura)

The following data providers do not yet support `meta.gqlVariables`;

- [Nestjs-Query](https://github.com/refinedev/refine/tree/master/packages/nestjs-query)
- [GraphQL](https://github.com/refinedev/refine/tree/master/packages/graphql)

```tsx
// Hasura Data Provider Example
import gql from "graphql-tag";
import { useTable } from "@refinedev/antd";
import type { GetFieldsFromList } from "@refinedev/hasura";
import type { GetPostsQuery } from "graphql/types";

const POSTS_QUERY = gql`
query GetPosts(
$offset: Int!
$limit: Int!
$order_by: [posts_order_by!]
$where: posts_bool_exp
) {
posts(
offset: $offset
limit: $limit
order_by: $order_by
where: $where
) {
id
title
content
category_id
created_at
category {
id
title
}
}
posts_aggregate(where: $where) {
aggregate {
count
}
}
}
`;

export const PostList = () => {
const { tableProps } = useTable<
GetFieldsFromList<GetPostsQuery>
>({
meta: {
gqlQuery: POSTS_QUERY,
gqlVariables: {
where: {
_and: [
{
_not: {
category: { title: { _eq: "ok" } },
},
},
{
title: {
_ilike: "%Updated%",
},
},
{
title: {
_ilike: "%3%",
},
},
{
created_at: {
_gte: "2023-08-04T08:26:26.489116+00:00",
},
},
],
},
},
});
return ( <Table {...tableProps}/> );
}

```
3 changes: 3 additions & 0 deletions documentation/docs/core/interface-references/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,9 @@ import type { DocumentNode } from "graphql";
type GraphQLQueryOptions = {
gqlQuery?: DocumentNode;
gqlMutation?: DocumentNode;
gqlVariables?: {
[key: string]: any;
};
};
```

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -232,7 +232,7 @@ export const ThemedSiderV2: React.FC<RefineThemedLayoutV2SiderProps> = ({
<Drawer
open={mobileSiderOpen}
onClose={() => setMobileSiderOpen(false)}
placement="left"
placement={direction === "rtl" ? "right" : "left"}
closable={false}
width={200}
bodyStyle={{
Expand Down
4 changes: 2 additions & 2 deletions packages/antd/src/components/themedLayoutV2/sider/styles.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import type { CSSProperties } from "react";

export const drawerButtonStyles: CSSProperties = {
borderTopLeftRadius: 0,
borderBottomLeftRadius: 0,
borderStartStartRadius: 0,
borderEndStartRadius: 0,
position: "fixed",
top: 64,
zIndex: 999,
Expand Down
48 changes: 47 additions & 1 deletion packages/appwrite/src/utils/generateFilter.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,24 @@
import type { CrudFilter } from "@refinedev/core";
import { Query } from "appwrite";
import { replaceIdWithAppwriteId } from "./replaceIdWithAppwriteId";

/**
* Generate a filter string for Appwrite from Refine's filter
* @param filter Refine's filter
* @param deep Max deep of the filter
* @returns Appwrite's filter string
*/
export const generateFilter = (filter: CrudFilter, deep = 10): string => {
const nextDeep = deep - 1;

if (nextDeep < 0) {
throw new Error("Max deep reached");
}

filter = replaceIdWithAppwriteId(filter);

export const generateFilter = (filter: CrudFilter) => {
switch (filter.operator) {
// Logical operators
case "eq":
return Query.equal(filter.field, filter.value);
case "ne":
Expand All @@ -17,6 +33,36 @@ export const generateFilter = (filter: CrudFilter) => {
return Query.lessThanEqual(filter.field, filter.value);
case "contains":
return Query.search(filter.field, `%${filter.value}%`);
case "between":
if (!Array.isArray(filter.value) || filter.value.length !== 2) {
throw new Error(
`Value array must contain exactly two elements for "between" operator`,
);
}
return Query.between(filter.field, filter.value[0], filter.value[1]);
case "null":
return Query.isNull(filter.field);
case "nnull":
return Query.isNotNull(filter.field);
case "startswith":
return Query.startsWith(filter.field, filter.value);
case "endswith":
return Query.endsWith(filter.field, filter.value);

// Conditional operators
case "or":
if (filter.value.length === 1 && filter.value[0]) {
//? "OR" queries require at least two queries in Appwrite
return generateFilter(filter.value[0], nextDeep);
}
return Query.or(filter.value.map((f) => generateFilter(f, nextDeep)));
case "and":
if (filter.value.length === 1 && filter.value[0]) {
//? "AND" queries require at least two queries in Appwrite
return generateFilter(filter.value[0], nextDeep);
}
return Query.and(filter.value.map((f) => generateFilter(f, nextDeep)));

default:
throw new Error(`Operator ${filter.operator} is not supported`);
}
Expand Down
15 changes: 1 addition & 14 deletions packages/appwrite/src/utils/getAppwriteFilters.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,20 +7,7 @@ export const getAppwriteFilters: GetAppwriteFiltersType = (filters) => {
const appwriteFilters: string[] = [];

for (const filter of filters ?? []) {
if (
filter.operator !== "or" &&
filter.operator !== "and" &&
"field" in filter
) {
const filterField = filter.field === "id" ? "$id" : filter.field;

appwriteFilters.push(
generateFilter({
...filter,
field: filterField,
}),
);
}
appwriteFilters.push(generateFilter(filter));
}

return appwriteFilters;
Expand Down
17 changes: 17 additions & 0 deletions packages/appwrite/src/utils/replaceIdWithAppwriteId.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import type { CrudFilter } from "@refinedev/core";

/**
* Replace ID("id") With Appwrite ID("$id")
* @param filter Filter to replace
* @returns Filter with replaced ID
*/
export const replaceIdWithAppwriteId = (filter: CrudFilter): CrudFilter => {
if ("field" in filter && filter.field === "id") {
filter.field = "$id";
}

return {
...filter,
value: filter.value,
};
};
Loading
Loading