Skip to content

Commit

Permalink
Merge pull request #6253 from refinedev/releases/september
Browse files Browse the repository at this point in the history
release: september 2024
  • Loading branch information
BatuhanW authored Sep 3, 2024
2 parents 8780c74 + 2b89fbd commit 7beb38f
Show file tree
Hide file tree
Showing 53 changed files with 4,383 additions and 227 deletions.
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

0 comments on commit 7beb38f

Please sign in to comment.