forked from cerc-io/snowballtools-base
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:
committed by
Ashwin Phatak
co-authored by
neeraj
parent
cbc394f9f8
commit
c2b997a17b
@@ -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>
|
||||
|
||||
Reference in New Issue
Block a user