latest
This commit is contained in:
		
							parent
							
								
									5bc4dbf40d
								
							
						
					
					
						commit
						6fa8c7e7d3
					
				
							
								
								
									
										39
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										39
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							| @ -8,13 +8,14 @@ | |||||||
|       "name": "log", |       "name": "log", | ||||||
|       "version": "0.1.0", |       "version": "0.1.0", | ||||||
|       "dependencies": { |       "dependencies": { | ||||||
|         "@emotion/react": "^11.11.3", |         "@emotion/react": "^11.14.0", | ||||||
|         "@emotion/styled": "^11.11.0", |         "@emotion/styled": "^11.14.0", | ||||||
|         "@fortawesome/fontawesome-svg-core": "^6.7.2", |         "@fortawesome/fontawesome-svg-core": "^6.7.2", | ||||||
|         "@fortawesome/free-solid-svg-icons": "^6.7.2", |         "@fortawesome/free-solid-svg-icons": "^6.7.2", | ||||||
|         "@fortawesome/react-fontawesome": "^0.2.2", |         "@fortawesome/react-fontawesome": "^0.2.2", | ||||||
|         "@mui/icons-material": "^5.15.20", |         "@material-ui/icons": "^4.11.3", | ||||||
|         "@mui/material": "^5.15.20", |         "@mui/icons-material": "^5.17.1", | ||||||
|  |         "@mui/material": "^5.17.1", | ||||||
|         "@mui/styles": "^5.16.4", |         "@mui/styles": "^5.16.4", | ||||||
|         "@mui/x-charts": "^7.6.2", |         "@mui/x-charts": "^7.6.2", | ||||||
|         "@mui/x-data-grid": "^7.6.2", |         "@mui/x-data-grid": "^7.6.2", | ||||||
| @ -26,6 +27,7 @@ | |||||||
|         "ajv-keywords": "^3.5.2", |         "ajv-keywords": "^3.5.2", | ||||||
|         "axios": "^1.6.7", |         "axios": "^1.6.7", | ||||||
|         "chart.js": "^4.4.9", |         "chart.js": "^4.4.9", | ||||||
|  |         "file-saver": "^2.0.5", | ||||||
|         "mdb-react-ui-kit": "^7.1.0", |         "mdb-react-ui-kit": "^7.1.0", | ||||||
|         "moment": "^2.30.1", |         "moment": "^2.30.1", | ||||||
|         "react": "^18.2.0", |         "react": "^18.2.0", | ||||||
| @ -3764,6 +3766,29 @@ | |||||||
|       "integrity": "sha512-Vo+PSpZG2/fmgmiNzYK9qWRh8h/CHrwD0mo1h1DzL4yzHNSfWYujGTYsWGreD000gcgmZ7K4Ys6Tx9TxtsKdDw==", |       "integrity": "sha512-Vo+PSpZG2/fmgmiNzYK9qWRh8h/CHrwD0mo1h1DzL4yzHNSfWYujGTYsWGreD000gcgmZ7K4Ys6Tx9TxtsKdDw==", | ||||||
|       "license": "MIT" |       "license": "MIT" | ||||||
|     }, |     }, | ||||||
|  |     "node_modules/@material-ui/icons": { | ||||||
|  |       "version": "4.11.3", | ||||||
|  |       "resolved": "https://registry.npmjs.org/@material-ui/icons/-/icons-4.11.3.tgz", | ||||||
|  |       "integrity": "sha512-IKHlyx6LDh8n19vzwH5RtHIOHl9Tu90aAAxcbWME6kp4dmvODM3UvOHJeMIDzUbd4muuJKHmlNoBN+mDY4XkBA==", | ||||||
|  |       "license": "MIT", | ||||||
|  |       "dependencies": { | ||||||
|  |         "@babel/runtime": "^7.4.4" | ||||||
|  |       }, | ||||||
|  |       "engines": { | ||||||
|  |         "node": ">=8.0.0" | ||||||
|  |       }, | ||||||
|  |       "peerDependencies": { | ||||||
|  |         "@material-ui/core": "^4.0.0", | ||||||
|  |         "@types/react": "^16.8.6 || ^17.0.0", | ||||||
|  |         "react": "^16.8.0 || ^17.0.0", | ||||||
|  |         "react-dom": "^16.8.0 || ^17.0.0" | ||||||
|  |       }, | ||||||
|  |       "peerDependenciesMeta": { | ||||||
|  |         "@types/react": { | ||||||
|  |           "optional": true | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |     }, | ||||||
|     "node_modules/@mui/core-downloads-tracker": { |     "node_modules/@mui/core-downloads-tracker": { | ||||||
|       "version": "5.17.1", |       "version": "5.17.1", | ||||||
|       "resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-5.17.1.tgz", |       "resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-5.17.1.tgz", | ||||||
| @ -9931,6 +9956,12 @@ | |||||||
|         "webpack": "^4.0.0 || ^5.0.0" |         "webpack": "^4.0.0 || ^5.0.0" | ||||||
|       } |       } | ||||||
|     }, |     }, | ||||||
|  |     "node_modules/file-saver": { | ||||||
|  |       "version": "2.0.5", | ||||||
|  |       "resolved": "https://registry.npmjs.org/file-saver/-/file-saver-2.0.5.tgz", | ||||||
|  |       "integrity": "sha512-P9bmyZ3h/PRG+Nzga+rbdI4OEpNDzAVyy74uVO9ATgzLK6VtAsYybF/+TOCvrc0MO793d6+42lLyZTw7/ArVzA==", | ||||||
|  |       "license": "MIT" | ||||||
|  |     }, | ||||||
|     "node_modules/filelist": { |     "node_modules/filelist": { | ||||||
|       "version": "1.0.4", |       "version": "1.0.4", | ||||||
|       "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.4.tgz", |       "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.4.tgz", | ||||||
|  | |||||||
							
								
								
									
										10
									
								
								package.json
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								package.json
									
									
									
									
									
								
							| @ -3,13 +3,14 @@ | |||||||
|   "version": "0.1.0", |   "version": "0.1.0", | ||||||
|   "private": true, |   "private": true, | ||||||
|   "dependencies": { |   "dependencies": { | ||||||
|     "@emotion/react": "^11.11.3", |     "@emotion/react": "^11.14.0", | ||||||
|     "@emotion/styled": "^11.11.0", |     "@emotion/styled": "^11.14.0", | ||||||
|     "@fortawesome/fontawesome-svg-core": "^6.7.2", |     "@fortawesome/fontawesome-svg-core": "^6.7.2", | ||||||
|     "@fortawesome/free-solid-svg-icons": "^6.7.2", |     "@fortawesome/free-solid-svg-icons": "^6.7.2", | ||||||
|     "@fortawesome/react-fontawesome": "^0.2.2", |     "@fortawesome/react-fontawesome": "^0.2.2", | ||||||
|     "@mui/icons-material": "^5.15.20", |     "@material-ui/icons": "^4.11.3", | ||||||
|     "@mui/material": "^5.15.20", |     "@mui/icons-material": "^5.17.1", | ||||||
|  |     "@mui/material": "^5.17.1", | ||||||
|     "@mui/styles": "^5.16.4", |     "@mui/styles": "^5.16.4", | ||||||
|     "@mui/x-charts": "^7.6.2", |     "@mui/x-charts": "^7.6.2", | ||||||
|     "@mui/x-data-grid": "^7.6.2", |     "@mui/x-data-grid": "^7.6.2", | ||||||
| @ -21,6 +22,7 @@ | |||||||
|     "ajv-keywords": "^3.5.2", |     "ajv-keywords": "^3.5.2", | ||||||
|     "axios": "^1.6.7", |     "axios": "^1.6.7", | ||||||
|     "chart.js": "^4.4.9", |     "chart.js": "^4.4.9", | ||||||
|  |     "file-saver": "^2.0.5", | ||||||
|     "mdb-react-ui-kit": "^7.1.0", |     "mdb-react-ui-kit": "^7.1.0", | ||||||
|     "moment": "^2.30.1", |     "moment": "^2.30.1", | ||||||
|     "react": "^18.2.0", |     "react": "^18.2.0", | ||||||
|  | |||||||
| @ -1,117 +1,160 @@ | |||||||
|  | // import axios from 'axios';
 | ||||||
|  | 
 | ||||||
|  | // // Use the same environment variable name consistently
 | ||||||
|  | // const BASE_URL =   process.env.REACT_APP_API_BASE_URL;
 | ||||||
|  | // console.log('API Base URL:', BASE_URL);
 | ||||||
|  | // // Enhanced token service
 | ||||||
|  | // export const getToken = () => {
 | ||||||
|  | //   // Check multiple possible storage locations
 | ||||||
|  | //   return localStorage.getItem('token') || 
 | ||||||
|  | //          sessionStorage.getItem('token') || 
 | ||||||
|  | //          document.cookie.split('; ').find(row => row.startsWith('token='))?.split('=')[1];
 | ||||||
|  | // };
 | ||||||
|  | 
 | ||||||
|  | // const apiClient = axios.create({
 | ||||||
|  | //   baseURL: BASE_URL,
 | ||||||
|  | //   headers: {
 | ||||||
|  | //     'Content-Type': 'application/json',
 | ||||||
|  | //   },
 | ||||||
|  | // });
 | ||||||
|  | 
 | ||||||
|  | // // Enhanced request interceptor
 | ||||||
|  | // apiClient.interceptors.request.use(
 | ||||||
|  | //   (config) => {
 | ||||||
|  | //     const token = getToken();
 | ||||||
|  | //     if (token) {
 | ||||||
|  | //       config.headers['Authorization'] = `Bearer ${token}`;
 | ||||||
|  | //       // Add debug logging
 | ||||||
|  | //       console.debug('[API] Request with token:', {
 | ||||||
|  | //         url: config.url,
 | ||||||
|  | //         headers: config.headers
 | ||||||
|  | //       });
 | ||||||
|  | //     } else {
 | ||||||
|  | //       console.warn('[API] No token available for request:', config.url);
 | ||||||
|  | //     }
 | ||||||
|  | //     return config;
 | ||||||
|  | //   },
 | ||||||
|  | //   (error) => {
 | ||||||
|  | //     console.error('[API] Request interceptor error:', error);
 | ||||||
|  | //     return Promise.reject(error);
 | ||||||
|  | //   }
 | ||||||
|  | // );
 | ||||||
|  | 
 | ||||||
|  | // // Enhanced response interceptor
 | ||||||
|  | // apiClient.interceptors.response.use(
 | ||||||
|  | //   (response) => {
 | ||||||
|  | //     console.debug('[API] Successful response:', {
 | ||||||
|  | //       url: response.config.url,
 | ||||||
|  | //       status: response.status,
 | ||||||
|  | //       data: response.data
 | ||||||
|  | //     });
 | ||||||
|  | //     return response;
 | ||||||
|  | //   },
 | ||||||
|  | //   (error) => {
 | ||||||
|  | //     const originalRequest = error.config;
 | ||||||
|  |      | ||||||
|  | //     // Debug logging
 | ||||||
|  | //     console.error('[API] Error response:', {
 | ||||||
|  | //       url: originalRequest.url,
 | ||||||
|  | //       status: error.response?.status,
 | ||||||
|  | //       data: error.response?.data
 | ||||||
|  | //     });
 | ||||||
|  | 
 | ||||||
|  | //     // Handle 401 specifically
 | ||||||
|  | //     if (error.response?.status === 401 && !originalRequest._retry) {
 | ||||||
|  | //       originalRequest._retry = true;
 | ||||||
|  | //       console.warn('[API] Attempting token refresh...');
 | ||||||
|  | //       // Add your token refresh logic here if needed
 | ||||||
|  | //     }
 | ||||||
|  |      | ||||||
|  | //     return Promise.reject(error);
 | ||||||
|  | //   }
 | ||||||
|  | // );
 | ||||||
|  | 
 | ||||||
|  | // // API methods
 | ||||||
|  | // const apiService = {
 | ||||||
|  | //   get: (url, params, options = {}) => 
 | ||||||
|  | //     apiClient.get(url, { ...options, params }).catch(handleError),
 | ||||||
|  |    | ||||||
|  | //   post: (url, body = {}, options = {}) => 
 | ||||||
|  | //     apiClient.post(url, body, options).catch(handleError),
 | ||||||
|  |    | ||||||
|  | //   put: (url, body = {}, options = {}) => 
 | ||||||
|  | //     apiClient.put(url, body, options).catch(handleError),
 | ||||||
|  |    | ||||||
|  | //   delete: (url, options = {}) => 
 | ||||||
|  | //     apiClient.delete(url, options).catch(handleError),
 | ||||||
|  |    | ||||||
|  | //   // Add patch if needed
 | ||||||
|  | //   patch: (url, body = {}, options = {}) =>
 | ||||||
|  | //     apiClient.patch(url, body, options).catch(handleError)
 | ||||||
|  | // };
 | ||||||
|  | 
 | ||||||
|  | // // Enhanced error handler
 | ||||||
|  | // const handleError = (error) => {
 | ||||||
|  | //   // Your existing error handling logic
 | ||||||
|  | //   // ...
 | ||||||
|  | // };
 | ||||||
|  | 
 | ||||||
|  | // // Specific API endpoints
 | ||||||
|  | // export const getSubmenuItems = async (id) => {
 | ||||||
|  | //   try {
 | ||||||
|  | //     const response = await apiService.get(`/api1/submenu1/${id}`);
 | ||||||
|  | //     return response.data;
 | ||||||
|  | //   } catch (error) {
 | ||||||
|  | //     console.error('Error fetching submenu items:', error);
 | ||||||
|  | //     throw error; // Re-throw for component-level handling
 | ||||||
|  | //   }
 | ||||||
|  | // };
 | ||||||
|  | 
 | ||||||
|  | // // Export the configured service
 | ||||||
|  | // export default apiService;
 | ||||||
|  | 
 | ||||||
| import axios from 'axios'; | import axios from 'axios'; | ||||||
|  import { getToken } from '../../src/utils/tokenService';  |  | ||||||
| 
 | 
 | ||||||
| const BASE_URL = process.env.REACT_APP_API_BASE_URL; | const BASE_URL = process.env.REACT_APP_API_BASE_URL ; | ||||||
| 
 | 
 | ||||||
| const apiClient = axios.create({ | const apiService = axios.create({ | ||||||
|   baseURL: BASE_URL, |   baseURL: BASE_URL, | ||||||
|   headers: { |   timeout: 30000, | ||||||
|     'Content-Type': 'application/json', |  | ||||||
|   }, |  | ||||||
| }); | }); | ||||||
| // Add a request interceptor to include Authorization header
 | 
 | ||||||
| apiClient.interceptors.request.use( | // Request interceptor for auth token
 | ||||||
|  | apiService.interceptors.request.use( | ||||||
|   (config) => { |   (config) => { | ||||||
|     const token = getToken(); |     const token = localStorage.getItem('authToken'); | ||||||
|     if (token) { |     if (token) { | ||||||
|       console.log("token: ",token); |       config.headers.Authorization = `Bearer ${token}`; | ||||||
|       config.headers['Authorization'] = `Bearer ${token}`; |  | ||||||
|     } |     } | ||||||
|     return config; |     return config; | ||||||
|   }, |   }, | ||||||
|   (error) => Promise.reject(error) |   (error) => { | ||||||
|  |     return Promise.reject(error); | ||||||
|  |   } | ||||||
| ); | ); | ||||||
| 
 | 
 | ||||||
| // Generic error handler function
 | // Response interceptor
 | ||||||
| const handleError = (error) => { | apiService.interceptors.response.use( | ||||||
|   let errorMessage = 'An unknown error occurred'; |   (response) => response, | ||||||
|   console.error('Error Details:', error); |   (error) => { | ||||||
| 
 |     if (error.response?.status === 401) { | ||||||
|   if (error.response) { |       localStorage.removeItem('authToken'); | ||||||
|     // HTTP errors
 |       window.location.href = '/login'; | ||||||
|     switch (error.response.status) { |  | ||||||
|       case 401: |  | ||||||
|         errorMessage = 'Unauthorized - Please login again.'; |  | ||||||
|         break; |  | ||||||
|       case 403: |  | ||||||
|         errorMessage = 'Forbidden - Access denied.'; |  | ||||||
|         break; |  | ||||||
|       case 404: |  | ||||||
|         errorMessage = 'Service not found.'; |  | ||||||
|         break; |  | ||||||
|       case 408: |  | ||||||
|         errorMessage = 'Request timed out.'; |  | ||||||
|         break; |  | ||||||
|       case 500: |  | ||||||
|         errorMessage = 'Internal server error.'; |  | ||||||
|         break; |  | ||||||
|       default: |  | ||||||
|         errorMessage = `Unexpected error: ${error.response.statusText || 'Server Error'}`; |  | ||||||
|     } |     } | ||||||
|   } else if (error.request) { |     return Promise.reject(error); | ||||||
|     // No response received
 |  | ||||||
|     errorMessage = 'No response from server. Please check your connection.'; |  | ||||||
|   } else { |  | ||||||
|     // Other errors
 |  | ||||||
|     errorMessage = error.message || 'An unexpected error occurred.'; |  | ||||||
|   } |   } | ||||||
|  | ); | ||||||
| 
 | 
 | ||||||
|   return Promise.reject(errorMessage); // Return error message as rejected promise
 | // Add downloadFile method
 | ||||||
|  | apiService.downloadFile = async (url, data) => { | ||||||
|  |   try { | ||||||
|  |     const response = await apiService.post(url, data, { | ||||||
|  |       responseType: 'blob', | ||||||
|  |     }); | ||||||
|  |     return response.data; | ||||||
|  |   } catch (error) { | ||||||
|  |     throw error; | ||||||
|  |   } | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| // Define the reusable methods
 | export default apiService; | ||||||
| // const apiService = {
 |  | ||||||
| //   get: (url, params) =>
 |  | ||||||
| //     apiClient
 |  | ||||||
| //       .get(url, { params: params || {} })
 |  | ||||||
| //       .catch(handleError), // Attach error handler
 |  | ||||||
| //   post: (url, body = {}) =>
 |  | ||||||
| //     apiClient
 |  | ||||||
| //       .post(url, body)
 |  | ||||||
| //       .catch(handleError), // Attach error handler
 |  | ||||||
| //   put: (url, body = {}) =>
 |  | ||||||
| //     apiClient
 |  | ||||||
| //       .put(url, body)
 |  | ||||||
| //       .catch(handleError), // Attach error handler
 |  | ||||||
| //   delete: (url) =>
 |  | ||||||
| //     apiClient
 |  | ||||||
| //       .delete(url)
 |  | ||||||
| //       .catch(handleError), // Attach error handler
 |  | ||||||
| // };
 |  | ||||||
| 
 |  | ||||||
| const apiService = { |  | ||||||
|   get: (url, params) => |  | ||||||
|     apiClient |  | ||||||
|       .get(url, { params: params || {} }) |  | ||||||
|       .catch(handleError), // Attach error handler
 |  | ||||||
| 
 |  | ||||||
|   post: (url, body = {}, options = {}) => |  | ||||||
|     apiClient |  | ||||||
|       .post(url, body, options) // Pass options such as headers
 |  | ||||||
|       .catch(handleError), // Attach error handler
 |  | ||||||
| 
 |  | ||||||
|   put: (url, body = {}, options = {}) => |  | ||||||
|     apiClient |  | ||||||
|       .put(url, body, options) // Pass options such as headers
 |  | ||||||
|       .catch(handleError), // Attach error handler
 |  | ||||||
| 
 |  | ||||||
|   delete: (url, options = {}) => |  | ||||||
|     apiClient |  | ||||||
|       .delete(url, options) // Pass options such as headers
 |  | ||||||
|       .catch(handleError), // Attach error handler
 |  | ||||||
| }; |  | ||||||
| // Add at the bottom of APIService.js
 |  | ||||||
| 
 |  | ||||||
| export const getSubmenuItems = async (id) => { |  | ||||||
|   const response = await apiService.get(`/api1/submenu1/${id}`); |  | ||||||
|   return response.data;  |  | ||||||
| }; |  | ||||||
| export const addSubmenuItem = async (menuId, submenuData) => { |  | ||||||
|   const response = await apiService.post(`/api1/menu/${menuId}/submenu`, submenuData); |  | ||||||
|   return response.data; |  | ||||||
| }; |  | ||||||
| export const updateMenuItem = (id, formData) => apiService.put(`/api1/submenu1/${id}`, formData); |  | ||||||
| export const deleteMenuItem = (id) => apiService.delete(`/api1/menu/${id}`); |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| export default apiService; |  | ||||||
							
								
								
									
										22
									
								
								src/ApiServices/AddReportSQLBuilderAPI.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								src/ApiServices/AddReportSQLBuilderAPI.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,22 @@ | |||||||
|  | import axios from 'axios'; | ||||||
|  | 
 | ||||||
|  | export const addSQLReport = async (formData) => { | ||||||
|  |   try { | ||||||
|  |     const token = localStorage.getItem('authToken'); | ||||||
|  |     const response = await axios.post( | ||||||
|  |       `${process.env.REACT_APP_API_BASE_URL}/Rpt_builder2/Rpt_builder2`, | ||||||
|  |       formData, | ||||||
|  |       { | ||||||
|  |         headers: { | ||||||
|  |           'Content-Type': 'application/json', | ||||||
|  |           Authorization: `Bearer ${token}` | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  |     ); | ||||||
|  |     return response.data; | ||||||
|  |   } catch (error) { | ||||||
|  |     console.error('Error adding SQL report:', error); | ||||||
|  |     throw error; | ||||||
|  |   } | ||||||
|  | }; | ||||||
|  | 
 | ||||||
							
								
								
									
										17
									
								
								src/ApiServices/DeleteReportSQLAPI.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								src/ApiServices/DeleteReportSQLAPI.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,17 @@ | |||||||
|  | import apiService from '../APIRequestService/APIServices'; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | export const deleteReportSQL = async (id) => { | ||||||
|  |     if (!id) { | ||||||
|  |         throw new Error("ID is required for deletion."); | ||||||
|  |     } | ||||||
|  |     const BASE_URL = `${process.env.REACT_APP_API_BASE_URL}/Rpt_builder2/Rpt_builder2/${id}`; | ||||||
|  |     try { | ||||||
|  |         const response = await apiService.delete(BASE_URL); | ||||||
|  |         console.log("Delete response:", response.data); | ||||||
|  |         return response.data; | ||||||
|  |     } catch (error) { | ||||||
|  |         console.error("Error in API call:", error.response || error.message); | ||||||
|  |         throw error; | ||||||
|  |     } | ||||||
|  | }; | ||||||
							
								
								
									
										134
									
								
								src/ApiServices/ReportBuilderService.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										134
									
								
								src/ApiServices/ReportBuilderService.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,134 @@ | |||||||
|  | import apiService from '../APIRequestService/APIServices'; | ||||||
|  | 
 | ||||||
|  | const API_BASE_URL = 'api'; | ||||||
|  | 
 | ||||||
|  | const ReportBuilderService = { | ||||||
|  |   getById: (id) => apiService.get(`${API_BASE_URL}/edit-report/${id}`), | ||||||
|  | 
 | ||||||
|  |   buildReport: (id) => { | ||||||
|  |     const params = { id }; | ||||||
|  |     return apiService.get(`${API_BASE_URL}/build_report`, params); | ||||||
|  |   }, | ||||||
|  | 
 | ||||||
|  |   getAll: (moduleId, page = 0, size = 1000) => { | ||||||
|  |     const params = { page, size, moduleId }; | ||||||
|  |     return apiService.get(`${API_BASE_URL}/report-builder-by-id`, params); | ||||||
|  |   }, | ||||||
|  | 
 | ||||||
|  |   create: (fbHeader, moduleId) => { | ||||||
|  |     const params = { moduleId }; | ||||||
|  |     return apiService.post(`${API_BASE_URL}/report-builder`, fbHeader, { params }); | ||||||
|  |   }, | ||||||
|  | 
 | ||||||
|  |   createservicereport: (fbHeader, moduleId) => { | ||||||
|  |     const params = { moduleId }; | ||||||
|  |     return apiService.post(`${API_BASE_URL}/report-builder_service`, fbHeader, { params }); | ||||||
|  |   }, | ||||||
|  | 
 | ||||||
|  |   createQuery: (reportId) => { | ||||||
|  |     const params = { reportId }; | ||||||
|  |     return apiService.post(`${API_BASE_URL}/add-master-query`, {}, { params }); | ||||||
|  |   }, | ||||||
|  | 
 | ||||||
|  |   update: (id, functionRegister) => { | ||||||
|  |     return apiService.put(`${API_BASE_URL}/add-master-query/${id}`, functionRegister); | ||||||
|  |   }, | ||||||
|  | 
 | ||||||
|  |   updateservicereport: (id, functionRegister) => { | ||||||
|  |     return apiService.put(`${API_BASE_URL}/updatereport/${id}`, functionRegister); | ||||||
|  |   }, | ||||||
|  | 
 | ||||||
|  |   getMasterQuery: (id) => apiService.get(`${API_BASE_URL}/master-query/${id}`), | ||||||
|  | 
 | ||||||
|  |   getMasterData: (query) => { | ||||||
|  |     const params = { sql_query: query }; | ||||||
|  |     return apiService.get(`${API_BASE_URL}/master-query-data`, params); | ||||||
|  |   }, | ||||||
|  | 
 | ||||||
|  |   report2: (serviceName) => apiService.post(`${API_BASE_URL}/add-report`, serviceName), | ||||||
|  | 
 | ||||||
|  |   saveq: (data) => apiService.post('FndQuery/query', data), | ||||||
|  | 
 | ||||||
|  |   getall: () => apiService.get('FndQuery/query'), | ||||||
|  | 
 | ||||||
|  |   getreportdata: (apiName) => { | ||||||
|  |     const url = `${API_BASE_URL}/${apiName}`; | ||||||
|  |     return apiService.get(url); | ||||||
|  |   }, | ||||||
|  | 
 | ||||||
|  |   getDatabase: () => apiService.get('SqlworkbenchSqlcont/sql'), | ||||||
|  | 
 | ||||||
|  |   getTableListn: (val) => apiService.get(`Table_list/${val}`),  // table list
 | ||||||
|  | 
 | ||||||
|  |   getcolListn: (val, val1) => apiService.get(`Table_list/${val}/${val1}`), // column list
 | ||||||
|  | 
 | ||||||
|  |   getColumnList: (tableSchema, tables) => { | ||||||
|  |     const params = { str: tables.join(',') }; | ||||||
|  |     return apiService.get(`${API_BASE_URL}/AllTable_list/${tableSchema}`, { params }); | ||||||
|  |   }, | ||||||
|  | 
 | ||||||
|  |   getAllColumnsFromAllTables: (tableNames) => { | ||||||
|  |     // If tableNames is an array, join it with commas
 | ||||||
|  |     const tables = Array.isArray(tableNames) ? tableNames.join(',') : tableNames; | ||||||
|  |     return apiService.get(`Alias_Table_list/${tables}`); | ||||||
|  |   }, | ||||||
|  | 
 | ||||||
|  |   getcollist: (table) => apiService.get(`fndMenu/loadcolumn/${table}`), | ||||||
|  | 
 | ||||||
|  |   createdb: (data) => apiService.post('SqlworkbenchSqlcont/sql', data), | ||||||
|  | 
 | ||||||
|  |   updateSqlModel: (id, sqlModel) => apiService.put(`SqlworkbenchSqlcont/sql/${id}`, sqlModel), | ||||||
|  | 
 | ||||||
|  |   getSqlModelById: (id) => apiService.get(`SqlworkbenchSqlcont/sql/${id}`), | ||||||
|  | 
 | ||||||
|  |   deleteSqlModel: (id) => apiService.delete(`SqlworkbenchSqlcont/sql/${id}`), | ||||||
|  | 
 | ||||||
|  |   getallentity: () => apiService.get(`${API_BASE_URL}/report-builder`), | ||||||
|  | 
 | ||||||
|  |   saveData: (data) => apiService.post('Rpt_builder/Rpt_builder', data), | ||||||
|  | 
 | ||||||
|  |   getDetails: () => apiService.get('Rpt_builder/Rpt_builder'), | ||||||
|  | 
 | ||||||
|  |   getDetailsById: (id) => apiService.get(`Rpt_builder/Rpt_builder/${id}`), | ||||||
|  | 
 | ||||||
|  |   deleteById: (id) => apiService.delete(`Rpt_builder/Rpt_builder/${id}`), | ||||||
|  | 
 | ||||||
|  |   updateData: (data, id) => apiService.put(`Rpt_builder/Rpt_builder/${id}`, data), | ||||||
|  | 
 | ||||||
|  |   saverbData: (data) => apiService.post('Rpt_builder2/Rpt_builder2', data), | ||||||
|  | 
 | ||||||
|  |   getrbDetails: () => apiService.get('Rpt_builder2/Rpt_builder2'), | ||||||
|  | 
 | ||||||
|  |   getrbDetailsById: (id) => apiService.get(`Rpt_builder2/Rpt_builder2/${id}`), | ||||||
|  | 
 | ||||||
|  |   deletrbById: (id) => apiService.delete(`Rpt_builder2/Rpt_builder2/${id}`), | ||||||
|  | 
 | ||||||
|  |   updaterbData: (data, id) => apiService.put(`Rpt_builder2/Rpt_builder2/${id}`, data), | ||||||
|  | 
 | ||||||
|  |   updaterbLineData: (data, id) => apiService.put(`Rpt_builder2_lines/update/${id}`, data), | ||||||
|  | 
 | ||||||
|  |   getrbLineDetailsById: (id) => apiService.get(`Rpt_builder2_lines/Rpt_builder2_lines/${id}`), | ||||||
|  | 
 | ||||||
|  |   getStdParamById: (id) => apiService.get(`Rpt_builder2/html/build_report2/${id}`), | ||||||
|  | 
 | ||||||
|  |   getcolumnDetailsByurl: (url) => apiService.get(`Rpt_builder2_lines/geturlkeybyurl?url=${url}`), | ||||||
|  | 
 | ||||||
|  |   getAllDetailsByurl: (url) => apiService.get(`Rpt_builder2_lines/fetch_data_url?url=${url}`), | ||||||
|  | 
 | ||||||
|  |   downloadFile: async (format, dataList, name) => { | ||||||
|  |     const url = `${API_BASE_URL}/rbbuilder/fileconverter/downloadFile/${format}`; | ||||||
|  |     try { | ||||||
|  |       const fileData = await apiService.post(url, dataList, { responseType: 'blob' }); | ||||||
|  |       const blob = new Blob([fileData], { type: 'application/octet-stream' }); | ||||||
|  |       const fileName = name ? `${name}.${format}` : `download.${format}`; | ||||||
|  |       const link = document.createElement('a'); | ||||||
|  |       link.href = window.URL.createObjectURL(blob); | ||||||
|  |       link.download = fileName; | ||||||
|  |       link.click(); | ||||||
|  |     } catch (error) { | ||||||
|  |       console.error('Error downloading file:', error); | ||||||
|  |     } | ||||||
|  |   }, | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | export default ReportBuilderService; | ||||||
							
								
								
									
										49
									
								
								src/ApiServices/ReportRunnerAPI.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										49
									
								
								src/ApiServices/ReportRunnerAPI.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,49 @@ | |||||||
|  | import apiService from '../APIRequestService/APIServices'; | ||||||
|  | import { saveAs } from 'file-saver'; | ||||||
|  | 
 | ||||||
|  | // Function to run a specific report
 | ||||||
|  | export const runReport = async (reportId) => { | ||||||
|  |   try { | ||||||
|  |     const response = await apiService.get(`Rpt_builder2/Rpt_builder2/${reportId}`); | ||||||
|  |     return response.data; | ||||||
|  |   } catch (error) { | ||||||
|  |     console.error("Error running report:", error); | ||||||
|  |     throw error; | ||||||
|  |   } | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | // Function to fetch all reports
 | ||||||
|  | export const fetchAllReportsApi = async () => { | ||||||
|  |   try { | ||||||
|  |     const response = await apiService.get('Rpt_builder2/Rpt_builder2'); | ||||||
|  |     return response.data; | ||||||
|  |   } catch (error) { | ||||||
|  |     console.error("Error fetching reports:", error); | ||||||
|  |     throw error; | ||||||
|  |   } | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | // Function to fetch standard parameters
 | ||||||
|  | export const fetchStandardParameters = async (url) => { | ||||||
|  |   try { | ||||||
|  |     const response = await apiService.get(`Rpt_builder2_lines/fetch_data_url?url=${encodeURIComponent(url)}`); | ||||||
|  |     return response.data; | ||||||
|  |   } catch (error) { | ||||||
|  |     console.error("Error fetching parameters:", error); | ||||||
|  |     throw error; | ||||||
|  |   } | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | // File download function
 | ||||||
|  | export const downloadFile = async (format, dataList, name) => { | ||||||
|  |   try { | ||||||
|  |     const blob = await apiService.downloadFile( | ||||||
|  |       `rbbuilder/fileconverter/downloadFile/${format}`, | ||||||
|  |       dataList | ||||||
|  |     ); | ||||||
|  |     saveAs(blob, `${name}.${format}`); | ||||||
|  |   } catch (error) { | ||||||
|  |     console.error('Error downloading file:', error); | ||||||
|  |     throw error; | ||||||
|  |   } | ||||||
|  | }; | ||||||
							
								
								
									
										21
									
								
								src/ApiServices/ReportSQLBuilderAPI.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								src/ApiServices/ReportSQLBuilderAPI.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,21 @@ | |||||||
|  | // src/api/ReportSqlBuilderApi.js
 | ||||||
|  | 
 | ||||||
|  | import apiService from '../APIRequestService/APIServices';// Assuming apiService is in the same directory
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | const BASE_URL = `${process.env.REACT_APP_API_BASE_URL}/Rpt_builder2/Rpt_builder2`; | ||||||
|  | console.log("BASE_URL:", BASE_URL); // Log the base URL for debugging
 | ||||||
|  | const ReportSqlBuilderApi = { | ||||||
|  |   fetchUserDetails: async () => { | ||||||
|  |     try { | ||||||
|  |       const response = await apiService.get(BASE_URL); | ||||||
|  |       return response.data; // Return only the data part of the response
 | ||||||
|  |     } catch (error) { | ||||||
|  |       throw error; // Let the error be handled by the calling component
 | ||||||
|  |     } | ||||||
|  |   }, | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | export default ReportSqlBuilderApi; | ||||||
|  | 
 | ||||||
							
								
								
									
										0
									
								
								src/ApiServices/SQLWorksheetAPI.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										0
									
								
								src/ApiServices/SQLWorksheetAPI.js
									
									
									
									
									
										Normal file
									
								
							
							
								
								
									
										23
									
								
								src/ApiServices/SystemparameterApi.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										23
									
								
								src/ApiServices/SystemparameterApi.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,23 @@ | |||||||
|  | import apiService from '../APIRequestService/APIService'; | ||||||
|  | 
 | ||||||
|  | export const getSysParameter = async (id) => { | ||||||
|  |     try { | ||||||
|  |       const response = await apiService.get(`/sysparam/getSysParams/${id}`); | ||||||
|  |       return response.data; // Return only the data part of the response
 | ||||||
|  |     } catch (error) { | ||||||
|  |       throw error; // Let the error be handled by the calling component
 | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  | export const addSysParameter = async (formdata) => { | ||||||
|  |     try { | ||||||
|  |       const response = await apiService.put(`/sysparam/updateSysParams/${1}`,formdata); | ||||||
|  |       console.log("add response data ",response.data) | ||||||
|  |       return response.data; // Return only the data part of the response
 | ||||||
|  |     } catch (error) { | ||||||
|  |       throw error; // Let the error be handled by the calling component
 | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |    | ||||||
|  | 
 | ||||||
							
								
								
									
										16
									
								
								src/ApiServices/UpdateReportSQLBuilderAPI.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								src/ApiServices/UpdateReportSQLBuilderAPI.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,16 @@ | |||||||
|  | import apiService from '../APIRequestService/APIServices'; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | export const UpdateReportSQLBuilder = async (id,formData) => { | ||||||
|  |     const BASE_URL = `${process.env.REACT_APP_API_BASE_URL}/Rpt_builder2/Rpt_builder2/${id}`; | ||||||
|  |     try { | ||||||
|  |       const response = await apiService.put(BASE_URL, formData); | ||||||
|  |       console.log("update response: ",response.data); | ||||||
|  |        | ||||||
|  |       return response.data; // Return only the data part of the response
 | ||||||
|  |     } catch (error) { | ||||||
|  |       throw error; // Let the error be handled by the calling component
 | ||||||
|  |     } | ||||||
|  |   } | ||||||
							
								
								
									
										24
									
								
								src/ApiServices/reportBaseUrlAddAPI.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								src/ApiServices/reportBaseUrlAddAPI.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,24 @@ | |||||||
|  | // reportBaseUrlAddAPI.js
 | ||||||
|  | import apiService from '../APIRequestService/APIServices'; | ||||||
|  | 
 | ||||||
|  | // Function to handle the Add API request
 | ||||||
|  | export const addReport = async (formData) => { | ||||||
|  |   try { | ||||||
|  |     const response = await apiService.post('/Rpt_builder2/Rpt_builder2', formData); | ||||||
|  |      | ||||||
|  |     console.log("add Report response: ",response) | ||||||
|  |     return response; // Return the response to handle success in the component
 | ||||||
|  |   } catch (error) { | ||||||
|  |     throw error; // Re-throw error to handle it in the calling component
 | ||||||
|  |   } | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | // Function to fetch keys from URL
 | ||||||
|  | export const getKeysFromUrl = async (url) => { | ||||||
|  |   try { | ||||||
|  |     const response = await apiService.get(`/api/report-builder/columns`, { url }); | ||||||
|  |     return response; // Return the response for further processing
 | ||||||
|  |   } catch (error) { | ||||||
|  |     throw error; // Re-throw error to handle it in the calling component
 | ||||||
|  |   } | ||||||
|  | }; | ||||||
							
								
								
									
										35
									
								
								src/ApiServices/reportBaseUrlAllAPI.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								src/ApiServices/reportBaseUrlAllAPI.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,35 @@ | |||||||
|  | import axios from 'axios'; | ||||||
|  | 
 | ||||||
|  | // Create axios instance
 | ||||||
|  | const apiService = axios.create({ | ||||||
|  |   baseURL: process.env.REACT_APP_API_BASE_URL, | ||||||
|  | }); | ||||||
|  | 
 | ||||||
|  | // Add request interceptor to inject the token
 | ||||||
|  | apiService.interceptors.request.use( | ||||||
|  |   (config) => { | ||||||
|  |     const token = localStorage.getItem('authToken'); | ||||||
|  |     if (token) { | ||||||
|  |       config.headers.Authorization = `Bearer ${token}`; | ||||||
|  |     } | ||||||
|  |     return config; | ||||||
|  |   }, | ||||||
|  |   (error) => { | ||||||
|  |     return Promise.reject(error); | ||||||
|  |   } | ||||||
|  | ); | ||||||
|  | 
 | ||||||
|  | // Add response interceptor to handle 401 errors
 | ||||||
|  | apiService.interceptors.response.use( | ||||||
|  |   (response) => response, | ||||||
|  |   (error) => { | ||||||
|  |     if (error.response?.status === 401) { | ||||||
|  |       // Handle token expiration (e.g., redirect to login)
 | ||||||
|  |       localStorage.removeItem('authToken'); | ||||||
|  |       window.location.href = '/login'; | ||||||
|  |     } | ||||||
|  |     return Promise.reject(error); | ||||||
|  |   } | ||||||
|  | ); | ||||||
|  | 
 | ||||||
|  | export default apiService; | ||||||
							
								
								
									
										12
									
								
								src/ApiServices/reportBaseUrlDeleteAPI.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										12
									
								
								src/ApiServices/reportBaseUrlDeleteAPI.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,12 @@ | |||||||
|  | import apiService from '../APIRequestService/APIServices'; | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | export const deleteReport = async (reportId) => { | ||||||
|  |     try { | ||||||
|  |         const response = await apiService.delete(`/Rpt_builder2/Rpt_builder2/${reportId}`); | ||||||
|  |         console.log(response.data); | ||||||
|  |         return response; | ||||||
|  |     } catch (error) { | ||||||
|  |         throw error; | ||||||
|  |     } | ||||||
|  | }; | ||||||
							
								
								
									
										16
									
								
								src/ApiServices/reportBaseUrlEditAPI.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										16
									
								
								src/ApiServices/reportBaseUrlEditAPI.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,16 @@ | |||||||
|  | import apiService from '../APIRequestService/APIServices'; | ||||||
|  | 
 | ||||||
|  | const editReport = async (id, payload) => { | ||||||
|  |   try { | ||||||
|  |     const response = await apiService.put(`Rpt_builder2_lines/update/${id}`, payload); | ||||||
|  |     console.log("Edit api report base url ", response.data) | ||||||
|  |     return response.data; | ||||||
|  |   } catch (error) { | ||||||
|  |     console.error("Error in editReport:", error); | ||||||
|  |     throw error; | ||||||
|  |   } | ||||||
|  | }; | ||||||
|  | 
 | ||||||
|  | export default { | ||||||
|  |   editReport, | ||||||
|  | }; | ||||||
							
								
								
									
										42
									
								
								src/App.js
									
									
									
									
									
								
							
							
						
						
									
										42
									
								
								src/App.js
									
									
									
									
									
								
							| @ -37,6 +37,8 @@ import DashboardNewAdd from "./components/dashboardnew/dashboardadd/dashboardbui | |||||||
| import DashboardNewEdit from "./components/dashboardnew/editdashboard/editformdashboard"; | import DashboardNewEdit from "./components/dashboardnew/editdashboard/editformdashboard"; | ||||||
| import EditNewDash from "./components/dashboardnew/editdashboard/editdashboard"; | import EditNewDash from "./components/dashboardnew/editdashboard/editdashboard"; | ||||||
| import SubMenuMaintenance from "./components/Dashboard/sub menu/submenumaintanence"; | import SubMenuMaintenance from "./components/Dashboard/sub menu/submenumaintanence"; | ||||||
|  | import ReportRunnerAll from "./components/Dashboard/reports/reportrunnerall"; | ||||||
|  | import ReportBuilderSQL from "./components/Dashboard/reports/reportbuildersql"; | ||||||
| const theme = createTheme({ | const theme = createTheme({ | ||||||
|   palette: { |   palette: { | ||||||
|     primary: { |     primary: { | ||||||
| @ -65,22 +67,22 @@ const App = () => { | |||||||
|             draggable |             draggable | ||||||
|             pauseOnHover |             pauseOnHover | ||||||
|           /> |           /> | ||||||
| 
 |            | ||||||
|           <Routes> |           <Routes> | ||||||
|             <Route path="/" element={<Login />} /> |             <Route path="/login" element={<Login />} /> | ||||||
| 
 |              | ||||||
|             {/* Main dashboard route */} |             {/* Main dashboard route */} | ||||||
|             <Route path="/dashboard" element={<Dashboard />}> |             <Route path="/dashboard/*" element={<Dashboard />}> | ||||||
|               <Route index element={<HomePage />} /> |               <Route index element={<HomePage />} /> | ||||||
| 
 |                | ||||||
|               {/* Setup section with all maintenance routes */} |               {/* Setup section with all maintenance routes */} | ||||||
|               <Route path="setup" element={<Setup />}> |               <Route path="setup" element={<Setup />}> | ||||||
|                 <Route index element={<div>Select a setup option from the menu</div>} /> |                 <Route index element={<div>Select a setup option from the menu</div>} /> | ||||||
|                 <Route path="user-maintenance" element={<UserMaintenance />} /> |                 <Route path="user-maintenance" element={<UserMaintenance />} /> | ||||||
|                 <Route path="user-group-maintenance" element={<UserGroupMaintenance />} /> |                 <Route path="user-group-maintenance" element={<UserGroupMaintenance />} /> | ||||||
|                 <Route path="menu-maintenance" element={<MenuMaintenance />} /> |                 <Route path="menu-maintenance" element={<MenuMaintenance />} /> | ||||||
|                 <Route path="sub-menu-maintenance/:menuItemId" element={<SubMenuMaintenance />} /> |                 <Route path="sub-menu-maintenance/:menuItemId" element={<SubMenuMaintenance/>} /> | ||||||
| 
 |              | ||||||
|                 <Route path="menu-access-control" element={<MenuAccessControl />} /> |                 <Route path="menu-access-control" element={<MenuAccessControl />} /> | ||||||
|                 <Route path="system-parameters" element={<SystemParameters />} /> |                 <Route path="system-parameters" element={<SystemParameters />} /> | ||||||
|                 <Route path="access-type" element={<AccessType />} /> |                 <Route path="access-type" element={<AccessType />} /> | ||||||
| @ -90,23 +92,25 @@ const App = () => { | |||||||
|                 {/* Additional components */} |                 {/* Additional components */} | ||||||
|                 <Route path="code-extension" element={<CodeExtension />} /> |                 <Route path="code-extension" element={<CodeExtension />} /> | ||||||
|                 <Route path="dynamic-table" element={<DynamicTable />} /> |                 <Route path="dynamic-table" element={<DynamicTable />} /> | ||||||
| 
 |                     | ||||||
|               </Route> |               </Route> | ||||||
|               <Route path="dashboard-runner-all" element={<DashboardRunnerAll />} /> |                 <Route path="dashboard-runner-all" element={<DashboardRunnerAll/>}/> | ||||||
|               <Route path="dashboard-new-all" element={<DashboardNewAll />} /> |                 <Route path="dashboard-new-all" element={<DashboardNewAll/>}/> | ||||||
|               <Route path="dashboard-new-add" element={<DashboardNewAdd />} /> |                 <Route path="dashboard-new-add" element={<DashboardNewAdd/>}/> | ||||||
|               <Route path="dashboard-new-edit/:id" element={<DashboardNewEdit />} /> |                 <Route path="dashboard-new-edit/:id" element={<DashboardNewEdit/>}/>  | ||||||
|               <Route path="edit-new-dash/:id" element={<EditNewDash />} /> |                 <Route path="edit-new-dash/:id" element={<EditNewDash/>}/> | ||||||
|               <Route path="dashrunner/:id" element={<DashboardRunner />} /> |                 <Route path="dashrunner/:id" element={  <DashboardRunner/>}/> | ||||||
| 
 |                <Route path="reports" element={<Report />} /> | ||||||
|               <Route path="reports" element={<Report />} /> |                 <Route path="user-report" element={<ReportBuilderSQL />} /> | ||||||
|               <Route path="about" element={<About />} /> |               {/* <Route path="reports" element={<ReportRunnerAll />} /> */} | ||||||
|               <Route path="profile" element={<Profile />} /> |                 <Route path="about" element={<About />} /> | ||||||
|  |               <Route path="profile" element={<Profile />} />   | ||||||
|             </Route> |             </Route> | ||||||
| 
 |  | ||||||
|             {/* buildercomponents */} |             {/* buildercomponents */} | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | 
 | ||||||
|  |              | ||||||
|             <Route path="*" element={<Navigate to="/" replace />} /> |             <Route path="*" element={<Navigate to="/" replace />} /> | ||||||
|           </Routes> |           </Routes> | ||||||
|         </BrowserRouter> |         </BrowserRouter> | ||||||
|  | |||||||
| @ -4,7 +4,7 @@ import { getToken } from '../../../utils/tokenService'; | |||||||
| 
 | 
 | ||||||
| // Create axios instance with base configuration
 | // Create axios instance with base configuration
 | ||||||
| const apiClient = axios.create({ | const apiClient = axios.create({ | ||||||
|   baseURL: process.env.REACT_APP_API_URL || 'http://157.66.191.31:33730/back/', |   baseURL: process.env.REACT_APP_API_URL , | ||||||
| }); | }); | ||||||
| 
 | 
 | ||||||
| // Add request interceptor to inject token
 | // Add request interceptor to inject token
 | ||||||
|  | |||||||
| @ -50,7 +50,7 @@ import ApiRegistery from "./ApiRegistery/ApiRegistery"; | |||||||
| import TokenRegistery from "./TokenRegistery/TokenRegistery"; | import TokenRegistery from "./TokenRegistery/TokenRegistery"; | ||||||
| import HomePage from "./HomePage"; | import HomePage from "./HomePage"; | ||||||
| import Setup from "./Setup"; | import Setup from "./Setup"; | ||||||
| import Report from "./reports/Report"; | // import Report from "./reports/Report";
 | ||||||
| import SequenceGenerator from "./document sequence/sequencegenerator"; | import SequenceGenerator from "./document sequence/sequencegenerator"; | ||||||
| import About from "./dropdown/about"; | import About from "./dropdown/about"; | ||||||
| import Profile from "./dropdown/profile"; | import Profile from "./dropdown/profile"; | ||||||
| @ -61,7 +61,9 @@ import DashboardNewEdit from "../dashboardnew/editdashboard/editformdashboard"; | |||||||
| import EditNewDash from "../dashboardnew/editdashboard/editdashboard"; | import EditNewDash from "../dashboardnew/editdashboard/editdashboard"; | ||||||
| import DashboardRunner from "../dashboardnew/dashboardrunner/dashboardrunner"; | import DashboardRunner from "../dashboardnew/dashboardrunner/dashboardrunner"; | ||||||
| import SubMenuMaintenance from "./sub menu/submenumaintanence";  | import SubMenuMaintenance from "./sub menu/submenumaintanence";  | ||||||
| 
 | import ReportRunnerAll from "./reports/reportrunnerall"; | ||||||
|  | import Report from "./reports/Report"; | ||||||
|  | import ReportBuilderSQL from "./reports/reportbuildersql"; | ||||||
| 
 | 
 | ||||||
| const Dashboard = () => { | const Dashboard = () => { | ||||||
|   const navigate = useNavigate(); |   const navigate = useNavigate(); | ||||||
| @ -585,7 +587,8 @@ const Dashboard = () => { | |||||||
|               <Route path="document-sequence" element={<SequenceGenerator />} /> |               <Route path="document-sequence" element={<SequenceGenerator />} /> | ||||||
|             <Route path="sub-menu-maintenance/:menuItemId" element={<SubMenuMaintenance/>} /> |             <Route path="sub-menu-maintenance/:menuItemId" element={<SubMenuMaintenance/>} /> | ||||||
|             </Route> |             </Route> | ||||||
|             <Route path="reports" element={<Report />} /> |             <Route path="reports" element={<Report/>} /> | ||||||
|  |             <Route path="user-report" element={<ReportBuilderSQL/>} /> | ||||||
|             <Route path="about" element={<About/>} /> |             <Route path="about" element={<About/>} /> | ||||||
|             <Route path="profile" element={<Profile/>} /> |             <Route path="profile" element={<Profile/>} /> | ||||||
|             <Route path="dashboard-runner-all" element={<DashboardRunnerAll/>}/> |             <Route path="dashboard-runner-all" element={<DashboardRunnerAll/>}/> | ||||||
|  | |||||||
| @ -1,32 +1,50 @@ | |||||||
| import React, { useState, useEffect } from "react"; | import React, { useState, useEffect } from "react"; | ||||||
| 
 | import { useNavigate } from "react-router-dom"; | ||||||
| const Card = ({ report }) => { | import { toast } from "react-toastify"; | ||||||
|   return ( | import "react-toastify/dist/ReactToastify.css"; | ||||||
|     <div className="bg-white border border-gray-300 rounded-lg shadow-md p-6 m-4 cursor-pointer transition-transform transform hover:scale-105 hover:shadow-lg flex flex-col items-center justify-center text-center"> | import { | ||||||
|       <h2 className="text-lg font-semibold mb-2">{report.reportName}</h2> |   Container, | ||||||
|       <p className="text-gray-600 mb-2">{report.description}</p> |   Grid, | ||||||
|       <p className="text-gray-600 mb-2"> |   Card, | ||||||
|         Active: {report.active ? "Yes" : "No"} |   CardHeader, | ||||||
|       </p> |   CardContent, | ||||||
|       <p className="text-gray-600">Is SQL: {report.isSql ? "Yes" : "No"}</p> |   Typography, | ||||||
|     </div> |   CircularProgress, | ||||||
|   ); |   Alert, | ||||||
| }; |   Paper, | ||||||
| 
 |   Button, | ||||||
| // Define the API base URL using the environment variable
 |   Avatar, | ||||||
| const api = process.env.REACT_APP_API_BASE_URL; |   Chip, | ||||||
|  |   Box, | ||||||
|  |   IconButton, | ||||||
|  |   Divider | ||||||
|  | } from '@mui/material'; | ||||||
|  | import {  | ||||||
|  |   AddCircleOutline,  | ||||||
|  |   Storage as Database,  | ||||||
|  |   Link as LinkIcon,  | ||||||
|  |   CheckCircle,  | ||||||
|  |   Cancel, | ||||||
|  |   MoreVert, | ||||||
|  |   AccessTime | ||||||
|  | } from '@mui/icons-material'; | ||||||
| 
 | 
 | ||||||
| const Report = () => { | const Report = () => { | ||||||
|   const [reports, setReports] = useState([]); |   const [reports, setReports] = useState([]); | ||||||
|   const [loading, setLoading] = useState(true); |   const [loading, setLoading] = useState(true); | ||||||
|  |   const [error, setError] = useState(""); | ||||||
|  |   const navigate = useNavigate(); | ||||||
| 
 | 
 | ||||||
|  |   const api = process.env.REACT_APP_API_BASE_URL; | ||||||
|  |   console.log("API Base URL:", api); | ||||||
|   useEffect(() => { |   useEffect(() => { | ||||||
|     const fetchData = async () => { |     const fetchData = async () => { | ||||||
|       const token = localStorage.getItem("authToken"); |       const token = localStorage.getItem("authToken"); | ||||||
| 
 | 
 | ||||||
|       if (!token) { |       if (!token) { | ||||||
|         console.error("No auth token found. Redirecting to login."); |         setError("No auth token found. Please login."); | ||||||
|         // You can redirect to the login page here if needed
 |         toast.error("Authentication required"); | ||||||
|  |         navigate("/login"); | ||||||
|         return; |         return; | ||||||
|       } |       } | ||||||
| 
 | 
 | ||||||
| @ -38,37 +56,276 @@ const Report = () => { | |||||||
|         }); |         }); | ||||||
| 
 | 
 | ||||||
|         if (!response.ok) { |         if (!response.ok) { | ||||||
|           throw new Error("Failed to fetch data"); |           throw new Error(response.status === 401 ? "Session expired" : "Failed to fetch data"); | ||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         const data = await response.json(); |         const data = await response.json(); | ||||||
|         setReports(data); |         setReports(data); | ||||||
|         setLoading(false); |  | ||||||
|       } catch (error) { |       } catch (error) { | ||||||
|         console.error("Error fetching data:", error); |         console.error("Error fetching data:", error); | ||||||
|  |         setError(error.message); | ||||||
|  |         if (error.message === "Session expired") { | ||||||
|  |           toast.error("Session expired. Please login again."); | ||||||
|  |           navigate("/login"); | ||||||
|  |         } | ||||||
|  |       } finally { | ||||||
|         setLoading(false); |         setLoading(false); | ||||||
|       } |       } | ||||||
|     }; |     }; | ||||||
| 
 | 
 | ||||||
|     fetchData(); |     fetchData(); | ||||||
|   }, []); |   }, [api, navigate]); | ||||||
|  | 
 | ||||||
|  |   const goToAddSQLReport = () => { | ||||||
|  |     navigate("/dashboard/user-report"); | ||||||
|  |   }; | ||||||
|  | 
 | ||||||
|  |   const goToAddURLReport = () => { | ||||||
|  |     navigate("/admin/reportbuild2all"); | ||||||
|  |   }; | ||||||
|  | 
 | ||||||
|  |   const handleCardClick = (report) => { | ||||||
|  |     if (report.isSql) { | ||||||
|  |       navigate(`/admin/report-runner1/${report.id}`, {  | ||||||
|  |         state: { reportId: report.id, reportData: report } | ||||||
|  |       }); | ||||||
|  |     } else { | ||||||
|  |       navigate(`/admin/report-runner2/${report.id}`, {  | ||||||
|  |         state: { reportId: report.id, reportData: report } | ||||||
|  |       }); | ||||||
|  |     } | ||||||
|  |   }; | ||||||
| 
 | 
 | ||||||
|   return ( |   return ( | ||||||
|     <div className="min-h-screen bg-gray-100 p-4 flex flex-col items-center"> |     <Container maxWidth="xl" sx={{ py: 4 }}> | ||||||
|       <div className="mb-6"> |       {/* Header Section */} | ||||||
|         <h1 className="text-3xl font-semibold text-gray-700">Reports</h1> |       <Paper elevation={2} sx={{  | ||||||
|       </div> |         p: 3,  | ||||||
|       {loading ? ( |         mb: 4,  | ||||||
|         <p className="text-gray-700">Loading...</p> |         display: 'flex',  | ||||||
|       ) : ( |         justifyContent: 'space-between',  | ||||||
|         <div className="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-6"> |         alignItems: 'center', | ||||||
|           {reports.map((report) => ( |         borderRadius: '12px' | ||||||
|             <Card key={report.id} report={report} /> |       }}> | ||||||
|           ))} |         <Typography variant="h4" color="primary" sx={{ fontWeight: 'bold' }}> | ||||||
|         </div> |           All Reports | ||||||
|  |         </Typography> | ||||||
|  |         <Box> | ||||||
|  |           <Button | ||||||
|  |             variant="contained" | ||||||
|  |             startIcon={<AddCircleOutline />} | ||||||
|  |             onClick={goToAddSQLReport} | ||||||
|  |             sx={{ mr: 2 }} | ||||||
|  |           > | ||||||
|  |             Report Builder SQL | ||||||
|  |           </Button> | ||||||
|  |           <Button | ||||||
|  |             variant="contained" | ||||||
|  |             startIcon={<AddCircleOutline />} | ||||||
|  |             onClick={goToAddURLReport} | ||||||
|  |           > | ||||||
|  |             Report Builder URL | ||||||
|  |           </Button> | ||||||
|  |         </Box> | ||||||
|  |       </Paper> | ||||||
|  | 
 | ||||||
|  |       {/* Loading State */} | ||||||
|  |       {loading && ( | ||||||
|  |         <Grid container justifyContent="center" sx={{ py: 8 }}> | ||||||
|  |           <CircularProgress size={60} /> | ||||||
|  |         </Grid> | ||||||
|       )} |       )} | ||||||
|     </div> | 
 | ||||||
|  |       {/* Error State */} | ||||||
|  |       {error && !loading && ( | ||||||
|  |         <Alert severity="error" sx={{ mb: 4 }}> | ||||||
|  |           {error} | ||||||
|  |         </Alert> | ||||||
|  |       )} | ||||||
|  | 
 | ||||||
|  |       {/* Reports Grid */} | ||||||
|  |       {!loading && reports.length > 0 && ( | ||||||
|  |         <Grid container spacing={3}> | ||||||
|  |           {reports.map((report) => ( | ||||||
|  |             <Grid item xs={12} sm={6} md={4} lg={3} key={report.id}> | ||||||
|  |               <Card  | ||||||
|  |                 sx={{  | ||||||
|  |                   height: '100%', | ||||||
|  |                   display: 'flex', | ||||||
|  |                   flexDirection: 'column', | ||||||
|  |                   cursor: 'pointer', | ||||||
|  |                   transition: 'transform 0.3s, box-shadow 0.3s', | ||||||
|  |                   '&:hover': { | ||||||
|  |                     transform: 'translateY(-8px)', | ||||||
|  |                     boxShadow: 6 | ||||||
|  |                   }, | ||||||
|  |                   borderRadius: '16px', | ||||||
|  |                   overflow: 'hidden' | ||||||
|  |                 }} | ||||||
|  |                 onClick={() => handleCardClick(report)} | ||||||
|  |               > | ||||||
|  |                 {/* Card Header with Gradient */} | ||||||
|  |                 <Box | ||||||
|  |                   sx={{ | ||||||
|  |                     p: 2, | ||||||
|  |                     display: 'flex', | ||||||
|  |                     justifyContent: 'space-between', | ||||||
|  |                     alignItems: 'center', | ||||||
|  |                     borderBottom: '1px solid', | ||||||
|  |                     borderColor: 'divider', | ||||||
|  |                     background: report.isSql  | ||||||
|  |                       ? 'linear-gradient(135deg, #f5f7fa 0%,rgb(198, 218, 255) 100%)'  | ||||||
|  |                       : 'linear-gradient(135deg, #fff9f0 0%,rgb(217, 204, 255) 100%)', | ||||||
|  |                     height: '60px' | ||||||
|  |                   }} | ||||||
|  |                 > | ||||||
|  |                   <Box sx={{ display: 'flex', alignItems: 'center' }}> | ||||||
|  |                     <Avatar | ||||||
|  |                       sx={{  | ||||||
|  |                         width: 36, | ||||||
|  |                         height: 36, | ||||||
|  |                         mr: 2, | ||||||
|  |                         borderRadius: '10px', | ||||||
|  |                         bgcolor: report.isSql ? 'rgba(65, 105, 225, 0.15)' : 'rgba(255, 165, 0, 0.15)', | ||||||
|  |                         color: report.isSql ? '#4169E1' : '#FF8C00' | ||||||
|  |                       }} | ||||||
|  |                     > | ||||||
|  |                       {report.isSql ? <Database /> : <LinkIcon />} | ||||||
|  |                     </Avatar> | ||||||
|  |                     <Typography | ||||||
|  |                       variant="subtitle2" | ||||||
|  |                       sx={{  | ||||||
|  |                         color: report.isSql ? '#4169E1' : '#FF8C00', | ||||||
|  |                       }} | ||||||
|  |                     > | ||||||
|  |                       {report.isSql ? "SQL Report" : "URL Report"} | ||||||
|  |                     </Typography> | ||||||
|  |                   </Box> | ||||||
|  | 
 | ||||||
|  |                   {/* Status Chip */} | ||||||
|  |                   <Chip | ||||||
|  |                     label={report.active ? "Active" : "Inactive"} | ||||||
|  |                     size="small" | ||||||
|  |                     color={report.active ? "success" : "error"} | ||||||
|  |                     icon={report.active ? <CheckCircle fontSize="small" /> : <Cancel fontSize="small" />} | ||||||
|  |                     sx={{ | ||||||
|  |                       backgroundColor: report.active ? 'rgba(40, 167, 69, 0.1)' : 'rgba(220, 53, 69, 0.1)', | ||||||
|  |                       color: report.active ? '#28a745' : '#dc3545', | ||||||
|  |                       px: 1, | ||||||
|  |                       py: 0.5 | ||||||
|  |                     }} | ||||||
|  |                   /> | ||||||
|  |                 </Box> | ||||||
|  | 
 | ||||||
|  |                 {/* Card Content */} | ||||||
|  |                 <CardContent sx={{ flexGrow: 1, p: 3 }}> | ||||||
|  |                   <Typography  | ||||||
|  |                     gutterBottom  | ||||||
|  |                     variant="h6"  | ||||||
|  |                     component="div"  | ||||||
|  |                     noWrap | ||||||
|  |                     sx={{  | ||||||
|  |                       fontWeight: 'bold', | ||||||
|  |                       color: 'text.primary', | ||||||
|  |                       mb: 2 | ||||||
|  |                     }} | ||||||
|  |                   > | ||||||
|  |                     {report.reportName} | ||||||
|  |                   </Typography> | ||||||
|  |                   <Typography  | ||||||
|  |                     variant="body2"  | ||||||
|  |                     color="text.secondary" | ||||||
|  |                     sx={{ | ||||||
|  |                       display: '-webkit-box', | ||||||
|  |                       WebkitLineClamp: 2, | ||||||
|  |                       WebkitBoxOrient: 'vertical', | ||||||
|  |                       overflow: 'hidden', | ||||||
|  |                       minHeight: '40px', | ||||||
|  |                       lineHeight: 1.5, | ||||||
|  |                       fontSize: '0.9rem' | ||||||
|  |                     }} | ||||||
|  |                   > | ||||||
|  |                     {report.description || "No description available"} | ||||||
|  |                   </Typography> | ||||||
|  |                 </CardContent> | ||||||
|  | 
 | ||||||
|  |                 {/* Card Footer */} | ||||||
|  |                 <Box | ||||||
|  |                   sx={{ | ||||||
|  |                     p: 2, | ||||||
|  |                     borderTop: '1px solid', | ||||||
|  |                     borderColor: 'divider', | ||||||
|  |                     backgroundColor: 'background.default' | ||||||
|  |                   }} | ||||||
|  |                 > | ||||||
|  |                   <Box sx={{  | ||||||
|  |                     display: 'flex',  | ||||||
|  |                     justifyContent: 'space-between',  | ||||||
|  |                     alignItems: 'center'  | ||||||
|  |                   }}> | ||||||
|  |                     <Box sx={{ display: 'flex', alignItems: 'center' }}> | ||||||
|  |                       <AccessTime fontSize="small" sx={{ mr: 1, color: 'text.secondary' }} /> | ||||||
|  |                       <Typography variant="caption" color="text.secondary"> | ||||||
|  |                         Updated: {new Date(report.updatedAt).toLocaleDateString()} | ||||||
|  |                       </Typography> | ||||||
|  |                     </Box> | ||||||
|  |                     <IconButton | ||||||
|  |                       size="small" | ||||||
|  |                       sx={{  | ||||||
|  |                         backgroundColor: 'action.hover', | ||||||
|  |                         '&:hover': { | ||||||
|  |                           backgroundColor: 'action.selected' | ||||||
|  |                         } | ||||||
|  |                       }} | ||||||
|  |                       onClick={(e) => { | ||||||
|  |                         e.stopPropagation(); | ||||||
|  |                         // Add menu functionality here
 | ||||||
|  |                       }} | ||||||
|  |                     > | ||||||
|  |                       <MoreVert fontSize="small" /> | ||||||
|  |                     </IconButton> | ||||||
|  |                   </Box> | ||||||
|  |                 </Box> | ||||||
|  |               </Card> | ||||||
|  |             </Grid> | ||||||
|  |           ))} | ||||||
|  |         </Grid> | ||||||
|  |       )} | ||||||
|  | 
 | ||||||
|  |       {/* Empty State */} | ||||||
|  |       {!loading && reports.length === 0 && !error && ( | ||||||
|  |         <Paper sx={{  | ||||||
|  |           p: 4,  | ||||||
|  |           textAlign: 'center', | ||||||
|  |           borderRadius: '12px' | ||||||
|  |         }}> | ||||||
|  |           <Typography variant="h6" gutterBottom> | ||||||
|  |             No reports available | ||||||
|  |           </Typography> | ||||||
|  |           <Typography variant="body1" color="text.secondary" sx={{ mb: 3 }}> | ||||||
|  |             Create your first report by clicking one of the "Add Report" buttons | ||||||
|  |           </Typography> | ||||||
|  |           <Box> | ||||||
|  |             <Button | ||||||
|  |               variant="contained" | ||||||
|  |               startIcon={<AddCircleOutline />} | ||||||
|  |               onClick={goToAddSQLReport} | ||||||
|  |               sx={{ mr: 2 }} | ||||||
|  |             > | ||||||
|  |               Add SQL Report | ||||||
|  |             </Button> | ||||||
|  |             <Button | ||||||
|  |               variant="contained" | ||||||
|  |               startIcon={<AddCircleOutline />} | ||||||
|  |               onClick={goToAddURLReport} | ||||||
|  |             > | ||||||
|  |               Add URL Report | ||||||
|  |             </Button> | ||||||
|  |           </Box> | ||||||
|  |         </Paper> | ||||||
|  |       )} | ||||||
|  |     </Container> | ||||||
|   ); |   ); | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
| export default Report; | export default Report; | ||||||
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							| @ -2,15 +2,45 @@ import React, { useState, useEffect } from "react"; | |||||||
| import { useNavigate } from "react-router-dom"; | import { useNavigate } from "react-router-dom"; | ||||||
| import { toast } from "react-toastify"; | import { toast } from "react-toastify"; | ||||||
| import "react-toastify/dist/ReactToastify.css"; | import "react-toastify/dist/ReactToastify.css"; | ||||||
| import { fetchAllReportsApi } from '../../../APIServices/ReportRunnerAPI'; | import { fetchAllReportsApi } from '../../../ApiServices/ReportRunnerAPI'; | ||||||
|  | import { | ||||||
|  |   Container, | ||||||
|  |   Grid, | ||||||
|  |   Card, | ||||||
|  |   CardHeader, | ||||||
|  |   CardContent, | ||||||
|  |   CardActions, | ||||||
|  |   Typography, | ||||||
|  |   Button, | ||||||
|  |   CircularProgress, | ||||||
|  |   Alert, | ||||||
|  |   Dialog, | ||||||
|  |   DialogTitle, | ||||||
|  |   DialogContent, | ||||||
|  |   DialogActions, | ||||||
|  |   Avatar, | ||||||
|  |   IconButton, | ||||||
|  |   Chip, | ||||||
|  |   Divider, | ||||||
|  |   Paper | ||||||
|  | } from '@mui/material'; | ||||||
|  | import { | ||||||
|  |   AddCircleOutline, | ||||||
|  |   Link, | ||||||
|  |   Storage as Database, | ||||||
|  |   MoreVert, | ||||||
|  |   AccessTime, | ||||||
|  |   Delete, | ||||||
|  |   CheckCircle, | ||||||
|  |   Cancel | ||||||
|  | } from '@mui/icons-material'; | ||||||
| 
 | 
 | ||||||
| const ReportRunnerAll = () => { | const ReportRunnerAll = () => { | ||||||
|   const [gridData, setGridData] = useState([]); |   const [gridData, setGridData] = useState([]); | ||||||
|   const [isLoading, setIsLoading] = useState(false); |   const [isLoading, setIsLoading] = useState(false); | ||||||
|   const [error, setError] = useState(""); |   const [error, setError] = useState(""); | ||||||
|   const [rowSelected, setRowSelected] = useState(null); |   const [rowSelected, setRowSelected] = useState(null); | ||||||
|   const [modalDelete, setModalDelete] = useState(false); |   const [openDeleteDialog, setOpenDeleteDialog] = useState(false); | ||||||
|   const [reports, setReports] = useState([]); |  | ||||||
| 
 | 
 | ||||||
|   const navigate = useNavigate(); |   const navigate = useNavigate(); | ||||||
| 
 | 
 | ||||||
| @ -23,16 +53,12 @@ const ReportRunnerAll = () => { | |||||||
|     try { |     try { | ||||||
|       const data = await fetchAllReportsApi(); |       const data = await fetchAllReportsApi(); | ||||||
|       console.log("Fetched all reports:", data); |       console.log("Fetched all reports:", data); | ||||||
| 
 |  | ||||||
|       setGridData(data); |       setGridData(data); | ||||||
|       setReports(data); |       if (data.length === 0) setError("No data available"); | ||||||
| 
 |  | ||||||
|       if (data.length === 0) { |  | ||||||
|         setError("No data available"); |  | ||||||
|       } |  | ||||||
|     } catch (error) { |     } catch (error) { | ||||||
|       console.error("Error while fetching reports:", error); |       console.error("Error while fetching reports:", error); | ||||||
|       setError("Error fetching data."); |       setError("Error fetching data."); | ||||||
|  |       toast.error("Failed to load reports"); | ||||||
|     } finally { |     } finally { | ||||||
|       setIsLoading(false); |       setIsLoading(false); | ||||||
|     } |     } | ||||||
| @ -42,170 +68,196 @@ const ReportRunnerAll = () => { | |||||||
|   const goToAdd2 = () => navigate("/admin/reportbuild2all"); |   const goToAdd2 = () => navigate("/admin/reportbuild2all"); | ||||||
| 
 | 
 | ||||||
|   const goToRunner = (report) => { |   const goToRunner = (report) => { | ||||||
|     console.log("at time of navigating reportID: ",report.id, " report: ",report); |  | ||||||
|     if (report.isSql) { |     if (report.isSql) { | ||||||
|       navigate(`/admin/report-runner1/${report.id}`,{ state: { reportId: report.id, reportData: report}}); |       navigate(`/admin/report-runner1/${report.id}`, {  | ||||||
|  |         state: { reportId: report.id, reportData: report } | ||||||
|  |       }); | ||||||
|     } else { |     } else { | ||||||
|       navigate(`/admin/report-runner2/${report.id}`,{ state: { reportId: report.id, reportData: report}}); |       navigate(`/admin/report-runner2/${report.id}`, {  | ||||||
|  |         state: { reportId: report.id, reportData: report } | ||||||
|  |       }); | ||||||
|     } |     } | ||||||
|   }; |   }; | ||||||
| 
 | 
 | ||||||
|   const handleDelete = async (id) => { |   const handleDelete = async (id) => { | ||||||
|     setModalDelete(false); |     setOpenDeleteDialog(false); | ||||||
|     try { |     try { | ||||||
|       const response = await fetch(`/api/report-builder/${id}`, { method: "DELETE" }); |       const response = await fetch(`/api/report-builder/${id}`, {  | ||||||
|  |         method: "DELETE"  | ||||||
|  |       }); | ||||||
|       if (response.ok) { |       if (response.ok) { | ||||||
|         toast.success("Deleted successfully"); |         toast.success("Report deleted successfully"); | ||||||
|         fetchAllReports(); |         fetchAllReports(); | ||||||
|       } else { |       } else { | ||||||
|         toast.error("Error deleting data."); |         throw new Error("Failed to delete"); | ||||||
|       } |       } | ||||||
|     } catch (err) { |     } catch (err) { | ||||||
|       console.error(err); |       console.error(err); | ||||||
|       toast.error("Error deleting data."); |       toast.error("Error deleting report"); | ||||||
|     } |     } | ||||||
|   }; |   }; | ||||||
| 
 | 
 | ||||||
|   const openDeleteModal = (row) => { |   const openDeleteModal = (row) => { | ||||||
|     setRowSelected(row); |     setRowSelected(row); | ||||||
|     setModalDelete(true); |     setOpenDeleteDialog(true); | ||||||
|   }; |   }; | ||||||
| 
 | 
 | ||||||
|   return ( |   return ( | ||||||
|     <div className="container-fluid p-4"> |     <Container maxWidth="xl" sx={{ py: 4 }}> | ||||||
|       {/* Header */} |       {/* Header */} | ||||||
|       <div className="d-flex justify-content-between align-items-center mb-4"> |       <Paper elevation={2} sx={{ p: 3, mb: 4, display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}> | ||||||
|         <h3 className="m-0"><strong>All Reports</strong></h3> |         <Typography variant="h4" color="primary"> | ||||||
|  |           <Database sx={{ verticalAlign: 'middle', mr: 1 }} /> | ||||||
|  |           All Reports | ||||||
|  |         </Typography> | ||||||
|         <div> |         <div> | ||||||
|           <button className="btn btn-primary me-2" onClick={goToAdd}> |           <Button | ||||||
|             <i className="bi bi-plus me-1"></i> Report Builder SQL |             variant="contained" | ||||||
|           </button> |             startIcon={<AddCircleOutline />} | ||||||
|           <button className="btn btn-primary" onClick={goToAdd2}> |             onClick={goToAdd} | ||||||
|             <i className="bi bi-plus me-1"></i> Report Builder URL |             sx={{ mr: 2 }} | ||||||
|           </button> |           > | ||||||
|  |             SQL Report | ||||||
|  |           </Button> | ||||||
|  |           <Button | ||||||
|  |             variant="outlined" | ||||||
|  |             startIcon={<Link />} | ||||||
|  |             onClick={goToAdd2} | ||||||
|  |           > | ||||||
|  |             URL Report | ||||||
|  |           </Button> | ||||||
|         </div> |         </div> | ||||||
|       </div> |       </Paper> | ||||||
| 
 | 
 | ||||||
|       {/* Loading Spinner */} |       {/* Loading state */} | ||||||
|       {isLoading && ( |       {isLoading && ( | ||||||
|         <div className="alert alert-info d-flex align-items-center mt-3"> |         <Grid container justifyContent="center" sx={{ py: 8 }}> | ||||||
|           <div className="spinner-border me-2" role="status"></div> |           <CircularProgress size={60} /> | ||||||
|           Loading... |         </Grid> | ||||||
|         </div> |       )} | ||||||
|  | 
 | ||||||
|  |       {/* Error state */} | ||||||
|  |       {error && !isLoading && ( | ||||||
|  |         <Alert severity="error" sx={{ mb: 4 }}> | ||||||
|  |           {error} | ||||||
|  |         </Alert> | ||||||
|       )} |       )} | ||||||
| 
 | 
 | ||||||
|       {/* Report Cards */} |       {/* Report Cards */} | ||||||
|       {!isLoading && gridData.length > 0 && ( |       {!isLoading && gridData.length > 0 && ( | ||||||
|         <div className="row row-cols-1 row-cols-md-2 row-cols-lg-3 row-cols-xl-4 g-4"> |         <Grid container spacing={3}> | ||||||
|           {gridData.map((report, index) => ( |           {gridData.map((report, index) => ( | ||||||
|             <div className="col" key={index}> |             <Grid item xs={12} sm={6} md={4} lg={3} key={index}> | ||||||
|               <div  |               <Card  | ||||||
|                 className="card h-100 shadow-sm border-0" |                 sx={{  | ||||||
|  |                   height: '100%', | ||||||
|  |                   display: 'flex', | ||||||
|  |                   flexDirection: 'column', | ||||||
|  |                   cursor: 'pointer', | ||||||
|  |                   transition: 'transform 0.3s, box-shadow 0.3s', | ||||||
|  |                   '&:hover': { | ||||||
|  |                     transform: 'translateY(-8px)', | ||||||
|  |                     boxShadow: 6 | ||||||
|  |                   } | ||||||
|  |                 }} | ||||||
|                 onClick={() => goToRunner(report)} |                 onClick={() => goToRunner(report)} | ||||||
|                 style={{ cursor: 'pointer' }} |  | ||||||
|               > |               > | ||||||
|                 {/* Card Header */} |                 {/* Card Header */} | ||||||
|                 <div  |                 <CardHeader | ||||||
|                   className={`card-header d-flex justify-content-between align-items-center ${report.isSql ? 'bg-primary bg-opacity-10' : 'bg-warning bg-opacity-10'}`} |                   avatar={ | ||||||
|                 > |                     <Avatar sx={{  | ||||||
|                   <div className="d-flex align-items-center"> |                       bgcolor: report.isSql ? 'primary.light' : 'secondary.light', | ||||||
|                     <div className={`me-2 p-2 rounded ${report.isSql ? 'bg-primary bg-opacity-25' : 'bg-warning bg-opacity-25'}`}> |                       color: report.isSql ? 'primary.main' : 'secondary.main' | ||||||
|                       <i className={`bi ${report.isSql ? 'bi-database' : 'bi-link-45deg'} ${report.isSql ? 'text-primary' : 'text-warning'}`}></i> |                     }}> | ||||||
|                     </div> |                       {report.isSql ? <Database /> : <Link />} | ||||||
|                     <span className={`fw-semibold ${report.isSql ? 'text-primary' : 'text-warning'}`}> |                     </Avatar> | ||||||
|                       {report.isSql == null ? "N/A" : report.isSql ? "SQL Report" : "URL Report"} |                   } | ||||||
|                     </span> |                   action={ | ||||||
|                   </div> |                     <Chip | ||||||
|                   <span className={`badge ${report.active ? 'bg-success' : 'bg-danger'}`}> |                       label={report.active ? "Active" : "Inactive"} | ||||||
|                     {report.active ? "Active" : "Inactive"} |                       size="small" | ||||||
|                   </span> |                       color={report.active ? "success" : "error"} | ||||||
|                 </div> |                       icon={report.active ? <CheckCircle fontSize="small" /> : <Cancel fontSize="small" />} | ||||||
|  |                       sx={{ ml: 1 }} | ||||||
|  |                     /> | ||||||
|  |                   } | ||||||
|  |                   title={ | ||||||
|  |                     <Typography variant="subtitle1" color="text.secondary"> | ||||||
|  |                       {report.isSql ? "SQL Report" : "URL Report"} | ||||||
|  |                     </Typography> | ||||||
|  |                   } | ||||||
|  |                   sx={{ | ||||||
|  |                     bgcolor: report.isSql ? 'primary.50' : 'secondary.50', | ||||||
|  |                     borderBottom: '1px solid', | ||||||
|  |                     borderColor: 'divider' | ||||||
|  |                   }} | ||||||
|  |                 /> | ||||||
| 
 | 
 | ||||||
|                 {/* Card Body */} |                 {/* Card Content */} | ||||||
|                 <div className="card-body"> |                 <CardContent sx={{ flexGrow: 1 }}> | ||||||
|                   <h5 className="card-title fw-bold text-truncate" title={report.reportName}> |                   <Typography gutterBottom variant="h6" component="div" noWrap> | ||||||
|                     {report.reportName} |                     {report.reportName} | ||||||
|                   </h5> |                   </Typography> | ||||||
|                   <p  |                   <Typography variant="body2" color="text.secondary" sx={{ | ||||||
|                     className="card-text text-muted"  |                     display: '-webkit-box', | ||||||
|                     style={{ |                     WebkitLineClamp: 2, | ||||||
|                       display: '-webkit-box', |                     WebkitBoxOrient: 'vertical', | ||||||
|                       WebkitLineClamp: '2', |                     overflow: 'hidden', | ||||||
|                       WebkitBoxOrient: 'vertical', |                     minHeight: '40px' | ||||||
|                       overflow: 'hidden', |                   }}> | ||||||
|                       height: '42px' |  | ||||||
|                     }} |  | ||||||
|                     title={report.description} |  | ||||||
|                   > |  | ||||||
|                     {report.description || "No description available"} |                     {report.description || "No description available"} | ||||||
|                   </p> |                   </Typography> | ||||||
|                 </div> |                 </CardContent> | ||||||
| 
 | 
 | ||||||
|                 {/* Card Footer */} |                 {/* Card Footer */} | ||||||
|                 <div className="card-footer bg-light"> |                 <Divider /> | ||||||
|                   <div className="d-flex justify-content-between align-items-center"> |                 <CardActions sx={{ justifyContent: 'space-between', p: 2 }}> | ||||||
|                     <small className="text-muted"> |                   <Typography variant="caption" color="text.secondary" sx={{ display: 'flex', alignItems: 'center' }}> | ||||||
|                       <i className="bi bi-clock me-1"></i> |                     <AccessTime fontSize="small" sx={{ mr: 0.5 }} /> | ||||||
|                       Updated: {new Date(report.updatedAt).toLocaleDateString()} |                     Updated: {new Date(report.updatedAt).toLocaleDateString()} | ||||||
|                     </small> |                   </Typography> | ||||||
|                     <button  |                   <IconButton  | ||||||
|                       className="btn btn-sm btn-outline-secondary" |                     size="small"  | ||||||
|                       onClick={(e) => { |                     onClick={(e) => { | ||||||
|                         e.stopPropagation(); |                       e.stopPropagation(); | ||||||
|                         openDeleteModal(report); |                       openDeleteModal(report); | ||||||
|                       }} |                     }} | ||||||
|                     > |                   > | ||||||
|                       <i className="bi bi-three-dots"></i> |                     <MoreVert /> | ||||||
|                     </button> |                   </IconButton> | ||||||
|                   </div> |                 </CardActions> | ||||||
|                 </div> |               </Card> | ||||||
|               </div> |             </Grid> | ||||||
|             </div> |  | ||||||
|           ))} |           ))} | ||||||
|         </div> |         </Grid> | ||||||
|       )} |       )} | ||||||
| 
 | 
 | ||||||
|       {/* Error */} |       {/* Delete Dialog */} | ||||||
|       {error && <div className="alert alert-danger mt-3">{error}</div>} |       <Dialog | ||||||
| 
 |         open={openDeleteDialog} | ||||||
|       {/* Delete Modal */} |         onClose={() => setOpenDeleteDialog(false)} | ||||||
|       {modalDelete && ( |       > | ||||||
|         <div className="modal show d-block" tabIndex="-1" style={{ backgroundColor: 'rgba(0,0,0,0.5)' }}> |         <DialogTitle>Delete Confirmation</DialogTitle> | ||||||
|           <div className="modal-dialog"> |         <DialogContent> | ||||||
|             <div className="modal-content"> |           <Typography> | ||||||
|               <div className="modal-header"> |             Are you sure you want to delete the report? | ||||||
|                 <h5 className="modal-title">Delete Confirmation</h5> |           </Typography> | ||||||
|                 <button |           <Typography variant="subtitle1" sx={{ mt: 1 }}> | ||||||
|                   type="button" |             {rowSelected?.reportName} | ||||||
|                   className="btn-close" |           </Typography> | ||||||
|                   onClick={() => setModalDelete(false)} |         </DialogContent> | ||||||
|                 ></button> |         <DialogActions> | ||||||
|               </div> |           <Button onClick={() => setOpenDeleteDialog(false)}>Cancel</Button> | ||||||
|               <div className="modal-body"> |           <Button  | ||||||
|                 <p>Are you sure you want to delete the report?</p> |             onClick={() => handleDelete(rowSelected?.id)}  | ||||||
|                 <h6>{rowSelected?.reportName}</h6> |             color="error" | ||||||
|               </div> |             startIcon={<Delete />} | ||||||
|               <div className="modal-footer"> |           > | ||||||
|                 <button |             Delete | ||||||
|                   type="button" |           </Button> | ||||||
|                   className="btn btn-secondary" |         </DialogActions> | ||||||
|                   onClick={() => setModalDelete(false)} |       </Dialog> | ||||||
|                 > |     </Container> | ||||||
|                   Cancel |  | ||||||
|                 </button> |  | ||||||
|                 <button |  | ||||||
|                   type="button" |  | ||||||
|                   className="btn btn-danger" |  | ||||||
|                   onClick={() => handleDelete(rowSelected.id)} |  | ||||||
|                 > |  | ||||||
|                   Delete |  | ||||||
|                 </button> |  | ||||||
|               </div> |  | ||||||
|             </div> |  | ||||||
|           </div> |  | ||||||
|         </div> |  | ||||||
|       )} |  | ||||||
|     </div> |  | ||||||
|   ); |   ); | ||||||
| }; | }; | ||||||
| 
 | 
 | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user