Loading capif_frontend/package.json +2 −0 Original line number Diff line number Diff line Loading @@ -31,6 +31,7 @@ "@hookform/resolvers": "3.1.0", "@iconify/react": "4.1.0", "@material-ui/core": "^4.12.4", "@mui/icons-material": "^5.15.12", "@mui/lab": "5.0.0-alpha.128", "@mui/material": "5.12.2", "@mui/system": "5.12.1", Loading Loading @@ -71,6 +72,7 @@ "react-hook-form": "7.43.9", "react-hot-toast": "2.4.1", "react-i18next": "12.2.2", "react-icons": "^5.0.1", "react-perfect-scrollbar": "1.5.8", "react-popper": "2.3.0", "react-redux": "8.0.5", Loading capif_frontend/src/@core/layouts/components/shared-components/footer/FooterContent.js +2 −2 Original line number Diff line number Diff line Loading @@ -26,14 +26,14 @@ const FooterContent = () => { {` © ${new Date().getFullYear()}`} </Typography> {/* Elemento central */} <Box sx={{ display: 'flex', alignItems: 'center', marginRight: 8 }}> {/* <Box sx={{ display: 'flex', alignItems: 'center', marginRight: 8 }}> <img src='/images/6g-sandbox.png' alt='logo' width='60' height='30' /> <Typography sx={{ marginLeft: 2 }}> <LinkStyled target='_blank' href='https://6g-sandbox.eu/'> 6G Sandbox </LinkStyled> </Typography> </Box> </Box> */} {hidden ? null : ( <Box sx={{ display: 'flex', flexWrap: 'wrap', alignItems: 'center', '& :not(:last-child)': { mr: 4 } }}> <LinkStyled target='_blank' href='https://ocf.etsi.org/'> Loading capif_frontend/src/configs/apiService.js +110 −15 Original line number Diff line number Diff line Loading @@ -7,12 +7,13 @@ export const getInvokers = async () => { return axiosInstance.get(`/resources/invokers`) } export const getInvokersPages = async ({ page, pageSize }) => { export const getInvokersPagesOrder = async ({ page, pageSize, order }) => { try { const response = await axiosInstance.get(`/resources/invokersPages`, { const response = await axiosInstance.get(`/resources/invokersPagesOrder`, { params: { page: page, pageSize: pageSize pageSize: pageSize, order: order //searchTerm: searchTerm } }); Loading Loading @@ -53,6 +54,23 @@ export const deleteInvoker = async invokerId => { return axiosInstance.delete(`/invokers/${invokerId}`) } export const deleteInvokers = async invokerIds => { try { console.log('invokerIds', invokerIds) const response = await axiosInstance.delete('/invokers10', { headers: { 'Content-Type': 'application/json' }, data: { invoker_ids: invokerIds } }); return response.data; // Retorna los datos de la respuesta si la solicitud fue exitosa } catch (error) { throw error; // Lanza un error si la solicitud no fue exitosa } }; export const deleteSecurityContext = async (invokerId, aef_id, api_id) => { return axiosInstance.delete(`/invokers/security/${invokerId}/${aef_id}/${api_id}`) } Loading @@ -63,13 +81,13 @@ export const getProviders = async () => { return axiosInstance.get(`/resources/providers`) } export const getProvidersPages = async ({ page, pageSize }) => { export const getProvidersPagesOrder = async ({ page, pageSize, order }) => { try { const response = await axiosInstance.get(`/resources/providersPages`, { const response = await axiosInstance.get(`/resources/providersPagesOrder`, { params: { page: page, pageSize: pageSize //searchTerm: searchTerm pageSize: pageSize, order: order } }); Loading @@ -91,10 +109,30 @@ export const deleteProvider = async providerId => { return axiosInstance.delete(`/providers/${providerId}`) } export const deleteProviders = async providerIds => { try { console.log('providerIds', providerIds) const response = await axiosInstance.delete('/providers10', { headers: { 'Content-Type': 'application/json' }, data: { provider_ids: providerIds } }); return response.data; // Retorna los datos de la respuesta si la solicitud fue exitosa } catch (error) { throw error; // Lanza un error si la solicitud no fue exitosa } }; export const deleteProviderService = async (apf_id, api_id) => { return axiosInstance.delete(`/providers/services/${apf_id}/${api_id}`) } // APIS export const getApis = async () => { return axiosInstance.get(`/apis`) Loading @@ -104,13 +142,13 @@ export const getNumApis = async () => { return axiosInstance.get(`/apis/num`) } export const getApisPages = async ({ page, pageSize }) => { export const getApisPagesOrder = async ({ page, pageSize, order }) => { try { const response = await axiosInstance.get(`/apisPages`, { const response = await axiosInstance.get(`/apisPagesOrder`, { params: { page: page, pageSize: pageSize //searchTerm: searchTerm pageSize: pageSize, order: order } }); Loading @@ -120,18 +158,38 @@ export const getApisPages = async ({ page, pageSize }) => { } } export const deleteProvidersServices = async apis => { try { const data = { api: apis.map(({ apf_id, api_id }) => ({ apf_id, api_id })) }; const response = await axiosInstance.delete('/apis10', { headers: { 'Content-Type': 'application/json' }, data: JSON.stringify(data) }); return response.data; // Retorna los datos de la respuesta si la solicitud fue exitosa } catch (error) { throw error; // Lanza un error si la solicitud no fue exitosa } }; // USERS export const getUsers = async id => { return axiosInstance.get(`/users`) } export const getUsersPages = async ({ page, pageSize }) => { export const getUsersPagesOrder = async ({ page, pageSize, order }) => { try { const response = await axiosInstance.get(`/resources/usersPagesRetrieve`, { const response = await axiosInstance.get(`/resources/usersPagesOrder`, { params: { page: page, pageSize: pageSize //searchTerm: searchTerm pageSize: pageSize, order: order } }); Loading @@ -153,6 +211,43 @@ export const deleteUser = async (username, password) => { return axiosInstance.delete(`/user/${username}/${password}`) } export const deleteUsers = async (users) => { try { const data = { users: users.map(({ username, password }) => ({ username, password })) }; const response = await axiosInstance.delete('/users10', { headers: { 'Content-Type': 'application/json' }, data: JSON.stringify(data) }); return response.data; // Retorna los datos de la respuesta si la solicitud fue exitosa } catch (error) { throw error; // Lanza un error si la solicitud no fue exitosa } }; export const createUser = async (userData) => { try { // Haz la solicitud POST con axios const response = await axiosInstance.post('/user', userData, { headers: { 'Content-Type': 'application/json' }, }); // Retorna los datos de la respuesta si la solicitud fue exitosa return response.data; } catch (error) { // Lanza un error si la solicitud no fue exitosa throw error; } }; // EVENTS export const getEvents = async id => { Loading capif_frontend/src/pages/apis/index.js +123 −53 Original line number Diff line number Diff line Loading @@ -16,15 +16,19 @@ 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 { getApisPages, searchApis } from 'src/configs/apiService'; import { getApisPagesOrder, searchApis } 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 { deleteProviderService, deleteProvidersServices } 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'; import Checkbox from '@mui/material/Checkbox'; import ArrowDropDownIcon from '@mui/icons-material/ArrowDropDown'; import ArrowDropUpIcon from '@mui/icons-material/ArrowDropUp'; const LinkStyled = styled(Link)(({ theme }) => ({ textDecoration: 'none', Loading Loading @@ -54,12 +58,19 @@ const Apis = () => { const [totalSearchResults, setTotalSearchResults] = useState(0); const [errorSearching, setErrorSearching] = useState(0); // ApiS DATA // Estados para la selección múltiple const [selectedApis, setSelectedApis] = useState([]); // Estados para el ordenamiento por fecha const [sortOrder, setSortOrder] = useState("asc"); const [isAscending, setIsAscending] = useState(true); // APIS DATA const queryKeyApis = ['apis']; const { data: apisDataPages, isLoadingApisData, isErrorApisData, refetchApis } = useQuery({ queryKey: queryKeyApis, queryFn: () => getApisPages({ page: currentPage, pageSize }), queryFn: () => getApisPagesOrder({ page: currentPage, pageSize, order: sortOrder}), refetchOnWindowFocus: false, refetchOnMount: false, }); Loading @@ -77,7 +88,7 @@ const Apis = () => { // Lógica para refrescar los datos aquí const fetchData = async () => { try { const response = await getApisPages({ page: currentPage, pageSize }); const response = await getApisPagesOrder({ page: currentPage, pageSize, order: sortOrder}); setApis(response.data); setTotalApis(response.total); setTotalPages(Math.ceil(response.total / pageSize)); Loading @@ -87,11 +98,30 @@ const Apis = () => { }; fetchData(); // Llama a la función fetchData directamente cuando cambien las dependencias }, [currentPage, pageSize]); }, [currentPage, pageSize, sortOrder]); const handleToggleApi = (apf_id, api_id) => { const selectedIndex = selectedApis.findIndex(api => api.api_id === api_id); let newSelected = []; if (selectedIndex === -1) { newSelected = [...selectedApis, { apf_id, api_id }]; } else if (selectedIndex === 0) { newSelected = selectedApis.slice(1); } else if (selectedIndex === selectedApis.length - 1) { newSelected = selectedApis.slice(0, -1); } else if (selectedIndex > 0) { newSelected = [ ...selectedApis.slice(0, selectedIndex), ...selectedApis.slice(selectedIndex + 1) ]; } setSelectedApis(newSelected); }; const handleDeleteClick = (apf_id, api_id) => { setSelectedApi({ apf_id, api_id }) console.log('selectedApis:', selectedApis); setDeleteDialogOpen(true) } Loading @@ -102,8 +132,9 @@ const Apis = () => { const currentPageBeforeDelete = currentPage; // Guarda la página actual antes de la eliminación const { apf_id, api_id } = selectedApi await deleteProviderService(apf_id, api_id) //const { apf_id, api_id } = selectedApi //await deleteProviderService(apf_id, api_id) await deleteProvidersServices(selectedApis); // Carga el mensaje de éxito setDeleteMessage('Api removed'); Loading @@ -121,6 +152,7 @@ const Apis = () => { } setDeleteDialogOpen(false); setSelectedApis([]); setSelectedApi(null); setShowDeleteMessage(true); } catch (error) { Loading Loading @@ -174,6 +206,11 @@ const Apis = () => { } }; const handleClickDate = () => { setIsAscending((prevState) => !prevState); setSortOrder(sortOrder === 'asc' ? 'desc' : 'asc'); }; return ( <Grid container spacing={3}> <Grid item xs={12}> Loading Loading @@ -212,37 +249,36 @@ const Apis = () => { <Table sx={{ minWidth: 650 }} aria-label='APIs table'> <TableHead> <TableRow> <TableCell></TableCell> <TableCell>API name</TableCell> <TableCell>Description</TableCell> <TableCell>AEF</TableCell> <TableCell>Delete API</TableCell> </TableRow> </TableHead> <TableBody> {searchResults.map((api) => ( {searchResults.map((selectedApi) => ( <TableRow key={api.api_id} key={selectedApi.api_id} sx={{ '&:last-of-type td, &:last-of-type th': { border: 0, }, }} > <TableCell> <Checkbox onChange={() => handleToggleApi(selectedApi.apf_id, selectedApi.api_id)} checked={selectedApis.some(api => api.apf_id === selectedApi.apf_id && api.api_id === selectedApi.api_id)} /> </TableCell> <TableCell component='th' scope='row'> <LinkStyled href={`/apis/${api.api_name}`}> {api.api_name} <LinkStyled href={`/apis/${selectedApi.api_name}`}> {selectedApi.api_name} </LinkStyled> </TableCell> <TableCell>{api.description}</TableCell> <TableCell>{api.aef_profiles[0].aef_id}</TableCell> <TableCell> <Button variant='contained' onClick={() => handleDeleteClick(api.apf_id, api.api_id)} > Delete </Button> </TableCell> <TableCell>{selectedApi.description}</TableCell> <TableCell>{selectedApi.aef_profiles[0].aef_id}</TableCell> <TableCell>{selectedApi.onboarding_date}</TableCell> </TableRow> ))} </TableBody> Loading @@ -260,39 +296,59 @@ const Apis = () => { <Table sx={{ minWidth: 650 }} aria-label='APIs table'> <TableHead> <TableRow> <TableCell></TableCell> <TableCell>API name</TableCell> <TableCell>Description</TableCell> <TableCell>AEF</TableCell> <TableCell>Delete API</TableCell> <TableCell> Date <Button aria-label="Sort by date" onClick={handleClickDate} style={{ minWidth: 'auto', padding: 0 }} > {isAscending ? <ArrowDropDownIcon /> : <ArrowDropUpIcon />} </Button> {/* <Menu id="date-order-menu" anchorEl={anchorEl} open={Boolean(anchorEl)} onClose={handleClose} > <MenuItem onClick={() => { handleSortOrderChange('asc'); handleClose(); }}>Ascending</MenuItem> <MenuItem onClick={() => { handleSortOrderChange('desc'); handleClose(); }}>Descending</MenuItem> </Menu> */} </TableCell> </TableRow> </TableHead> <TableBody> {apis.map((api) => ( {apis.map((selectedApi) => ( <TableRow key={api.api_id} key={selectedApi.api_id} sx={{ '&:last-of-type td, &:last-of-type th': { border: 0, }, }} > <TableCell> <Checkbox onChange={() => handleToggleApi(selectedApi.apf_id, selectedApi.api_id)} checked={selectedApis.some(api => api.apf_id === selectedApi.apf_id && api.api_id === selectedApi.api_id)} /> </TableCell> <TableCell component='th' scope='row'> <LinkStyled href={`/apis/${api.api_name}`}> {api.api_name} <LinkStyled href={`/apis/${selectedApi.api_name}`}> {selectedApi.api_name} </LinkStyled> </TableCell> <TableCell>{api.description}</TableCell> <TableCell>{api.aef_profiles[0].aef_id}</TableCell> <TableCell> <Button variant='contained' onClick={() => handleDeleteClick(api.apf_id, api.api_id)} > Delete </Button> </TableCell> <TableCell>{selectedApi.description}</TableCell> <TableCell>{selectedApi.aef_profiles[0].aef_id}</TableCell> <TableCell>{selectedApi.onboarding_date}</TableCell> </TableRow> ))} </TableBody> </Table> </TableContainer> Loading @@ -316,6 +372,13 @@ const Apis = () => { onChange={(event, value) => handlePageChange(value)} /> </Grid> <Grid> <Button variant="contained" color="primary" onClick={handleDeleteClick}> Delete </Button> </Grid> <Grid item> <Select value={pageSize} onChange={handlePageSizeChange}> <MenuItem value={10}>10 per page</MenuItem> Loading @@ -329,7 +392,14 @@ const Apis = () => { <Dialog open={isDeleteDialogOpen} onClose={handleDeleteCancel}> <DialogTitle>Confirm Deletion</DialogTitle> <DialogContent> Are you sure you want to delete the api? Are you sure you want to delete the following apis? <ul> {selectedApis.map(api => ( <li key={api.api_id}> {api.api_id} </li> ))} </ul> </DialogContent> <DialogActions> <Button onClick={handleDeleteCancel}>Cancel</Button> Loading @@ -346,7 +416,7 @@ const Apis = () => { <DialogContent> {errorDeleting ? 'An error occurred while deleting the api.' : 'The api has been successfully deleted.'} : 'The APIs has been successfully deleted.'} </DialogContent> <DialogActions> <Button onClick={handleDeleteMessageAccept} autoFocus> Loading capif_frontend/src/pages/invokers/index.js +122 −29 File changed.Preview size limit exceeded, changes collapsed. Show changes Loading
capif_frontend/package.json +2 −0 Original line number Diff line number Diff line Loading @@ -31,6 +31,7 @@ "@hookform/resolvers": "3.1.0", "@iconify/react": "4.1.0", "@material-ui/core": "^4.12.4", "@mui/icons-material": "^5.15.12", "@mui/lab": "5.0.0-alpha.128", "@mui/material": "5.12.2", "@mui/system": "5.12.1", Loading Loading @@ -71,6 +72,7 @@ "react-hook-form": "7.43.9", "react-hot-toast": "2.4.1", "react-i18next": "12.2.2", "react-icons": "^5.0.1", "react-perfect-scrollbar": "1.5.8", "react-popper": "2.3.0", "react-redux": "8.0.5", Loading
capif_frontend/src/@core/layouts/components/shared-components/footer/FooterContent.js +2 −2 Original line number Diff line number Diff line Loading @@ -26,14 +26,14 @@ const FooterContent = () => { {` © ${new Date().getFullYear()}`} </Typography> {/* Elemento central */} <Box sx={{ display: 'flex', alignItems: 'center', marginRight: 8 }}> {/* <Box sx={{ display: 'flex', alignItems: 'center', marginRight: 8 }}> <img src='/images/6g-sandbox.png' alt='logo' width='60' height='30' /> <Typography sx={{ marginLeft: 2 }}> <LinkStyled target='_blank' href='https://6g-sandbox.eu/'> 6G Sandbox </LinkStyled> </Typography> </Box> </Box> */} {hidden ? null : ( <Box sx={{ display: 'flex', flexWrap: 'wrap', alignItems: 'center', '& :not(:last-child)': { mr: 4 } }}> <LinkStyled target='_blank' href='https://ocf.etsi.org/'> Loading
capif_frontend/src/configs/apiService.js +110 −15 Original line number Diff line number Diff line Loading @@ -7,12 +7,13 @@ export const getInvokers = async () => { return axiosInstance.get(`/resources/invokers`) } export const getInvokersPages = async ({ page, pageSize }) => { export const getInvokersPagesOrder = async ({ page, pageSize, order }) => { try { const response = await axiosInstance.get(`/resources/invokersPages`, { const response = await axiosInstance.get(`/resources/invokersPagesOrder`, { params: { page: page, pageSize: pageSize pageSize: pageSize, order: order //searchTerm: searchTerm } }); Loading Loading @@ -53,6 +54,23 @@ export const deleteInvoker = async invokerId => { return axiosInstance.delete(`/invokers/${invokerId}`) } export const deleteInvokers = async invokerIds => { try { console.log('invokerIds', invokerIds) const response = await axiosInstance.delete('/invokers10', { headers: { 'Content-Type': 'application/json' }, data: { invoker_ids: invokerIds } }); return response.data; // Retorna los datos de la respuesta si la solicitud fue exitosa } catch (error) { throw error; // Lanza un error si la solicitud no fue exitosa } }; export const deleteSecurityContext = async (invokerId, aef_id, api_id) => { return axiosInstance.delete(`/invokers/security/${invokerId}/${aef_id}/${api_id}`) } Loading @@ -63,13 +81,13 @@ export const getProviders = async () => { return axiosInstance.get(`/resources/providers`) } export const getProvidersPages = async ({ page, pageSize }) => { export const getProvidersPagesOrder = async ({ page, pageSize, order }) => { try { const response = await axiosInstance.get(`/resources/providersPages`, { const response = await axiosInstance.get(`/resources/providersPagesOrder`, { params: { page: page, pageSize: pageSize //searchTerm: searchTerm pageSize: pageSize, order: order } }); Loading @@ -91,10 +109,30 @@ export const deleteProvider = async providerId => { return axiosInstance.delete(`/providers/${providerId}`) } export const deleteProviders = async providerIds => { try { console.log('providerIds', providerIds) const response = await axiosInstance.delete('/providers10', { headers: { 'Content-Type': 'application/json' }, data: { provider_ids: providerIds } }); return response.data; // Retorna los datos de la respuesta si la solicitud fue exitosa } catch (error) { throw error; // Lanza un error si la solicitud no fue exitosa } }; export const deleteProviderService = async (apf_id, api_id) => { return axiosInstance.delete(`/providers/services/${apf_id}/${api_id}`) } // APIS export const getApis = async () => { return axiosInstance.get(`/apis`) Loading @@ -104,13 +142,13 @@ export const getNumApis = async () => { return axiosInstance.get(`/apis/num`) } export const getApisPages = async ({ page, pageSize }) => { export const getApisPagesOrder = async ({ page, pageSize, order }) => { try { const response = await axiosInstance.get(`/apisPages`, { const response = await axiosInstance.get(`/apisPagesOrder`, { params: { page: page, pageSize: pageSize //searchTerm: searchTerm pageSize: pageSize, order: order } }); Loading @@ -120,18 +158,38 @@ export const getApisPages = async ({ page, pageSize }) => { } } export const deleteProvidersServices = async apis => { try { const data = { api: apis.map(({ apf_id, api_id }) => ({ apf_id, api_id })) }; const response = await axiosInstance.delete('/apis10', { headers: { 'Content-Type': 'application/json' }, data: JSON.stringify(data) }); return response.data; // Retorna los datos de la respuesta si la solicitud fue exitosa } catch (error) { throw error; // Lanza un error si la solicitud no fue exitosa } }; // USERS export const getUsers = async id => { return axiosInstance.get(`/users`) } export const getUsersPages = async ({ page, pageSize }) => { export const getUsersPagesOrder = async ({ page, pageSize, order }) => { try { const response = await axiosInstance.get(`/resources/usersPagesRetrieve`, { const response = await axiosInstance.get(`/resources/usersPagesOrder`, { params: { page: page, pageSize: pageSize //searchTerm: searchTerm pageSize: pageSize, order: order } }); Loading @@ -153,6 +211,43 @@ export const deleteUser = async (username, password) => { return axiosInstance.delete(`/user/${username}/${password}`) } export const deleteUsers = async (users) => { try { const data = { users: users.map(({ username, password }) => ({ username, password })) }; const response = await axiosInstance.delete('/users10', { headers: { 'Content-Type': 'application/json' }, data: JSON.stringify(data) }); return response.data; // Retorna los datos de la respuesta si la solicitud fue exitosa } catch (error) { throw error; // Lanza un error si la solicitud no fue exitosa } }; export const createUser = async (userData) => { try { // Haz la solicitud POST con axios const response = await axiosInstance.post('/user', userData, { headers: { 'Content-Type': 'application/json' }, }); // Retorna los datos de la respuesta si la solicitud fue exitosa return response.data; } catch (error) { // Lanza un error si la solicitud no fue exitosa throw error; } }; // EVENTS export const getEvents = async id => { Loading
capif_frontend/src/pages/apis/index.js +123 −53 Original line number Diff line number Diff line Loading @@ -16,15 +16,19 @@ 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 { getApisPages, searchApis } from 'src/configs/apiService'; import { getApisPagesOrder, searchApis } 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 { deleteProviderService, deleteProvidersServices } 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'; import Checkbox from '@mui/material/Checkbox'; import ArrowDropDownIcon from '@mui/icons-material/ArrowDropDown'; import ArrowDropUpIcon from '@mui/icons-material/ArrowDropUp'; const LinkStyled = styled(Link)(({ theme }) => ({ textDecoration: 'none', Loading Loading @@ -54,12 +58,19 @@ const Apis = () => { const [totalSearchResults, setTotalSearchResults] = useState(0); const [errorSearching, setErrorSearching] = useState(0); // ApiS DATA // Estados para la selección múltiple const [selectedApis, setSelectedApis] = useState([]); // Estados para el ordenamiento por fecha const [sortOrder, setSortOrder] = useState("asc"); const [isAscending, setIsAscending] = useState(true); // APIS DATA const queryKeyApis = ['apis']; const { data: apisDataPages, isLoadingApisData, isErrorApisData, refetchApis } = useQuery({ queryKey: queryKeyApis, queryFn: () => getApisPages({ page: currentPage, pageSize }), queryFn: () => getApisPagesOrder({ page: currentPage, pageSize, order: sortOrder}), refetchOnWindowFocus: false, refetchOnMount: false, }); Loading @@ -77,7 +88,7 @@ const Apis = () => { // Lógica para refrescar los datos aquí const fetchData = async () => { try { const response = await getApisPages({ page: currentPage, pageSize }); const response = await getApisPagesOrder({ page: currentPage, pageSize, order: sortOrder}); setApis(response.data); setTotalApis(response.total); setTotalPages(Math.ceil(response.total / pageSize)); Loading @@ -87,11 +98,30 @@ const Apis = () => { }; fetchData(); // Llama a la función fetchData directamente cuando cambien las dependencias }, [currentPage, pageSize]); }, [currentPage, pageSize, sortOrder]); const handleToggleApi = (apf_id, api_id) => { const selectedIndex = selectedApis.findIndex(api => api.api_id === api_id); let newSelected = []; if (selectedIndex === -1) { newSelected = [...selectedApis, { apf_id, api_id }]; } else if (selectedIndex === 0) { newSelected = selectedApis.slice(1); } else if (selectedIndex === selectedApis.length - 1) { newSelected = selectedApis.slice(0, -1); } else if (selectedIndex > 0) { newSelected = [ ...selectedApis.slice(0, selectedIndex), ...selectedApis.slice(selectedIndex + 1) ]; } setSelectedApis(newSelected); }; const handleDeleteClick = (apf_id, api_id) => { setSelectedApi({ apf_id, api_id }) console.log('selectedApis:', selectedApis); setDeleteDialogOpen(true) } Loading @@ -102,8 +132,9 @@ const Apis = () => { const currentPageBeforeDelete = currentPage; // Guarda la página actual antes de la eliminación const { apf_id, api_id } = selectedApi await deleteProviderService(apf_id, api_id) //const { apf_id, api_id } = selectedApi //await deleteProviderService(apf_id, api_id) await deleteProvidersServices(selectedApis); // Carga el mensaje de éxito setDeleteMessage('Api removed'); Loading @@ -121,6 +152,7 @@ const Apis = () => { } setDeleteDialogOpen(false); setSelectedApis([]); setSelectedApi(null); setShowDeleteMessage(true); } catch (error) { Loading Loading @@ -174,6 +206,11 @@ const Apis = () => { } }; const handleClickDate = () => { setIsAscending((prevState) => !prevState); setSortOrder(sortOrder === 'asc' ? 'desc' : 'asc'); }; return ( <Grid container spacing={3}> <Grid item xs={12}> Loading Loading @@ -212,37 +249,36 @@ const Apis = () => { <Table sx={{ minWidth: 650 }} aria-label='APIs table'> <TableHead> <TableRow> <TableCell></TableCell> <TableCell>API name</TableCell> <TableCell>Description</TableCell> <TableCell>AEF</TableCell> <TableCell>Delete API</TableCell> </TableRow> </TableHead> <TableBody> {searchResults.map((api) => ( {searchResults.map((selectedApi) => ( <TableRow key={api.api_id} key={selectedApi.api_id} sx={{ '&:last-of-type td, &:last-of-type th': { border: 0, }, }} > <TableCell> <Checkbox onChange={() => handleToggleApi(selectedApi.apf_id, selectedApi.api_id)} checked={selectedApis.some(api => api.apf_id === selectedApi.apf_id && api.api_id === selectedApi.api_id)} /> </TableCell> <TableCell component='th' scope='row'> <LinkStyled href={`/apis/${api.api_name}`}> {api.api_name} <LinkStyled href={`/apis/${selectedApi.api_name}`}> {selectedApi.api_name} </LinkStyled> </TableCell> <TableCell>{api.description}</TableCell> <TableCell>{api.aef_profiles[0].aef_id}</TableCell> <TableCell> <Button variant='contained' onClick={() => handleDeleteClick(api.apf_id, api.api_id)} > Delete </Button> </TableCell> <TableCell>{selectedApi.description}</TableCell> <TableCell>{selectedApi.aef_profiles[0].aef_id}</TableCell> <TableCell>{selectedApi.onboarding_date}</TableCell> </TableRow> ))} </TableBody> Loading @@ -260,39 +296,59 @@ const Apis = () => { <Table sx={{ minWidth: 650 }} aria-label='APIs table'> <TableHead> <TableRow> <TableCell></TableCell> <TableCell>API name</TableCell> <TableCell>Description</TableCell> <TableCell>AEF</TableCell> <TableCell>Delete API</TableCell> <TableCell> Date <Button aria-label="Sort by date" onClick={handleClickDate} style={{ minWidth: 'auto', padding: 0 }} > {isAscending ? <ArrowDropDownIcon /> : <ArrowDropUpIcon />} </Button> {/* <Menu id="date-order-menu" anchorEl={anchorEl} open={Boolean(anchorEl)} onClose={handleClose} > <MenuItem onClick={() => { handleSortOrderChange('asc'); handleClose(); }}>Ascending</MenuItem> <MenuItem onClick={() => { handleSortOrderChange('desc'); handleClose(); }}>Descending</MenuItem> </Menu> */} </TableCell> </TableRow> </TableHead> <TableBody> {apis.map((api) => ( {apis.map((selectedApi) => ( <TableRow key={api.api_id} key={selectedApi.api_id} sx={{ '&:last-of-type td, &:last-of-type th': { border: 0, }, }} > <TableCell> <Checkbox onChange={() => handleToggleApi(selectedApi.apf_id, selectedApi.api_id)} checked={selectedApis.some(api => api.apf_id === selectedApi.apf_id && api.api_id === selectedApi.api_id)} /> </TableCell> <TableCell component='th' scope='row'> <LinkStyled href={`/apis/${api.api_name}`}> {api.api_name} <LinkStyled href={`/apis/${selectedApi.api_name}`}> {selectedApi.api_name} </LinkStyled> </TableCell> <TableCell>{api.description}</TableCell> <TableCell>{api.aef_profiles[0].aef_id}</TableCell> <TableCell> <Button variant='contained' onClick={() => handleDeleteClick(api.apf_id, api.api_id)} > Delete </Button> </TableCell> <TableCell>{selectedApi.description}</TableCell> <TableCell>{selectedApi.aef_profiles[0].aef_id}</TableCell> <TableCell>{selectedApi.onboarding_date}</TableCell> </TableRow> ))} </TableBody> </Table> </TableContainer> Loading @@ -316,6 +372,13 @@ const Apis = () => { onChange={(event, value) => handlePageChange(value)} /> </Grid> <Grid> <Button variant="contained" color="primary" onClick={handleDeleteClick}> Delete </Button> </Grid> <Grid item> <Select value={pageSize} onChange={handlePageSizeChange}> <MenuItem value={10}>10 per page</MenuItem> Loading @@ -329,7 +392,14 @@ const Apis = () => { <Dialog open={isDeleteDialogOpen} onClose={handleDeleteCancel}> <DialogTitle>Confirm Deletion</DialogTitle> <DialogContent> Are you sure you want to delete the api? Are you sure you want to delete the following apis? <ul> {selectedApis.map(api => ( <li key={api.api_id}> {api.api_id} </li> ))} </ul> </DialogContent> <DialogActions> <Button onClick={handleDeleteCancel}>Cancel</Button> Loading @@ -346,7 +416,7 @@ const Apis = () => { <DialogContent> {errorDeleting ? 'An error occurred while deleting the api.' : 'The api has been successfully deleted.'} : 'The APIs has been successfully deleted.'} </DialogContent> <DialogActions> <Button onClick={handleDeleteMessageAccept} autoFocus> Loading
capif_frontend/src/pages/invokers/index.js +122 −29 File changed.Preview size limit exceeded, changes collapsed. Show changes