Loading capif_frontend/src/configs/apiService.js +34 −0 Original line number Diff line number Diff line Loading @@ -158,3 +158,37 @@ export const deleteUser = async (username, password) => { export const getEvents = async id => { return axiosInstance.get(`/resources/events/${id}`) } // BUSCADOR export const searchInvokers = async (searchTerm, page, pageSize) => { try { const response = await axiosInstance.get(`/invokers/search`, { params: { page: page, pageSize: pageSize, searchTerm: searchTerm } }); return response.data; } catch (error) { throw new Error(`Error searching invokers: ${error.message}`); } }; export const searchProviders = async (searchTerm, page, pageSize) => { try { const response = await axiosInstance.get(`/providers/search`, { params: { page: page, pageSize: pageSize, searchTerm: searchTerm } }); return response.data; } catch (error) { throw new Error(`Error searching providers: ${error.message}`); } }; capif_frontend/src/pages/invokers/index.js +104 −23 Original line number Diff line number Diff line import React from 'react'; import { useState } from 'react'; import { useQuery, useQueryClient, QueryClient, QueryClientInvoker, useMutation } from '@tanstack/react-query' import { getInvokers, getInvokersPages, deleteInvoker, getNumInvokers } from 'src/configs/apiService'; import { getInvokers, getInvokersPages, deleteInvoker, getNumInvokers, searchInvokers } from 'src/configs/apiService'; import Link from 'next/link'; import Grid from '@mui/material/Grid'; import Card from '@mui/material/Card'; Loading Loading @@ -52,6 +52,12 @@ const Invokers = () => { const [showDeleteMessage, setShowDeleteMessage] = useState(false); const [errorDeleting, setErrorDeleting] = useState(false); // Estados para la búsqueda const [searchResults, setSearchResults] = useState([]); const [totalSearchResults, setTotalSearchResults] = useState(0); const [errorSearching, setErrorSearching] = useState(0); // INVOKERS DATA const queryKeyInvokers = ['invokers']; Loading Loading @@ -153,29 +159,56 @@ const Invokers = () => { setCurrentPage(1); }; const handleSearch = async () => { try { setErrorSearching(false); // Realizar la búsqueda en el backend const searchData = await searchInvokers(searchTerm, currentPage, pageSize); // Actualizar el estado con los resultados de la búsqueda y la información de paginación setSearchResults(searchData.data); setTotalPages(1) setCurrentPage(1) } catch (error) { console.error('Error searching invokers:', error.message); setErrorSearching(true); } }; return ( <Grid container spacing={3}> <Grid item xs={12}> {/* Agregar controles de búsqueda aquí si es necesario */} </Grid> <Grid item xs={8}> <Grid container spacing={3}> <Grid item xs={4}> <Button onClick={() => window.location.reload()} style={{ textTransform: 'none' }}> <PageHeader title={<Typography variant='h5'>Invokers: {totalInvokers}</Typography>} /> </Button> </Grid> {/* Grid con el campo de búsqueda en la segunda columna */} <Grid item xs={4}> <Grid container spacing={2}> {/* Agregar un campo de búsqueda */} <Grid item xs={12}> <Grid item xs={8}> <Grid container spacing={2} alignItems="center" justifyContent="flex-end"> <Grid item> <TextField label="Search by ..." variant="outlined" //value={searchTerm} value={searchTerm} onChange={(e) => setSearchTerm(e.target.value)} /> </Grid> {/* Otros elementos adicionales en la segunda columna, si es necesario */} <Grid item> <Button variant="contained" color="primary" onClick={() => handleSearch(searchTerm)}> Search </Button> </Grid> </Grid> </Grid> </Grid> </Grid> Loading @@ -183,7 +216,56 @@ const Invokers = () => { <Grid item xs={12}> <Card> <CardHeader title='List of Invokers' /> {isLoadingInvokersData ? ( {searchResults.length > 0 ? ( <TableContainer component={Paper}> <Table sx={{ minWidth: 650 }} aria-label='Invokers table'> <TableHead> <TableRow> <TableCell>ID</TableCell> <TableCell>Info</TableCell> <TableCell>User name</TableCell> <TableCell>Actions</TableCell> </TableRow> </TableHead> <TableBody> {searchResults.map((invoker) => ( <TableRow key={invoker.api_invoker_id} sx={{ '&:last-of-type td, &:last-of-type th': { border: 0, }, }} > <TableCell component='th' scope='row'> <LinkStyled href={`/invokers/${invoker.api_invoker_id}`}> {invoker.api_invoker_id} </LinkStyled> </TableCell> <TableCell>{invoker.api_invoker_information}</TableCell> <TableCell> {invoker.username ? ( <LinkStyled href={`/users/${invoker.username}`}> {invoker.username} </LinkStyled> ) : ( 'Unknown user' )} </TableCell> <TableCell> <Button variant='contained' onClick={() => handleDeleteClick(invoker.api_invoker_id)} > Delete </Button> </TableCell> </TableRow> ))} </TableBody> </Table> </TableContainer> ) : isLoadingInvokersData ? ( <CircularProgress /> ) : isErrorInvokersData ? ( <Typography variant='body1' sx={{ paddingLeft: 4, paddingBottom: 2 }}> Loading Loading @@ -270,7 +352,6 @@ const Invokers = () => { </Grid> </Grid> <Dialog open={isDeleteDialogOpen} onClose={handleDeleteCancel}> <DialogTitle>Confirm Deletion</DialogTitle> <DialogContent> Loading capif_frontend/src/pages/providers/index.js +108 −27 Original line number Diff line number Diff line Loading @@ -17,7 +17,7 @@ import TableCell from '@mui/material/TableCell'; import TableContainer from '@mui/material/TableContainer'; import CircularProgress from '@mui/material/CircularProgress'; import Button from '@mui/material/Button'; import { deleteProvider, getNumProviders, getProvidersPages } from 'src/configs/apiService'; import { deleteProvider, getNumProviders, getProvidersPages, searchProviders } from 'src/configs/apiService'; import { Dialog, DialogTitle, DialogContent, DialogActions } from '@mui/material' import TextField from '@mui/material/TextField'; import Pagination from '@mui/material/Pagination'; Loading @@ -32,6 +32,7 @@ const LinkStyled = styled(Link)(({ theme }) => ({ })); const Providers = () => { const queryClient = useQueryClient() const [selectedProvider, setSelectedProvider] = useState(null); Loading @@ -48,8 +49,13 @@ const Providers = () => { const [showDeleteMessage, setShowDeleteMessage] = useState(false); const [errorDeleting, setErrorDeleting] = useState(false); // Estados para la búsqueda const [searchResults, setSearchResults] = useState([]); const [totalSearchResults, setTotalSearchResults] = useState(0); const [errorSearching, setErrorSearching] = useState(0); // PROVIDERS DATA // ProviderS DATA const queryKeyProviders = ['providers']; const { data: providersDataPages, isLoadingProvidersData, isErrorProvidersData, refetchProviders } = useQuery({ Loading @@ -59,7 +65,7 @@ const Providers = () => { refetchOnMount: false, }); console.log('providersDataPages:', providersDataPages); //console.log('providersDataPages:', providersDataPages); useEffect(() => { // Solo establece los invocadores cuando providersData cambie Loading Loading @@ -98,7 +104,7 @@ const Providers = () => { await deleteProvider(selectedProvider); // Simula el mensaje de éxito, reemplaza esta línea con tu lógica real // Carga el mensaje de éxito setDeleteMessage('Provider removed'); // Refresca los datos después de la eliminación manteniendo la página actual Loading Loading @@ -150,36 +156,110 @@ const Providers = () => { setCurrentPage(1); }; const handleSearch = async () => { try { setErrorSearching(false); // Realizar la búsqueda en el backend const searchData = await searchProviders(searchTerm, currentPage, pageSize); // Actualizar el estado con los resultados de la búsqueda y la información de paginación setSearchResults(searchData.data); setTotalPages(1) setCurrentPage(1) } catch (error) { console.error('Error searching providers:', error.message); setErrorSearching(true); } }; return ( <Grid container spacing={3}> <Grid item xs={12}> {/* Agregar controles de búsqueda aquí si es necesario */} </Grid> <Grid item xs={8}> <Grid container spacing={3}> <Grid item xs={4}> <Button onClick={() => window.location.reload()} style={{ textTransform: 'none' }}> <PageHeader title={<Typography variant='h5'>Providers: {totalProviders}</Typography>} /> </Button> </Grid> {/* Grid con el campo de búsqueda en la segunda columna */} <Grid item xs={4}> <Grid container spacing={2}> {/* Agregar un campo de búsqueda */} <Grid item xs={12}> <Grid item xs={8}> <Grid container spacing={2} alignItems="center" justifyContent="flex-end"> <Grid item> <TextField label="Search by ..." variant="outlined" //value={searchTerm} value={searchTerm} onChange={(e) => setSearchTerm(e.target.value)} /> </Grid> {/* Otros elementos adicionales en la segunda columna, si es necesario */} <Grid item> <Button variant="contained" color="primary" onClick={() => handleSearch(searchTerm)}> Search </Button> </Grid> </Grid> </Grid> </Grid> </Grid> <Grid item xs={12}> <Card> <CardHeader title='List of Providers' /> {isLoadingProvidersData ? ( {searchResults.length > 0 ? ( <TableContainer component={Paper}> <Table sx={{ minWidth: 650 }} aria-label='Providers table'> <TableHead> <TableRow> <TableCell>Provider id</TableCell> <TableCell>Information</TableCell> <TableCell>Owner name</TableCell> <TableCell>Actions</TableCell> </TableRow> </TableHead> <TableBody> {searchResults.map((provider) => ( <TableRow key={provider.api_prov_dom_id} sx={{ '&:last-of-type td, &:last-of-type th': { border: 0, }, }} > <TableCell component='th' scope='row'> <LinkStyled href={`/providers/${provider.api_prov_funcs[0].api_prov_func_id}`}> {provider.api_prov_dom_id} </LinkStyled> </TableCell> <TableCell>{provider.api_prov_dom_info}</TableCell> <TableCell> {provider.username ? ( <LinkStyled href={`/users/${provider.username}`}> {provider.username} </LinkStyled> ) : ( 'Unknown user' )} </TableCell> <TableCell> <Button variant='contained' onClick={() => handleDeleteClick(provider.api_prov_dom_id)} > Delete </Button> </TableCell> </TableRow> ))} </TableBody> </Table> </TableContainer> ) : isLoadingProvidersData ? ( <CircularProgress /> ) : isErrorProvidersData ? ( <Typography variant='body1' sx={{ paddingLeft: 4, paddingBottom: 2 }}> Loading Loading @@ -245,6 +325,8 @@ const Providers = () => { </Grid> <Grid item xs={12}> <Grid container spacing={3} alignItems="center" justifyContent="space-between"> <Grid item> Loading @@ -264,7 +346,6 @@ const Providers = () => { </Grid> </Grid> <Dialog open={isDeleteDialogOpen} onClose={handleDeleteCancel}> <DialogTitle>Confirm Deletion</DialogTitle> <DialogContent> Loading Loading
capif_frontend/src/configs/apiService.js +34 −0 Original line number Diff line number Diff line Loading @@ -158,3 +158,37 @@ export const deleteUser = async (username, password) => { export const getEvents = async id => { return axiosInstance.get(`/resources/events/${id}`) } // BUSCADOR export const searchInvokers = async (searchTerm, page, pageSize) => { try { const response = await axiosInstance.get(`/invokers/search`, { params: { page: page, pageSize: pageSize, searchTerm: searchTerm } }); return response.data; } catch (error) { throw new Error(`Error searching invokers: ${error.message}`); } }; export const searchProviders = async (searchTerm, page, pageSize) => { try { const response = await axiosInstance.get(`/providers/search`, { params: { page: page, pageSize: pageSize, searchTerm: searchTerm } }); return response.data; } catch (error) { throw new Error(`Error searching providers: ${error.message}`); } };
capif_frontend/src/pages/invokers/index.js +104 −23 Original line number Diff line number Diff line import React from 'react'; import { useState } from 'react'; import { useQuery, useQueryClient, QueryClient, QueryClientInvoker, useMutation } from '@tanstack/react-query' import { getInvokers, getInvokersPages, deleteInvoker, getNumInvokers } from 'src/configs/apiService'; import { getInvokers, getInvokersPages, deleteInvoker, getNumInvokers, searchInvokers } from 'src/configs/apiService'; import Link from 'next/link'; import Grid from '@mui/material/Grid'; import Card from '@mui/material/Card'; Loading Loading @@ -52,6 +52,12 @@ const Invokers = () => { const [showDeleteMessage, setShowDeleteMessage] = useState(false); const [errorDeleting, setErrorDeleting] = useState(false); // Estados para la búsqueda const [searchResults, setSearchResults] = useState([]); const [totalSearchResults, setTotalSearchResults] = useState(0); const [errorSearching, setErrorSearching] = useState(0); // INVOKERS DATA const queryKeyInvokers = ['invokers']; Loading Loading @@ -153,29 +159,56 @@ const Invokers = () => { setCurrentPage(1); }; const handleSearch = async () => { try { setErrorSearching(false); // Realizar la búsqueda en el backend const searchData = await searchInvokers(searchTerm, currentPage, pageSize); // Actualizar el estado con los resultados de la búsqueda y la información de paginación setSearchResults(searchData.data); setTotalPages(1) setCurrentPage(1) } catch (error) { console.error('Error searching invokers:', error.message); setErrorSearching(true); } }; return ( <Grid container spacing={3}> <Grid item xs={12}> {/* Agregar controles de búsqueda aquí si es necesario */} </Grid> <Grid item xs={8}> <Grid container spacing={3}> <Grid item xs={4}> <Button onClick={() => window.location.reload()} style={{ textTransform: 'none' }}> <PageHeader title={<Typography variant='h5'>Invokers: {totalInvokers}</Typography>} /> </Button> </Grid> {/* Grid con el campo de búsqueda en la segunda columna */} <Grid item xs={4}> <Grid container spacing={2}> {/* Agregar un campo de búsqueda */} <Grid item xs={12}> <Grid item xs={8}> <Grid container spacing={2} alignItems="center" justifyContent="flex-end"> <Grid item> <TextField label="Search by ..." variant="outlined" //value={searchTerm} value={searchTerm} onChange={(e) => setSearchTerm(e.target.value)} /> </Grid> {/* Otros elementos adicionales en la segunda columna, si es necesario */} <Grid item> <Button variant="contained" color="primary" onClick={() => handleSearch(searchTerm)}> Search </Button> </Grid> </Grid> </Grid> </Grid> </Grid> Loading @@ -183,7 +216,56 @@ const Invokers = () => { <Grid item xs={12}> <Card> <CardHeader title='List of Invokers' /> {isLoadingInvokersData ? ( {searchResults.length > 0 ? ( <TableContainer component={Paper}> <Table sx={{ minWidth: 650 }} aria-label='Invokers table'> <TableHead> <TableRow> <TableCell>ID</TableCell> <TableCell>Info</TableCell> <TableCell>User name</TableCell> <TableCell>Actions</TableCell> </TableRow> </TableHead> <TableBody> {searchResults.map((invoker) => ( <TableRow key={invoker.api_invoker_id} sx={{ '&:last-of-type td, &:last-of-type th': { border: 0, }, }} > <TableCell component='th' scope='row'> <LinkStyled href={`/invokers/${invoker.api_invoker_id}`}> {invoker.api_invoker_id} </LinkStyled> </TableCell> <TableCell>{invoker.api_invoker_information}</TableCell> <TableCell> {invoker.username ? ( <LinkStyled href={`/users/${invoker.username}`}> {invoker.username} </LinkStyled> ) : ( 'Unknown user' )} </TableCell> <TableCell> <Button variant='contained' onClick={() => handleDeleteClick(invoker.api_invoker_id)} > Delete </Button> </TableCell> </TableRow> ))} </TableBody> </Table> </TableContainer> ) : isLoadingInvokersData ? ( <CircularProgress /> ) : isErrorInvokersData ? ( <Typography variant='body1' sx={{ paddingLeft: 4, paddingBottom: 2 }}> Loading Loading @@ -270,7 +352,6 @@ const Invokers = () => { </Grid> </Grid> <Dialog open={isDeleteDialogOpen} onClose={handleDeleteCancel}> <DialogTitle>Confirm Deletion</DialogTitle> <DialogContent> Loading
capif_frontend/src/pages/providers/index.js +108 −27 Original line number Diff line number Diff line Loading @@ -17,7 +17,7 @@ import TableCell from '@mui/material/TableCell'; import TableContainer from '@mui/material/TableContainer'; import CircularProgress from '@mui/material/CircularProgress'; import Button from '@mui/material/Button'; import { deleteProvider, getNumProviders, getProvidersPages } from 'src/configs/apiService'; import { deleteProvider, getNumProviders, getProvidersPages, searchProviders } from 'src/configs/apiService'; import { Dialog, DialogTitle, DialogContent, DialogActions } from '@mui/material' import TextField from '@mui/material/TextField'; import Pagination from '@mui/material/Pagination'; Loading @@ -32,6 +32,7 @@ const LinkStyled = styled(Link)(({ theme }) => ({ })); const Providers = () => { const queryClient = useQueryClient() const [selectedProvider, setSelectedProvider] = useState(null); Loading @@ -48,8 +49,13 @@ const Providers = () => { const [showDeleteMessage, setShowDeleteMessage] = useState(false); const [errorDeleting, setErrorDeleting] = useState(false); // Estados para la búsqueda const [searchResults, setSearchResults] = useState([]); const [totalSearchResults, setTotalSearchResults] = useState(0); const [errorSearching, setErrorSearching] = useState(0); // PROVIDERS DATA // ProviderS DATA const queryKeyProviders = ['providers']; const { data: providersDataPages, isLoadingProvidersData, isErrorProvidersData, refetchProviders } = useQuery({ Loading @@ -59,7 +65,7 @@ const Providers = () => { refetchOnMount: false, }); console.log('providersDataPages:', providersDataPages); //console.log('providersDataPages:', providersDataPages); useEffect(() => { // Solo establece los invocadores cuando providersData cambie Loading Loading @@ -98,7 +104,7 @@ const Providers = () => { await deleteProvider(selectedProvider); // Simula el mensaje de éxito, reemplaza esta línea con tu lógica real // Carga el mensaje de éxito setDeleteMessage('Provider removed'); // Refresca los datos después de la eliminación manteniendo la página actual Loading Loading @@ -150,36 +156,110 @@ const Providers = () => { setCurrentPage(1); }; const handleSearch = async () => { try { setErrorSearching(false); // Realizar la búsqueda en el backend const searchData = await searchProviders(searchTerm, currentPage, pageSize); // Actualizar el estado con los resultados de la búsqueda y la información de paginación setSearchResults(searchData.data); setTotalPages(1) setCurrentPage(1) } catch (error) { console.error('Error searching providers:', error.message); setErrorSearching(true); } }; return ( <Grid container spacing={3}> <Grid item xs={12}> {/* Agregar controles de búsqueda aquí si es necesario */} </Grid> <Grid item xs={8}> <Grid container spacing={3}> <Grid item xs={4}> <Button onClick={() => window.location.reload()} style={{ textTransform: 'none' }}> <PageHeader title={<Typography variant='h5'>Providers: {totalProviders}</Typography>} /> </Button> </Grid> {/* Grid con el campo de búsqueda en la segunda columna */} <Grid item xs={4}> <Grid container spacing={2}> {/* Agregar un campo de búsqueda */} <Grid item xs={12}> <Grid item xs={8}> <Grid container spacing={2} alignItems="center" justifyContent="flex-end"> <Grid item> <TextField label="Search by ..." variant="outlined" //value={searchTerm} value={searchTerm} onChange={(e) => setSearchTerm(e.target.value)} /> </Grid> {/* Otros elementos adicionales en la segunda columna, si es necesario */} <Grid item> <Button variant="contained" color="primary" onClick={() => handleSearch(searchTerm)}> Search </Button> </Grid> </Grid> </Grid> </Grid> </Grid> <Grid item xs={12}> <Card> <CardHeader title='List of Providers' /> {isLoadingProvidersData ? ( {searchResults.length > 0 ? ( <TableContainer component={Paper}> <Table sx={{ minWidth: 650 }} aria-label='Providers table'> <TableHead> <TableRow> <TableCell>Provider id</TableCell> <TableCell>Information</TableCell> <TableCell>Owner name</TableCell> <TableCell>Actions</TableCell> </TableRow> </TableHead> <TableBody> {searchResults.map((provider) => ( <TableRow key={provider.api_prov_dom_id} sx={{ '&:last-of-type td, &:last-of-type th': { border: 0, }, }} > <TableCell component='th' scope='row'> <LinkStyled href={`/providers/${provider.api_prov_funcs[0].api_prov_func_id}`}> {provider.api_prov_dom_id} </LinkStyled> </TableCell> <TableCell>{provider.api_prov_dom_info}</TableCell> <TableCell> {provider.username ? ( <LinkStyled href={`/users/${provider.username}`}> {provider.username} </LinkStyled> ) : ( 'Unknown user' )} </TableCell> <TableCell> <Button variant='contained' onClick={() => handleDeleteClick(provider.api_prov_dom_id)} > Delete </Button> </TableCell> </TableRow> ))} </TableBody> </Table> </TableContainer> ) : isLoadingProvidersData ? ( <CircularProgress /> ) : isErrorProvidersData ? ( <Typography variant='body1' sx={{ paddingLeft: 4, paddingBottom: 2 }}> Loading Loading @@ -245,6 +325,8 @@ const Providers = () => { </Grid> <Grid item xs={12}> <Grid container spacing={3} alignItems="center" justifyContent="space-between"> <Grid item> Loading @@ -264,7 +346,6 @@ const Providers = () => { </Grid> </Grid> <Dialog open={isDeleteDialogOpen} onClose={handleDeleteCancel}> <DialogTitle>Confirm Deletion</DialogTitle> <DialogContent> Loading