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", | ||||
|       "version": "0.1.0", | ||||
|       "dependencies": { | ||||
|         "@emotion/react": "^11.11.3", | ||||
|         "@emotion/styled": "^11.11.0", | ||||
|         "@emotion/react": "^11.14.0", | ||||
|         "@emotion/styled": "^11.14.0", | ||||
|         "@fortawesome/fontawesome-svg-core": "^6.7.2", | ||||
|         "@fortawesome/free-solid-svg-icons": "^6.7.2", | ||||
|         "@fortawesome/react-fontawesome": "^0.2.2", | ||||
|         "@mui/icons-material": "^5.15.20", | ||||
|         "@mui/material": "^5.15.20", | ||||
|         "@material-ui/icons": "^4.11.3", | ||||
|         "@mui/icons-material": "^5.17.1", | ||||
|         "@mui/material": "^5.17.1", | ||||
|         "@mui/styles": "^5.16.4", | ||||
|         "@mui/x-charts": "^7.6.2", | ||||
|         "@mui/x-data-grid": "^7.6.2", | ||||
| @ -26,6 +27,7 @@ | ||||
|         "ajv-keywords": "^3.5.2", | ||||
|         "axios": "^1.6.7", | ||||
|         "chart.js": "^4.4.9", | ||||
|         "file-saver": "^2.0.5", | ||||
|         "mdb-react-ui-kit": "^7.1.0", | ||||
|         "moment": "^2.30.1", | ||||
|         "react": "^18.2.0", | ||||
| @ -3764,6 +3766,29 @@ | ||||
|       "integrity": "sha512-Vo+PSpZG2/fmgmiNzYK9qWRh8h/CHrwD0mo1h1DzL4yzHNSfWYujGTYsWGreD000gcgmZ7K4Ys6Tx9TxtsKdDw==", | ||||
|       "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": { | ||||
|       "version": "5.17.1", | ||||
|       "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" | ||||
|       } | ||||
|     }, | ||||
|     "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": { | ||||
|       "version": "1.0.4", | ||||
|       "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", | ||||
|   "private": true, | ||||
|   "dependencies": { | ||||
|     "@emotion/react": "^11.11.3", | ||||
|     "@emotion/styled": "^11.11.0", | ||||
|     "@emotion/react": "^11.14.0", | ||||
|     "@emotion/styled": "^11.14.0", | ||||
|     "@fortawesome/fontawesome-svg-core": "^6.7.2", | ||||
|     "@fortawesome/free-solid-svg-icons": "^6.7.2", | ||||
|     "@fortawesome/react-fontawesome": "^0.2.2", | ||||
|     "@mui/icons-material": "^5.15.20", | ||||
|     "@mui/material": "^5.15.20", | ||||
|     "@material-ui/icons": "^4.11.3", | ||||
|     "@mui/icons-material": "^5.17.1", | ||||
|     "@mui/material": "^5.17.1", | ||||
|     "@mui/styles": "^5.16.4", | ||||
|     "@mui/x-charts": "^7.6.2", | ||||
|     "@mui/x-data-grid": "^7.6.2", | ||||
| @ -21,6 +22,7 @@ | ||||
|     "ajv-keywords": "^3.5.2", | ||||
|     "axios": "^1.6.7", | ||||
|     "chart.js": "^4.4.9", | ||||
|     "file-saver": "^2.0.5", | ||||
|     "mdb-react-ui-kit": "^7.1.0", | ||||
|     "moment": "^2.30.1", | ||||
|     "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 { 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, | ||||
|   headers: { | ||||
|     'Content-Type': 'application/json', | ||||
|   }, | ||||
|   timeout: 30000, | ||||
| }); | ||||
| // Add a request interceptor to include Authorization header
 | ||||
