Commit 5519e276 authored by Guillermo Sanz López's avatar Guillermo Sanz López
Browse files

invokers and providers page working with pagination and delete

parent a9622f17
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -3,3 +3,4 @@ NEXT_PUBLIC_JWT_SECRET=dd5f3089-40c3-403d-af14-d0c228b05cb4
NEXT_PUBLIC_JWT_REFRESH_TOKEN_SECRET=7c4c1c50-3230-45bf-9eae-c9b2e401c767
NEXT_PUBLIC_API_BASE_URL="https://backoffice-api.mobilesandbox.cloud:38443"
NEXT_PUBLIC_GRAFANA_BASE_URL="https://grafana.5gnacar.int"
NODE_ENV=development
+49 −1
Original line number Diff line number Diff line
@@ -7,7 +7,6 @@ export const getInvokers = async () => {
  return axiosInstance.get(`/resources/invokers`)
}

// GET /resources/invokers?page=1&page_size=10
export const getInvokersPages = async ({ page, pageSize }) => {
  try {
    const response = await axiosInstance.get(`/resources/invokersPages`, {
@@ -64,6 +63,22 @@ export const getProviders = async () => {
  return axiosInstance.get(`/resources/providers`)
}

export const getProvidersPages = async ({ page, pageSize }) => {
  try {
    const response = await axiosInstance.get(`/resources/providersPages`, {
      params: {
        page: page,
        pageSize: pageSize
        //searchTerm: searchTerm
      }
    });
    
    return response.data;
  } catch (error) {
    throw new Error(`Error fetching providers: ${error.message}`);
  }
}

export const getNumProviders = async () => {
  return axiosInstance.get(`/resources/numProviders`)
}
@@ -73,6 +88,7 @@ export const getProviderServices = async providerId => {
}

export const deleteProvider = async providerId => {
  console.log("providerId: ", providerId)
  return axiosInstance.delete(`/providers/${providerId}`)
}

@@ -89,11 +105,43 @@ export const getNumApis = async () => {
  return axiosInstance.get(`/apis/num`)
}

export const getApisPages = async ({ page, pageSize }) => {
  try {
    const response = await axiosInstance.get(`/apisPages`, {
      params: {
        page: page,
        pageSize: pageSize
        //searchTerm: searchTerm
      }
    });
    
    return response.data;
  } catch (error) {
    throw new Error(`Error fetching apis: ${error.message}`);
  }
}

// USERS
export const getUsers = async id => {
  return axiosInstance.get(`/users`)
}

export const getUsersPages = async ({ page, pageSize }) => {
  try {
    const response = await axiosInstance.get(`/resources/usersPagesRetrieve`, {
      params: {
        page: page,
        pageSize: pageSize
        //searchTerm: searchTerm
      }
    });
    
    return response.data;
  } catch (error) {
    throw new Error(`Error fetching users: ${error.message}`);
  }
}

export const getUser = async name => {
  return axiosInstance.get(`/resources/users/${name}`)
}
+4 −4
Original line number Diff line number Diff line
@@ -49,16 +49,16 @@ const AuthProvider = ({ children }) => {
  // useEffect -> hook de react que se ejecuta cuando el componente se monta, 1 VEZ
  useEffect(() => {
    const initAuth = async () => {
      console.log('Entró por initAuth')
      //console.log('Entró por initAuth')
      const storedAccessToken = getAccessToken()  // obtiene el token de acceso almacenado en las cookies
      
      console.log('storedAccessToken: ', storedAccessToken)
      console.log('authConfig.meEndpoint: ', authConfig.meEndpoint)
      //console.log('storedAccessToken: ', storedAccessToken)
      //console.log('authConfig.meEndpoint: ', authConfig.meEndpoint)

      if (storedAccessToken) { // la primera vez que se ejecute no entrará por aquí logicamente pues no hay token de acceso aún
        setLoading(true)
        try {
          console.log("Entró por donde el token existe")
          //console.log("Entró por donde el token existe")
          
          // auth/me -> se le envía el token de acceso y devuelve 200 si es válido o 401 si no lo es
          const response = await axiosInstance.get(authConfig.meEndpoint, {  // https://10.95.82.71:8085/auth/me + Authorization: Bearer token
+98 −30
Original line number Diff line number Diff line
@@ -16,11 +16,15 @@ 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 { getApis, getNumApis } from 'src/configs/apiService';
import { getNumApis, getApisPages } from 'src/configs/apiService';
import { useState } from 'react'
import { Dialog, DialogTitle, DialogContent, DialogActions } from '@mui/material'
import TextField from '@mui/material/TextField';
import { deleteProviderService } from 'src/configs/apiService';
import Pagination from '@mui/material/Pagination';
import Select from '@mui/material/Select';
import MenuItem from '@mui/material/MenuItem';
import { useEffect } from 'react';

const LinkStyled = styled(Link)(({ theme }) => ({
  textDecoration: 'none',
@@ -33,24 +37,56 @@ const Apis = () => {
  const [isDeleteDialogOpen, setDeleteDialogOpen] = useState(false);
  const [searchTerm, setSearchTerm] = useState('');

  // Define la clave única para esta consulta
  const queryKey = ['apis'];
  const [currentPage, setCurrentPage] = useState(1);
  const [pageSize, setPageSize] = useState(10); // Número de invocadores por página
  const [totalPages, setTotalPages] = useState(0);
  const [totalApis, setTotalApis] = useState(0);
  const [apis, setApis] = useState([]);

  // Usa useQuery para obtener los datos
  const { data: apisData, isLoading, isError, refetch } = useQuery({
    queryKey,
    queryFn: getApis,
  });
  // APIS DATA
  const queryKeyApis = ['apis'];

  // Definir la clave única para esta consulta
  const queryKeyNum = ['apisNum']
  console.log("entra por aquí")

  // Utilizar useQuery para obtener los datos
  const { data: apisNum, isLoadingNum, isErrorNum } = useQuery({
    queryKeyNum,
    queryFn: getNumApis,
  const { data: apisDataPages, isLoadingApisData, isErrorApisData, refetchApis } = useQuery({
    queryKey: queryKeyApis,
    queryFn: () => getApisPages({ page: currentPage, pageSize }),
    refetchOnWindowFocus: false,
    refetchOnMount: false,
  });

  console.log("2 Imprime apisDataPages", apisDataPages)


  useEffect(() => {
    // Solo establece los invocadores cuando ApisData cambie
    console.log("3 dentro del useEffect1 Imprime apisDataPages", apisDataPages)
    if (apisDataPages) {
      setApis(apisDataPages.data);
      console.log("4 Imprime apisDataPages.data dentro del if", apisDataPages.data)
    }
  }, [apisDataPages]);

  useEffect(() => {
    // Lógica para refrescar los datos aquí
    const fetchData = async () => {
      try {
        const response = await getApisPages({ page: currentPage, pageSize });
        setApis(response.data);
        setTotalApis(response.total);
        console.log('Total apis:', response.total);
        setTotalPages(Math.ceil(response.total / pageSize));
      } catch (error) {
        console.error('Error fetching apis:', error.message);
      }
    };
  
    fetchData(); // Llama a la función fetchData directamente cuando cambien las dependencias
  }, [currentPage, pageSize]);

  console.log('5 apis, no debería existir hasta refrescar la página: ', apis)
  

  const handleDeleteClick = (apf_id, api_id) => {
    setSelectedApi({ apf_id, api_id })
    setDeleteDialogOpen(true)
@@ -77,11 +113,24 @@ const Apis = () => {
    setSelectedApi(null)
  }

  const handlePageChange = (newPage) => {
    setCurrentPage(newPage);
  };

  const handlePageSizeChange = (event) => {
    const newSize = event.target.value;
    setPageSize(newSize);
    // Recalcular el número total de páginas cuando cambia el tamaño de la página
    const newTotalPages = Math.ceil(totalApis / newSize);
    setTotalPages(newTotalPages);
    // Asegurarse de que la página actual sea válida después de cambiar el tamaño de la página
    setCurrentPage(1);
  };

  return (
    <Grid container spacing={6}>
      
      <Grid item xs={8}>
        <PageHeader title={<Typography variant='h5'>APIs: {apisNum?.data}</Typography>} />
        <PageHeader title={<Typography variant='h5'>Apis: {totalApis}</Typography>} />
      </Grid>

      {/* Grid con el campo de búsqueda en la segunda columna */}
@@ -103,20 +152,16 @@ const Apis = () => {
      
      <Grid item xs={12}>
        <Card>
          <CardHeader title='List of APIs' />
          <CardHeader title='List of Apis' />
          <TableContainer component={Paper}>
            <Table sx={{ minWidth: 650 }} aria-label='APIs table'>
              {isLoading ? (
            <Table sx={{ minWidth: 650 }} aria-label='Apis table'>
              {isLoadingApisData ? (
                <CircularProgress />
              ) : isError ? (
              ) : isErrorApisData ? (
                <Typography variant='body1' sx={{ paddingLeft: 4, paddingBottom: 2 }}>
                  Error loading data.
                </Typography>
              ) : !apisData || apisData.length === 0 ? (
                <Typography variant='body1' sx={{ paddingLeft: 4, paddingBottom: 2 }}>
                  There are no apis yet.
                </Typography>
              ) : (
              ) : apisDataPages?.data && apisDataPages.data.length > 0 ? (
                <>
                  <TableHead>
                    <TableRow>
@@ -127,9 +172,9 @@ const Apis = () => {
                    </TableRow>
                  </TableHead>
                  <TableBody>
                    {apisData.data.object.map((api) => (
                    {apis.map((api) => (
                      <TableRow
                        key={api.username}
                        key={api.api_id}
                        sx={{
                          '&:last-of-type td, &:last-of-type th': {
                            border: 0,
@@ -155,17 +200,40 @@ const Apis = () => {
                    ))}
                  </TableBody>
                </>
              ) : (
                <Typography variant='body1' sx={{ paddingLeft: 4, paddingBottom: 2 }}>
                  There are no apis yet.
                </Typography>
              )}
            </Table>
          </TableContainer>
        </Card>
      </Grid>

      <Grid item xs={12}>
        <Grid container spacing={3} alignItems="center" justifyContent="space-between">
          <Grid item>
            <Pagination
              count={totalPages}
              page={currentPage}
              onChange={(event, value) => handlePageChange(value)}
            />
          </Grid>
          <Grid item>
            <Select value={pageSize} onChange={handlePageSizeChange}>
              <MenuItem value={10}>10 per page</MenuItem>
              <MenuItem value={20}>20 per page</MenuItem>
              <MenuItem value={30}>30 per page</MenuItem>
            </Select>
          </Grid>
        </Grid>
      </Grid>

      {/* Confirmación de eliminación */}
      <Dialog open={isDeleteDialogOpen} onClose={handleDeleteCancel}>
        <DialogTitle>Confirm Deletion</DialogTitle>
        <DialogContent>
          Are you sure you want to delete the provider?
          Are you sure you want to delete the API?
        </DialogContent>
        <DialogActions>
          <Button onClick={handleDeleteCancel}>Cancel</Button>
+7 −7
Original line number Diff line number Diff line
@@ -76,10 +76,10 @@ const Homedash = () => {
  });

  // APIS DATA
  const queryKeyApis= ['apis'];
  const queryKeyApisDataHD= ['apisDataHD'];

  const { data: apisData, isLoadingApis, isErrorApis, refetchApis } = useQuery({
    queryKey: queryKeyApis,
  const { data: apisDataHD, isLoadingApisDataHD, isErrorApisDataHD, refetchApisDataHD } = useQuery({
    queryKey: queryKeyApisDataHD,
    queryFn: getApis,
  });

@@ -256,11 +256,11 @@ const Homedash = () => {
                <CardContent style={{ textAlign: 'center' }}>
                  <Typography variant='h5'>APIs:</Typography>
                  <Typography variant='h4' sx={{ marginBottom: 6 }}>{apisNum?.data}</Typography>
                  {!apisData?.data && <CircularProgress />}
                  {apisData?.data && (
                  {!apisDataHD?.data && <CircularProgress />}
                  {apisDataHD?.data && (
                    <>
                    <List>
                      {apisData.data.object.slice(-5).map((api) => (
                      {apisDataHD.data.object.slice(-5).map((api) => (
                        <ListItem key={api.api_id}>
                          <ListItemText
                            primary={
@@ -275,7 +275,7 @@ const Homedash = () => {
                    </List>
                    <Box textAlign='center' mt={3}>
                      <Typography variant='body2' sx={{ textDecoration: 'underline' }}>
                        Click here to see more users.
                        Click here to see more APIs.
                      </Typography>
                    </Box>
                  </>
Loading