diff --git a/packages/backend/src/graphql/queries/get-flows.ts b/packages/backend/src/graphql/queries/get-flows.ts
index b6fb95a1..1b72af81 100644
--- a/packages/backend/src/graphql/queries/get-flows.ts
+++ b/packages/backend/src/graphql/queries/get-flows.ts
@@ -15,7 +15,7 @@ const getFlows = async (_parent: unknown, params: Params, context: Context) => {
.withGraphFetched('steps.[connection]')
.where((builder) => {
if (params.name) {
- builder.where('flows.name', 'like', `%${params.name}%`);
+ builder.where('flows.name', 'ilike', `%${params.name}%`);
}
if (params.appKey) {
diff --git a/packages/web/src/graphql/queries/get-flows.ts b/packages/web/src/graphql/queries/get-flows.ts
index 56e18dc2..71cd5d86 100644
--- a/packages/web/src/graphql/queries/get-flows.ts
+++ b/packages/web/src/graphql/queries/get-flows.ts
@@ -1,8 +1,8 @@
import { gql } from '@apollo/client';
export const GET_FLOWS = gql`
- query GetFlows($limit: Int!, $offset: Int!, $appKey: String) {
- getFlows(limit: $limit, offset: $offset, appKey: $appKey) {
+ query GetFlows($limit: Int!, $offset: Int!, $appKey: String, $name: String) {
+ getFlows(limit: $limit, offset: $offset, appKey: $appKey, name: $name) {
pageInfo {
currentPage
totalPages
diff --git a/packages/web/src/pages/Flows/index.tsx b/packages/web/src/pages/Flows/index.tsx
index 5b9faddd..c1ed6660 100644
--- a/packages/web/src/pages/Flows/index.tsx
+++ b/packages/web/src/pages/Flows/index.tsx
@@ -1,10 +1,12 @@
import * as React from 'react';
import { Link, useSearchParams } from 'react-router-dom';
import type { LinkProps } from 'react-router-dom';
-import { useQuery } from '@apollo/client';
+import { useLazyQuery } from '@apollo/client';
+import debounce from 'lodash/debounce';
import Box from '@mui/material/Box';
import Grid from '@mui/material/Grid';
import AddIcon from '@mui/icons-material/Add';
+import CircularProgress from '@mui/material/CircularProgress';
import Pagination from '@mui/material/Pagination';
import PaginationItem from '@mui/material/PaginationItem';
import type { IFlow } from '@automatisch/types';
@@ -30,17 +32,44 @@ export default function Flows(): React.ReactElement {
const [searchParams, setSearchParams] = useSearchParams();
const page = parseInt(searchParams.get('page') || '', 10) || 1;
const [flowName, setFlowName] = React.useState('');
- const { data } = useQuery(GET_FLOWS, {
- variables: getLimitAndOffset(page),
- fetchPolicy: 'cache-and-network',
+ const [loading, setLoading] = React.useState(false);
+ const [getFlows, { data }] = useLazyQuery(GET_FLOWS, {
+ onCompleted: () => { setLoading(false); },
});
- const getFlows = data?.getFlows || {};
- const { pageInfo, edges } = getFlows;
+ const fetchData = React.useMemo(
+ () => debounce((name) => getFlows(
+ {
+ variables: {
+ ...getLimitAndOffset(page),
+ name
+ }
+ }),
+ 300
+ ),
+ [page, getFlows]
+ );
- const flows: IFlow[] = edges
- ?.map(({ node }: { node: IFlow }) => node)
- .filter((flow: IFlow) => flow.name?.toLowerCase().includes(flowName.toLowerCase()));
+ React.useEffect(function fetchFlowsOnSearch() {
+ setLoading(true);
+
+ fetchData(flowName);
+ }, [fetchData, flowName]);
+
+ React.useEffect(function resetPageOnSearch() {
+ // reset search params which only consists of `page`
+ setSearchParams({})
+ }, [flowName]);
+
+ React.useEffect(function cancelDebounceOnUnmount() {
+ return () => {
+ fetchData.cancel();
+ }
+ }, []);
+
+ const { pageInfo, edges } = data?.getFlows || {};
+
+ const flows: IFlow[] = edges?.map(({ node }: { node: IFlow }) => node);
const onSearchChange = React.useCallback((event) => {
setFlowName(event.target.value);
@@ -84,9 +113,11 @@ export default function Flows(): React.ReactElement {
- {flows?.map((flow) => ())}
+ {loading && }
- {pageInfo && pageInfo.totalPages > 1 && ())}
+
+ {!loading && pageInfo && pageInfo.totalPages > 1 &&