| apiClient.interceptors.request.use( | ||||
| 
 | ||||
| // Request interceptor for auth token
 | ||||
| apiService.interceptors.request.use( | ||||
|   (config) => { | ||||
|     const token = getToken(); | ||||
|     const token = localStorage.getItem('authToken'); | ||||
|     if (token) { | ||||
|       console.log("token: ",token); | ||||
|       config.headers['Authorization'] = `Bearer ${token}`; | ||||
|       config.headers.Authorization = `Bearer ${token}`; | ||||
|     } | ||||
|     return config; | ||||
|   }, | ||||
|   (error) => Promise.reject(error) | ||||
|   (error) => { | ||||
|     return Promise.reject(error); | ||||
|   } | ||||
| ); | ||||
| 
 | ||||
| // Generic error handler function
 | ||||
| const handleError = (error) => { | ||||
|   let errorMessage = 'An unknown error occurred'; | ||||
|   console.error('Error Details:', error); | ||||
| 
 | ||||
|   if (error.response) { | ||||
|     // HTTP errors
 | ||||
|     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'}`; | ||||
| // Response interceptor
 | ||||
| apiService.interceptors.response.use( | ||||
|   (response) => response, | ||||
|   (error) => { | ||||
|     if (error.response?.status === 401) { | ||||
|       localStorage.removeItem('authToken'); | ||||
|       window.location.href = '/login'; | ||||
|     } | ||||
|   } else if (error.request) { | ||||
|     // 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(error); | ||||
|   } | ||||
| ); | ||||
| 
 | ||||
|   return Promise.reject(errorMessage); // Return error message as rejected promise
 | ||||
| }; | ||||
| 
 | ||||
| // Define the reusable methods
 | ||||
| // 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}`); | ||||
| // 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; | ||||
|   } | ||||
| }; | ||||
| 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, | ||||
| }; | ||||
							
								
								
									
										26
									
								
								src/App.js
									
									
									
									
									
								
							
							
						
						
									
										26
									
								
								src/App.js
									
									
									
									
									
								
							| @ -37,6 +37,8 @@ import DashboardNewAdd from "./components/dashboardnew/dashboardadd/dashboardbui | ||||
