Add GQL query for projects search in app (#38)

* Find projects based on search text

* Use get search projects client method in UI

* Fetch searched projects inside useCombobox hook

* Get searched project from project entity

* Remove non required search projects filtering

* Fetch projects if user is owner or project member

---------

Co-authored-by: neeraj <neeraj.rtly@gmail.com>
This commit is contained in:
2024-02-01 11:37:57 +05:30
committed by Ashwin Phatak
co-authored by neeraj
parent cbc394f9f8
commit c2b997a17b
13 changed files with 138 additions and 28 deletions
@@ -1,4 +1,4 @@
import React, { useState } from 'react';
import React, { useCallback, useState } from 'react';
import { useCombobox } from 'downshift';
import {
@@ -9,17 +9,19 @@ import {
Typography,
} from '@material-tailwind/react';
import { Project } from 'gql-client';
import SearchBar from '../SearchBar';
import { ProjectDetails } from '../../types/project';
import { useGQLClient } from '../../context/GQLClientContext';
interface ProjectsSearchProps {
projects: ProjectDetails[];
onChange?: (data: ProjectDetails) => void;
onChange?: (data: Project) => void;
}
const ProjectSearchBar = ({ projects, onChange }: ProjectsSearchProps) => {
const [items, setItems] = useState<ProjectDetails[]>([]);
const [selectedItem, setSelectedItem] = useState<ProjectDetails | null>(null);
const ProjectSearchBar = ({ onChange }: ProjectsSearchProps) => {
const [items, setItems] = useState<Project[]>([]);
const [selectedItem, setSelectedItem] = useState<Project | null>(null);
const client = useGQLClient();
const {
isOpen,
@@ -30,17 +32,14 @@ const ProjectSearchBar = ({ projects, onChange }: ProjectsSearchProps) => {
inputValue,
} = useCombobox({
onInputValueChange({ inputValue }) {
setItems(
inputValue
? projects.filter((project) =>
project.title.toLowerCase().includes(inputValue.toLowerCase()),
)
: [],
);
if (inputValue) {
// TODO: Use debounce
fetchProjects(inputValue);
}
},
items,
itemToString(item) {
return item ? item.title : '';
return item ? item.name : '';
},
selectedItem,
onSelectedItemChange: ({ selectedItem: newSelectedItem }) => {
@@ -54,6 +53,14 @@ const ProjectSearchBar = ({ projects, onChange }: ProjectsSearchProps) => {
},
});
const fetchProjects = useCallback(
async (inputValue: string) => {
const { searchProjects } = await client.searchProjects(inputValue);
setItems(searchProjects);
},
[client],
);
return (
<div className="relative">
<SearchBar {...getInputProps()} />
@@ -81,14 +88,14 @@ const ProjectSearchBar = ({ projects, onChange }: ProjectsSearchProps) => {
</ListItemPrefix>
<div>
<Typography variant="h6" color="blue-gray">
{item.title}
{item.name}
</Typography>
<Typography
variant="small"
color="gray"
className="font-normal"
>
{item.organization}
{item.organization.name}
</Typography>
</div>
</ListItem>
@@ -1,5 +1,5 @@
import React, { useEffect, useState } from 'react';
import { Outlet } from 'react-router-dom';
import { Outlet, useNavigate } from 'react-router-dom';
import HorizontalLine from '../components/HorizontalLine';
import { IconButton, Typography } from '@material-tailwind/react';
@@ -9,6 +9,7 @@ import { Environments, ProjectDetails } from '../types/project';
const ProjectSearch = () => {
const client = useGQLClient();
const navigate = useNavigate();
const [projects, setProjects] = useState<ProjectDetails[]>([]);
useEffect(() => {
@@ -87,7 +88,11 @@ const ProjectSearch = () => {
<div className="sticky top-0 bg-white z-30">
<div className="flex p-5">
<div className="grow mr-2">
<ProjectSearchBar onChange={() => {}} projects={projects} />
<ProjectSearchBar
onChange={(project) => {
navigate(`/projects/${project.id}`);
}}
/>
</div>
<IconButton color="blue" className="rounded-full mr-2">
<Typography variant="h5">+</Typography>