| import DashboardNewEdit from "./components/dashboardnew/editdashboard/editformdashboard"; | ||||
| import EditNewDash from "./components/dashboardnew/editdashboard/editdashboard"; | ||||
| 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({ | ||||
|   palette: { | ||||
|     primary: { | ||||
| @ -67,10 +69,10 @@ const App = () => { | ||||
|           /> | ||||
|            | ||||
|           <Routes> | ||||
|             <Route path="/" element={<Login />} /> | ||||
|             <Route path="/login" element={<Login />} /> | ||||
|              | ||||
|             {/* Main dashboard route */} | ||||
|             <Route path="/dashboard" element={<Dashboard />}> | ||||
|             <Route path="/dashboard/*" element={<Dashboard />}> | ||||
|               <Route index element={<HomePage />} /> | ||||
|                | ||||
|               {/* Setup section with all maintenance routes */} | ||||
| @ -79,7 +81,7 @@ const App = () => { | ||||
|                 <Route path="user-maintenance" element={<UserMaintenance />} /> | ||||
|                 <Route path="user-group-maintenance" element={<UserGroupMaintenance />} /> | ||||
|                 <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="system-parameters" element={<SystemParameters />} /> | ||||
| @ -92,21 +94,23 @@ const App = () => { | ||||
|                 <Route path="dynamic-table" element={<DynamicTable />} /> | ||||
|                     | ||||
|               </Route> | ||||
|               <Route path="dashboard-runner-all" element={<DashboardRunnerAll />} /> | ||||
|               <Route path="dashboard-new-all" element={<DashboardNewAll />} /> | ||||
|               <Route path="dashboard-new-add" element={<DashboardNewAdd />} /> | ||||
|               <Route path="dashboard-new-edit/:id" element={<DashboardNewEdit />} /> | ||||
|               <Route path="edit-new-dash/:id" element={<EditNewDash />} /> | ||||
|               <Route path="dashrunner/:id" element={<DashboardRunner />} /> | ||||
| 
 | ||||
|                 <Route path="dashboard-runner-all" element={<DashboardRunnerAll/>}/> | ||||
|                 <Route path="dashboard-new-all" element={<DashboardNewAll/>}/> | ||||
|                 <Route path="dashboard-new-add" element={<DashboardNewAdd/>}/> | ||||
|                 <Route path="dashboard-new-edit/:id" element={<DashboardNewEdit/>}/>  | ||||
|                 <Route path="edit-new-dash/:id" element={<EditNewDash/>}/> | ||||
|                 <Route path="dashrunner/:id" element={  <DashboardRunner/>}/> | ||||
|                <Route path="reports" element={<Report />} /> | ||||
|                 <Route path="user-report" element={<ReportBuilderSQL />} /> | ||||
|               {/* <Route path="reports" element={<ReportRunnerAll />} /> */} | ||||
|                 <Route path="about" element={<About />} /> | ||||
|               <Route path="profile" element={<Profile />} />   | ||||
|             </Route> | ||||
| 
 | ||||
|             {/* buildercomponents */} | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
|              | ||||
|             <Route path="*" element={<Navigate to="/" replace />} /> | ||||
|           </Routes> | ||||
|         </BrowserRouter> | ||||
|  | ||||
| @ -4,7 +4,7 @@ import { getToken } from '../../../utils/tokenService'; | ||||
| 
 | ||||
| // Create axios instance with base configuration
 | ||||
| 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
 | ||||
|  | ||||
| @ -50,7 +50,7 @@ import ApiRegistery from "./ApiRegistery/ApiRegistery"; | ||||
| import TokenRegistery from "./TokenRegistery/TokenRegistery"; | ||||
| import HomePage from "./HomePage"; | ||||
| import Setup from "./Setup"; | ||||
| import Report from "./reports/Report"; | ||||
| // import Report from "./reports/Report";
 | ||||
| import SequenceGenerator from "./document sequence/sequencegenerator"; | ||||
| import About from "./dropdown/about"; | ||||
| import Profile from "./dropdown/profile"; | ||||
| @ -61,7 +61,9 @@ import DashboardNewEdit from "../dashboardnew/editdashboard/editformdashboard"; | ||||
| import EditNewDash from "../dashboardnew/editdashboard/editdashboard"; | ||||
| import DashboardRunner from "../dashboardnew/dashboardrunner/dashboardrunner"; | ||||
| import SubMenuMaintenance from "./sub menu/submenumaintanence";  | ||||
| 
 | ||||
| import ReportRunnerAll from "./reports/reportrunnerall"; | ||||
| import Report from "./reports/Report"; | ||||
| import ReportBuilderSQL from "./reports/reportbuildersql"; | ||||
| 
 | ||||
| const Dashboard = () => { | ||||
|   const navigate = useNavigate(); | ||||
| @ -585,7 +587,8 @@ const Dashboard = () => { | ||||
|               <Route path="document-sequence" element={<SequenceGenerator />} /> | ||||
|             <Route path="sub-menu-maintenance/:menuItemId" element={<SubMenuMaintenance/>} /> | ||||
|             </Route> | ||||
|             <Route path="reports" element={<Report />} /> | ||||
|             <Route path="reports" element={<Report/>} /> | ||||
|             <Route path="user-report" element={<ReportBuilderSQL/>} /> | ||||
|             <Route path="about" element={<About/>} /> | ||||
|             <Route path="profile" element={<Profile/>} /> | ||||
|             <Route path="dashboard-runner-all" element={<DashboardRunnerAll/>}/> | ||||
|  | ||||
| @ -1,32 +1,50 @@ | ||||
| import React, { useState, useEffect } from "react"; | ||||
| 
 | ||||
| const Card = ({ report }) => { | ||||
|   return ( | ||||
|     <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"> | ||||
|       <h2 className="text-lg font-semibold mb-2">{report.reportName}</h2> | ||||
|       <p className="text-gray-600 mb-2">{report.description}</p> | ||||
|       <p className="text-gray-600 mb-2"> | ||||
|         Active: {report.active ? "Yes" : "No"} | ||||
|       </p> | ||||
|       <p className="text-gray-600">Is SQL: {report.isSql ? "Yes" : "No"}</p> | ||||
|     </div> | ||||
|   ); | ||||
| }; | ||||
| 
 | ||||
| // Define the API base URL using the environment variable
 | ||||
| const api = process.env.REACT_APP_API_BASE_URL; | ||||
| import { useNavigate } from "react-router-dom"; | ||||
| import { toast } from "react-toastify"; | ||||
| import "react-toastify/dist/ReactToastify.css"; | ||||
| import { | ||||
|   Container, | ||||
|   Grid, | ||||
|   Card, | ||||
|   CardHeader, | ||||
|   CardContent, | ||||
|   Typography, | ||||
|   CircularProgress, | ||||
|   Alert, | ||||
|   Paper, | ||||
|   Button, | ||||
|   Avatar, | ||||
|   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 [reports, setReports] = useState([]); | ||||
|   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(() => { | ||||
|     const fetchData = async () => { | ||||
|       const token = localStorage.getItem("authToken"); | ||||
| 
 | ||||
|       if (!token) { | ||||
|         console.error("No auth token found. Redirecting to login."); | ||||
|         // You can redirect to the login page here if needed
 | ||||
|         setError("No auth token found. Please login."); | ||||
|         toast.error("Authentication required"); | ||||
|         navigate("/login"); | ||||
|         return; | ||||
|       } | ||||
| 
 | ||||
| @ -38,36 +56,275 @@ const Report = () => { | ||||
|         }); | ||||
| 
 | ||||
|         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(); | ||||
|         setReports(data); | ||||
|         setLoading(false); | ||||
|       } catch (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); | ||||
|       } | ||||
|     }; | ||||
| 
 | ||||
|     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 ( | ||||
|     <div className="min-h-screen bg-gray-100 p-4 flex flex-col items-center"> | ||||
|       <div className="mb-6"> | ||||
|         <h1 className="text-3xl font-semibold text-gray-700">Reports</h1> | ||||
|       </div> | ||||
|       {loading ? ( | ||||
|         <p className="text-gray-700">Loading...</p> | ||||
|       ) : ( | ||||
|         <div className="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-6"> | ||||
|           {reports.map((report) => ( | ||||
|             <Card key={report.id} report={report} /> | ||||
|           ))} | ||||
|         </div> | ||||
|     <Container maxWidth="xl" sx={{ py: 4 }}> | ||||
|       {/* Header Section */} | ||||
|       <Paper elevation={2} sx={{  | ||||
|         p: 3,  | ||||
|         mb: 4,  | ||||
|         display: 'flex',  | ||||
|         justifyContent: 'space-between',  | ||||
|         alignItems: 'center', | ||||
|         borderRadius: '12px' | ||||
|       }}> | ||||
|         <Typography variant="h4" color="primary" sx={{ fontWeight: 'bold' }}> | ||||
|           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> | ||||
|   ); | ||||
| }; | ||||
| 
 | ||||
|  | ||||
										
											
												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 { toast } from "react-toastify"; | ||||
| 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 [gridData, setGridData] = useState([]); | ||||
|   const [isLoading, setIsLoading] = useState(false); | ||||
|   const [error, setError] = useState(""); | ||||
|   const [rowSelected, setRowSelected] = useState(null); | ||||
|   const [modalDelete, setModalDelete] = useState(false); | ||||
|   const [reports, setReports] = useState([]); | ||||
|   const [openDeleteDialog, setOpenDeleteDialog] = useState(false); | ||||
| 
 | ||||
|   const navigate = useNavigate(); | ||||
| 
 | ||||
| @ -23,16 +53,12 @@ const ReportRunnerAll = () => { | ||||
|     try { | ||||
|       const data = await fetchAllReportsApi(); | ||||
|       console.log("Fetched all reports:", data); | ||||
| 
 | ||||
|       setGridData(data); | ||||
|       setReports(data); | ||||
| 
 | ||||
|       if (data.length === 0) { | ||||
|         setError("No data available"); | ||||
|       } | ||||
|       if (data.length === 0) setError("No data available"); | ||||
|     } catch (error) { | ||||
|       console.error("Error while fetching reports:", error); | ||||
|       setError("Error fetching data."); | ||||
|       toast.error("Failed to load reports"); | ||||
|     } finally { | ||||
|       setIsLoading(false); | ||||
|     } | ||||
| @ -42,170 +68,196 @@ const ReportRunnerAll = () => { | ||||
|   const goToAdd2 = () => navigate("/admin/reportbuild2all"); | ||||
| 
 | ||||
|   const goToRunner = (report) => { | ||||
|     console.log("at time of navigating reportID: ",report.id, " report: ",report); | ||||
|     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 { | ||||
|       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) => { | ||||
|     setModalDelete(false); | ||||
|     setOpenDeleteDialog(false); | ||||
|     try { | ||||
|       const response = await fetch(`/api/report-builder/${id}`, { method: "DELETE" }); | ||||
|       const response = await fetch(`/api/report-builder/${id}`, {  | ||||
|         method: "DELETE"  | ||||
|       }); | ||||
|       if (response.ok) { | ||||
|         toast.success("Deleted successfully"); | ||||
|         toast.success("Report deleted successfully"); | ||||
|         fetchAllReports(); | ||||
|       } else { | ||||
|         toast.error("Error deleting data."); | ||||
|         throw new Error("Failed to delete"); | ||||
|       } | ||||
|     } catch (err) { | ||||
|       console.error(err); | ||||
|       toast.error("Error deleting data."); | ||||
|       toast.error("Error deleting report"); | ||||
|     } | ||||
|   }; | ||||
| 
 | ||||
|   const openDeleteModal = (row) => { | ||||
|     setRowSelected(row); | ||||
|     setModalDelete(true); | ||||
|     setOpenDeleteDialog(true); | ||||
|   }; | ||||
| 
 | ||||
|   return ( | ||||
|     <div className="container-fluid p-4"> | ||||
|     <Container maxWidth="xl" sx={{ py: 4 }}> | ||||
|       {/* Header */} | ||||
|       <div className="d-flex justify-content-between align-items-center mb-4"> | ||||
|         <h3 className="m-0"><strong>All Reports</strong></h3> | ||||
|       <Paper elevation={2} sx={{ p: 3, mb: 4, display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}> | ||||
|         <Typography variant="h4" color="primary"> | ||||
|           <Database sx={{ verticalAlign: 'middle', mr: 1 }} /> | ||||
|           All Reports | ||||
|         </Typography> | ||||
|         <div> | ||||
|           <button className="btn btn-primary me-2" onClick={goToAdd}> | ||||
|             <i className="bi bi-plus me-1"></i> Report Builder SQL | ||||
|           </button> | ||||
|           <button className="btn btn-primary" onClick={goToAdd2}> | ||||
|             <i className="bi bi-plus me-1"></i> Report Builder URL | ||||
|           </button> | ||||
|         </div> | ||||
|           <Button | ||||
|             variant="contained" | ||||
|             startIcon={<AddCircleOutline />} | ||||
|             onClick={goToAdd} | ||||
|             sx={{ mr: 2 }} | ||||
|           > | ||||
|             SQL Report | ||||
|           </Button> | ||||
|           <Button | ||||
|             variant="outlined" | ||||
|             startIcon={<Link />} | ||||
|             onClick={goToAdd2} | ||||
|           > | ||||
|             URL Report | ||||
|           </Button> | ||||
|         </div> | ||||
|       </Paper> | ||||
| 
 | ||||
|       {/* Loading Spinner */} | ||||
|       {/* Loading state */} | ||||
|       {isLoading && ( | ||||
|         <div className="alert alert-info d-flex align-items-center mt-3"> | ||||
|           <div className="spinner-border me-2" role="status"></div> | ||||
|           Loading... | ||||
|         </div> | ||||
|         <Grid container justifyContent="center" sx={{ py: 8 }}> | ||||
|           <CircularProgress size={60} /> | ||||
|         </Grid> | ||||
|       )} | ||||
| 
 | ||||
|       {/* Error state */} | ||||
|       {error && !isLoading && ( | ||||
|         <Alert severity="error" sx={{ mb: 4 }}> | ||||
|           {error} | ||||
|         </Alert> | ||||
|       )} | ||||
| 
 | ||||
|       {/* Report Cards */} | ||||
|       {!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) => ( | ||||
|             <div className="col" key={index}> | ||||
|               <div  | ||||
|                 className="card h-100 shadow-sm border-0" | ||||
|             <Grid item xs={12} sm={6} md={4} lg={3} key={index}> | ||||
|               <Card  | ||||
|                 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)} | ||||
|                 style={{ cursor: 'pointer' }} | ||||
|               > | ||||
|                 {/* Card Header */} | ||||
|                 <div  | ||||
|                   className={`card-header d-flex justify-content-between align-items-center ${report.isSql ? 'bg-primary bg-opacity-10' : 'bg-warning bg-opacity-10'}`} | ||||
|                 > | ||||
|                   <div className="d-flex align-items-center"> | ||||
|                     <div className={`me-2 p-2 rounded ${report.isSql ? 'bg-primary bg-opacity-25' : 'bg-warning bg-opacity-25'}`}> | ||||
|                       <i className={`bi ${report.isSql ? 'bi-database' : 'bi-link-45deg'} ${report.isSql ? 'text-primary' : 'text-warning'}`}></i> | ||||
|                     </div> | ||||
|                     <span className={`fw-semibold ${report.isSql ? 'text-primary' : 'text-warning'}`}> | ||||
|                       {report.isSql == null ? "N/A" : report.isSql ? "SQL Report" : "URL Report"} | ||||
|                     </span> | ||||
|                   </div> | ||||
|                   <span className={`badge ${report.active ? 'bg-success' : 'bg-danger'}`}> | ||||
|                     {report.active ? "Active" : "Inactive"} | ||||
|                   </span> | ||||
|                 </div> | ||||
|                 <CardHeader | ||||
|                   avatar={ | ||||
|                     <Avatar sx={{  | ||||
|                       bgcolor: report.isSql ? 'primary.light' : 'secondary.light', | ||||
|                       color: report.isSql ? 'primary.main' : 'secondary.main' | ||||
|                     }}> | ||||
|                       {report.isSql ? <Database /> : <Link />} | ||||
|                     </Avatar> | ||||
|                   } | ||||
|                   action={ | ||||
|                     <Chip | ||||
|                       label={report.active ? "Active" : "Inactive"} | ||||
|                       size="small" | ||||
|                       color={report.active ? "success" : "error"} | ||||
|                       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 */} | ||||
|                 <div className="card-body"> | ||||
|                   <h5 className="card-title fw-bold text-truncate" title={report.reportName}> | ||||
|                 {/* Card Content */} | ||||
|                 <CardContent sx={{ flexGrow: 1 }}> | ||||
|                   <Typography gutterBottom variant="h6" component="div" noWrap> | ||||
|                     {report.reportName} | ||||
|                   </h5> | ||||
|                   <p  | ||||
|                     className="card-text text-muted"  | ||||
|                     style={{ | ||||
|                   </Typography> | ||||
|                   <Typography variant="body2" color="text.secondary" sx={{ | ||||
|                     display: '-webkit-box', | ||||
|                       WebkitLineClamp: '2', | ||||
|                     WebkitLineClamp: 2, | ||||
|                     WebkitBoxOrient: 'vertical', | ||||
|                     overflow: 'hidden', | ||||
|                       height: '42px' | ||||
|                     }} | ||||
|                     title={report.description} | ||||
|                   > | ||||
|                     minHeight: '40px' | ||||
|                   }}> | ||||
|                     {report.description || "No description available"} | ||||
|                   </p> | ||||
|                 </div> | ||||
|                   </Typography> | ||||
|                 </CardContent> | ||||
| 
 | ||||
|                 {/* Card Footer */} | ||||
|                 <div className="card-footer bg-light"> | ||||
|                   <div className="d-flex justify-content-between align-items-center"> | ||||
|                     <small className="text-muted"> | ||||
|                       <i className="bi bi-clock me-1"></i> | ||||
|                 <Divider /> | ||||
|                 <CardActions sx={{ justifyContent: 'space-between', p: 2 }}> | ||||
|                   <Typography variant="caption" color="text.secondary" sx={{ display: 'flex', alignItems: 'center' }}> | ||||
|                     <AccessTime fontSize="small" sx={{ mr: 0.5 }} /> | ||||
|                     Updated: {new Date(report.updatedAt).toLocaleDateString()} | ||||
|                     </small> | ||||
|                     <button  | ||||
|                       className="btn btn-sm btn-outline-secondary" | ||||
|                   </Typography> | ||||
|                   <IconButton  | ||||
|                     size="small"  | ||||
|                     onClick={(e) => { | ||||
|                       e.stopPropagation(); | ||||
|                       openDeleteModal(report); | ||||
|                     }} | ||||
|                   > | ||||
|                       <i className="bi bi-three-dots"></i> | ||||
|                     </button> | ||||
|                   </div> | ||||
|                 </div> | ||||
|               </div> | ||||
|             </div> | ||||
|                     <MoreVert /> | ||||
|                   </IconButton> | ||||
|                 </CardActions> | ||||
|               </Card> | ||||
|             </Grid> | ||||
|           ))} | ||||
|         </div> | ||||
|         </Grid> | ||||
|       )} | ||||
| 
 | ||||
|       {/* Error */} | ||||
|       {error && <div className="alert alert-danger mt-3">{error}</div>} | ||||
| 
 | ||||
|       {/* Delete Modal */} | ||||
|       {modalDelete && ( | ||||
|         <div className="modal show d-block" tabIndex="-1" style={{ backgroundColor: 'rgba(0,0,0,0.5)' }}> | ||||
|           <div className="modal-dialog"> | ||||
|             <div className="modal-content"> | ||||
|               <div className="modal-header"> | ||||
|                 <h5 className="modal-title">Delete Confirmation</h5> | ||||
|                 <button | ||||
|                   type="button" | ||||
|                   className="btn-close" | ||||
|                   onClick={() => setModalDelete(false)} | ||||
|                 ></button> | ||||
|               </div> | ||||
|               <div className="modal-body"> | ||||
|                 <p>Are you sure you want to delete the report?</p> | ||||
|                 <h6>{rowSelected?.reportName}</h6> | ||||
|               </div> | ||||
|               <div className="modal-footer"> | ||||
|                 <button | ||||
|                   type="button" | ||||
|                   className="btn btn-secondary" | ||||
|                   onClick={() => setModalDelete(false)} | ||||
|       {/* Delete Dialog */} | ||||
|       <Dialog | ||||
|         open={openDeleteDialog} | ||||
|         onClose={() => setOpenDeleteDialog(false)} | ||||
|       > | ||||
|                   Cancel | ||||
|                 </button> | ||||
|                 <button | ||||
|                   type="button" | ||||
|                   className="btn btn-danger" | ||||
|                   onClick={() => handleDelete(rowSelected.id)} | ||||
|         <DialogTitle>Delete Confirmation</DialogTitle> | ||||
|         <DialogContent> | ||||
|           <Typography> | ||||
|             Are you sure you want to delete the report? | ||||
|           </Typography> | ||||
|           <Typography variant="subtitle1" sx={{ mt: 1 }}> | ||||
|             {rowSelected?.reportName} | ||||
|           </Typography> | ||||
|         </DialogContent> | ||||
|         <DialogActions> | ||||
|           <Button onClick={() => setOpenDeleteDialog(false)}>Cancel</Button> | ||||
|           <Button  | ||||
|             onClick={() => handleDelete(rowSelected?.id)}  | ||||
|             color="error" | ||||
|             startIcon={<Delete />} | ||||
|           > | ||||
|             Delete | ||||
|                 </button> | ||||
|               </div> | ||||
|             </div> | ||||
|           </div> | ||||
|         </div> | ||||
|       )} | ||||
|     </div> | ||||
|           </Button> | ||||
|         </DialogActions> | ||||
|       </Dialog> | ||||
|     </Container> | ||||
|   ); | ||||
| }; | ||||
| 
 | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user