| @@ -50,116 +50,112 @@ const ClientPanel = () => { | |||||
| //const [tagCombo, setTagCombo] = useState({}); | //const [tagCombo, setTagCombo] = useState({}); | ||||
| function updateApplicationDetail(applicationData) { | |||||
| setApplicationDetail(applicationData); | |||||
| } | |||||
| // function updateApplicationDetail(applicationData) { | |||||
| // setApplicationDetail(applicationData); | |||||
| // } | |||||
| useEffect(() => { | useEffect(() => { | ||||
| getReminderInterval(); | |||||
| getReminderBefore(); | |||||
| getReminderLimit(); | |||||
| getReminderLimitMax(); | |||||
| // getReminderInterval(); | |||||
| // getReminderBefore(); | |||||
| // getReminderLimit(); | |||||
| // getReminderLimitMax(); | |||||
| if(refId !== null){ | if(refId !== null){ | ||||
| setIsNewRecord(true); | |||||
| setIsNewRecord(false); | |||||
| getClientDetail(refId); | getClientDetail(refId); | ||||
| } | } | ||||
| else if(params.id<0){ | else if(params.id<0){ | ||||
| setIsNewRecord(true); | setIsNewRecord(true); | ||||
| } | } | ||||
| else{ | else{ | ||||
| setIsNewRecord(false); | |||||
| getClientDetail(params.id); | getClientDetail(params.id); | ||||
| } | } | ||||
| getGroupList(); | |||||
| getApplicationList(); | |||||
| }, []); | |||||
| function getReminderBefore(){ | |||||
| axios.get(`${apiPath}${GET_REMINDER_BEFORE}`, | |||||
| ) | |||||
| .then((response) => { | |||||
| if (response.status === 200) { | |||||
| setReminderBefore(response.data.data); | |||||
| } | |||||
| }) | |||||
| .catch(error => { | |||||
| console.log(error); | |||||
| return false; | |||||
| }); | |||||
| } | |||||
| function getReminderLimit(){ | |||||
| axios.get(`${apiPath}${GET_REMINDER_LIMIT}`, | |||||
| ) | |||||
| .then((response) => { | |||||
| if (response.status === 200) { | |||||
| setReminderLimit(response.data.data); | |||||
| } | |||||
| }) | |||||
| .catch(error => { | |||||
| console.log(error); | |||||
| return false; | |||||
| }); | |||||
| } | |||||
| function getReminderLimitMax(){ | |||||
| axios.get(`${apiPath}${GET_REMINDER_LIMIT_MAX}`, | |||||
| ) | |||||
| .then((response) => { | |||||
| if (response.status === 200) { | |||||
| setReminderLimitMax(response.data.data); | |||||
| } | |||||
| }) | |||||
| .catch(error => { | |||||
| console.log(error); | |||||
| return false; | |||||
| }); | |||||
| } | |||||
| // getGroupList(); | |||||
| // getApplicationList(); | |||||
| }, [refId, params.id]); | |||||
| // function getReminderBefore(){ | |||||
| // axios.get(`${apiPath}${GET_REMINDER_BEFORE}`, | |||||
| // ) | |||||
| // .then((response) => { | |||||
| // if (response.status === 200) { | |||||
| // setReminderBefore(response.data.data); | |||||
| // } | |||||
| // }) | |||||
| // .catch(error => { | |||||
| // console.log(error); | |||||
| // return false; | |||||
| // }); | |||||
| // } | |||||
| // function getReminderLimit(){ | |||||
| // axios.get(`${apiPath}${GET_REMINDER_LIMIT}`, | |||||
| // ) | |||||
| // .then((response) => { | |||||
| // if (response.status === 200) { | |||||
| // setReminderLimit(response.data.data); | |||||
| // } | |||||
| // }) | |||||
| // .catch(error => { | |||||
| // console.log(error); | |||||
| // return false; | |||||
| // }); | |||||
| // } | |||||
| // function getReminderLimitMax(){ | |||||
| // axios.get(`${apiPath}${GET_REMINDER_LIMIT_MAX}`, | |||||
| // ) | |||||
| // .then((response) => { | |||||
| // if (response.status === 200) { | |||||
| // setReminderLimitMax(response.data.data); | |||||
| // } | |||||
| // }) | |||||
| // .catch(error => { | |||||
| // console.log(error); | |||||
| // return false; | |||||
| // }); | |||||
| // } | |||||
| useEffect(() => { | useEffect(() => { | ||||
| if (!isObjEmpty(subDivisionCombo)) { | |||||
| setOnReady(true); | |||||
| } | |||||
| else if(isNewRecord && | |||||
| Object.keys(clientDetail).length > 0 | |||||
| ){ | |||||
| if(isNewRecord || Object.keys(clientDetail).length > 0) { | |||||
| setOnReady(true); | setOnReady(true); | ||||
| } | } | ||||
| }, [subDivisionCombo,clientDetail]); | |||||
| function getApplicationList(){ | |||||
| const byDivision = { | |||||
| clientId: params.id, | |||||
| userSubDivisionId: ability.can('VIEW', 'ALL_RECORD') ? null : localStorage.getItem('subDivisionId'), | |||||
| } | |||||
| axios.get(`${apiPath}${GET_EVENT_APPLICATION_PATH}`, | |||||
| { | |||||
| params: byDivision, | |||||
| } | |||||
| ) | |||||
| .then((response) => { | |||||
| if (response.status === 200) { | |||||
| setApplicationList(response.data.records); | |||||
| } | |||||
| }) | |||||
| .catch(error => { | |||||
| console.log(error); | |||||
| return false; | |||||
| }); | |||||
| } | |||||
| function getReminderInterval(){ | |||||
| axios.get(`${apiPath}${GET_REMINDER_INTERVAL}`, | |||||
| ) | |||||
| .then((response) => { | |||||
| if (response.status === 200) { | |||||
| setReminderInterval(response.data.data); | |||||
| } | |||||
| }) | |||||
| .catch(error => { | |||||
| console.log(error); | |||||
| return false; | |||||
| }); | |||||
| } | |||||
| }, [isNewRecord, clientDetail]); | |||||
| // function getApplicationList(){ | |||||
| // const byDivision = { | |||||
| // clientId: params.id, | |||||
| // userSubDivisionId: ability.can('VIEW', 'ALL_RECORD') ? null : localStorage.getItem('subDivisionId'), | |||||
| // } | |||||
| // axios.get(`${apiPath}${GET_EVENT_APPLICATION_PATH}`, | |||||
| // { | |||||
| // params: byDivision, | |||||
| // } | |||||
| // ) | |||||
| // .then((response) => { | |||||
| // if (response.status === 200) { | |||||
| // setApplicationList(response.data.records); | |||||
| // } | |||||
| // }) | |||||
| // .catch(error => { | |||||
| // console.log(error); | |||||
| // return false; | |||||
| // }); | |||||
| // } | |||||
| // function getReminderInterval(){ | |||||
| // axios.get(`${apiPath}${GET_REMINDER_INTERVAL}`, | |||||
| // ) | |||||
| // .then((response) => { | |||||
| // if (response.status === 200) { | |||||
| // setReminderInterval(response.data.data); | |||||
| // } | |||||
| // }) | |||||
| // .catch(error => { | |||||
| // console.log(error); | |||||
| // return false; | |||||
| // }); | |||||
| // } | |||||
| function getClientDetail(clientId) { | function getClientDetail(clientId) { | ||||
| axios.get(`${apiPath}${GET_CLIENT_PATH}/${clientId}`, | axios.get(`${apiPath}${GET_CLIENT_PATH}/${clientId}`, | ||||
| @@ -167,7 +163,7 @@ const ClientPanel = () => { | |||||
| .then((response) => { | .then((response) => { | ||||
| if (response.status === 200) { | if (response.status === 200) { | ||||
| setClientDetail(response.data.data); | setClientDetail(response.data.data); | ||||
| setRefSubDivisionList(response.data.clientDivision); | |||||
| // setRefSubDivisionList(response.data.clientDivision); | |||||
| } | } | ||||
| }) | }) | ||||
| .catch(error => { | .catch(error => { | ||||
| @@ -176,19 +172,19 @@ const ClientPanel = () => { | |||||
| }); | }); | ||||
| } | } | ||||
| function getGroupList() { | |||||
| axios.get(`${apiPath}${GET_SUB_DIVISION_COMBO_LIST}`, | |||||
| ) | |||||
| .then((response) => { | |||||
| if (response.status === 200) { | |||||
| setSubDivisionCombo(response.data.records); | |||||
| } | |||||
| }) | |||||
| .catch(error => { | |||||
| console.log(error); | |||||
| return false; | |||||
| }); | |||||
| } | |||||
| // function getGroupList() { | |||||
| // axios.get(`${apiPath}${GET_SUB_DIVISION_COMBO_LIST}`, | |||||
| // ) | |||||
| // .then((response) => { | |||||
| // if (response.status === 200) { | |||||
| // setSubDivisionCombo(response.data.records); | |||||
| // } | |||||
| // }) | |||||
| // .catch(error => { | |||||
| // console.log(error); | |||||
| // return false; | |||||
| // }); | |||||
| // } | |||||
| return ( | return ( | ||||
| !onReady ? | !onReady ? | ||||
| @@ -209,35 +205,11 @@ const ClientPanel = () => { | |||||
| {/*row 1*/} | {/*row 1*/} | ||||
| <Grid item xs={12} md={12} lg={12} > | <Grid item xs={12} md={12} lg={12} > | ||||
| <ClientForm | <ClientForm | ||||
| refReminderInterval={reminderInterval} | |||||
| refReminderBefore={reminderBefore} | |||||
| refReminderLimit={reminderLimit} | |||||
| refReminderLimitMax={reminderLimitMax} | |||||
| applicationList={applicationList} | |||||
| getClientDetail={getClientDetail} | getClientDetail={getClientDetail} | ||||
| refClientDetail={clientDetail} | refClientDetail={clientDetail} | ||||
| applicationDetail={applicationDetail} | |||||
| updateApplicationDetail={updateApplicationDetail} | |||||
| isNewRecord={isNewRecord} | isNewRecord={isNewRecord} | ||||
| refSubDivisionList={refSubDivisionList} | |||||
| /> | /> | ||||
| </Grid> | </Grid> | ||||
| {/*row 2*/} | |||||
| { | |||||
| params.id > 0 ? | |||||
| <Grid item xs={12} md={12} lg={12}> | |||||
| <MainCard | |||||
| sx={{width:CARD_MAX_WIDTH}} | |||||
| > | |||||
| <ThemeProvider theme={LIONER_FORM_THEME}> | |||||
| <ApplicationTable recordList={applicationList}/> | |||||
| </ThemeProvider> | |||||
| </MainCard> | |||||
| </Grid> | |||||
| : | |||||
| undefined | |||||
| } | |||||
| </ThemeProvider> | </ThemeProvider> | ||||
| </Grid> | </Grid> | ||||
| @@ -469,7 +469,6 @@ const ClientSearchForm = ({applySearch, setExpanded,expanded}) => { | |||||
| variant="contained" | variant="contained" | ||||
| color="create" | color="create" | ||||
| onClick={createNewClient} | onClick={createNewClient} | ||||
| disabled='true' | |||||
| > | > | ||||
| New Client | New Client | ||||
| </Button> | </Button> | ||||
| @@ -51,7 +51,7 @@ export default function ClientTable({recordList}) { | |||||
| className="textPrimary" | className="textPrimary" | ||||
| onClick={handleEditClick(id)} | onClick={handleEditClick(id)} | ||||
| color="edit" | color="edit" | ||||
| disabled={'true'} | |||||
| // disabled={'true'} | |||||
| // disabled={!ability.can('VIEW','DASHBOARD')} | // disabled={!ability.can('VIEW','DASHBOARD')} | ||||
| /> | /> | ||||
| </ThemeProvider> | </ThemeProvider> | ||||
| @@ -81,7 +81,7 @@ export default function ClientTable({recordList}) { | |||||
| renderCell: (params) => { | renderCell: (params) => { | ||||
| return ( | return ( | ||||
| <div style={{display: 'flex', alignItems: 'center', justifyContent: 'center', whiteSpace: 'normal', wordBreak: 'break-word'}}> | <div style={{display: 'flex', alignItems: 'center', justifyContent: 'center', whiteSpace: 'normal', wordBreak: 'break-word'}}> | ||||
| ({params.row.title}) {params.value} | |||||
| {params.row.title ? `(${params.row.title})` : ''} {params.value} | |||||
| </div> | </div> | ||||
| ); | ); | ||||
| } | } | ||||
| @@ -94,7 +94,6 @@ export default function ClientTable({recordList}) { | |||||
| sortComparator: dateComparator, | sortComparator: dateComparator, | ||||
| renderCell: (params) => ( | renderCell: (params) => ( | ||||
| <div> | <div> | ||||
| {/* {formattedDate = date.toLocaleDateString()} */} | |||||
| {getDateString(params.row.joinDate, 'dd/MM/yyyy')} | {getDateString(params.row.joinDate, 'dd/MM/yyyy')} | ||||
| </div> | </div> | ||||
| ), | ), | ||||
| @@ -78,8 +78,8 @@ const ClientSearchPage = () => { | |||||
| // }, []); | // }, []); | ||||
| function applySearch(input) { | function applySearch(input) { | ||||
| console.log("SearchCriteria:") | |||||
| console.log(input) | |||||
| // console.log("SearchCriteria:") | |||||
| // console.log(input) | |||||
| setSearchCriteria(input); | setSearchCriteria(input); | ||||
| } | } | ||||
| @@ -2,6 +2,10 @@ | |||||
| import React, { useEffect, useRef, useState } from 'react'; | import React, { useEffect, useRef, useState } from 'react'; | ||||
| // import './App.css'; // For basic styling | // import './App.css'; // For basic styling | ||||
| import axios from 'axios'; | import axios from 'axios'; | ||||
| import {apiPath} from "../../auth/utils"; | |||||
| import { | |||||
| GET_PDF_PATH | |||||
| } from "../../utils/ApiPathConst"; | |||||
| // Import your chosen commercial PDF SDK (e.g., PSPDFKit) | // Import your chosen commercial PDF SDK (e.g., PSPDFKit) | ||||
| import PSPDFKit from 'pspdfkit'; | import PSPDFKit from 'pspdfkit'; | ||||
| @@ -10,28 +14,48 @@ function PDF() { | |||||
| const viewerRef = useRef(null); // Ref for the DOM element where PDF will render | const viewerRef = useRef(null); // Ref for the DOM element where PDF will render | ||||
| const instanceRef = useRef(null); // Ref for the PSPDFKit instance | const instanceRef = useRef(null); // Ref for the PSPDFKit instance | ||||
| const [pdfLoaded, setPdfLoaded] = useState(false); | const [pdfLoaded, setPdfLoaded] = useState(false); | ||||
| const [template,setTemplate] = useState(); | |||||
| const [viewInstance,setViewInstance] = useState(); | |||||
| useEffect(() => { | useEffect(() => { | ||||
| const loadPdfViewer = async () => { | const loadPdfViewer = async () => { | ||||
| if (viewerRef.current) { | |||||
| if (document.getElementById(viewerRef)) { | |||||
| // if (viewerRef.current) { | |||||
| try { | try { | ||||
| // 1. Fetch the blank PDF template from your Spring Boot backend | |||||
| const response = await axios.get('http://localhost:8090/api/pdf/template', { | |||||
| responseType: 'arraybuffer' // Essential for binary data | |||||
| //New try | |||||
| axios.get(`${apiPath}${GET_PDF_PATH}`, { | |||||
| responseType: 'arraybuffer', // Essential for binary data | |||||
| }) | |||||
| .then((response) => { | |||||
| if (response.status === 200) { | |||||
| setTemplate(response); | |||||
| } | |||||
| }) | |||||
| .catch(error => { | |||||
| console.log(error); | |||||
| return false; | |||||
| }); | }); | ||||
| const pdfBlob = new Blob([response.data], { type: 'application/pdf' }); | |||||
| // 1. Fetch the blank PDF template from your Spring Boot backend | |||||
| // const response = await axios.get(`${apiPath}${GET_PDF_PATH}`, { | |||||
| // responseType: 'arraybuffer', // Essential for binary data | |||||
| // }); | |||||
| const pdfBlob = new Blob(template, { type: 'application/pdf' }); | |||||
| const pdfUrl = URL.createObjectURL(pdfBlob); | const pdfUrl = URL.createObjectURL(pdfBlob); | ||||
| // 2. Initialize the PDF SDK (e.g., PSPDFKit) | // 2. Initialize the PDF SDK (e.g., PSPDFKit) | ||||
| console.log(template); | |||||
| const instance = await PSPDFKit.load({ | const instance = await PSPDFKit.load({ | ||||
| container: viewerRef.current, | |||||
| // setViewInstance(await PSPDFKit.load({ | |||||
| container: document.getElementById(viewerRef),//viewerRef.current, | |||||
| document: pdfUrl, | document: pdfUrl, | ||||
| // Remember to add your SDK license key if applicable | // Remember to add your SDK license key if applicable | ||||
| // licenseKey: "YOUR_PSPDFKIT_LICENSE_KEY", | // licenseKey: "YOUR_PSPDFKIT_LICENSE_KEY", | ||||
| baseUrl: process.env.PUBLIC_URL + '/pspdfkit-lib/', // Path to SDK assets | |||||
| baseUrl: `${process.env.PUBLIC_URL}/pspdfkit-lib/`//, // Path to SDK assets | |||||
| // Enable form filling UI | // Enable form filling UI | ||||
| formDesignerViewMode: PSPDFKit.FormDesignerViewMode.Enabled | |||||
| // formDesignerViewMode: PSPDFKit.FormDesignerViewMode.Enabled | |||||
| }); | }); | ||||
| // })); | |||||
| instanceRef.current = instance; | instanceRef.current = instance; | ||||
| setPdfLoaded(true); | setPdfLoaded(true); | ||||
| @@ -104,7 +128,7 @@ function PDF() { | |||||
| )} | )} | ||||
| </header> | </header> | ||||
| <div | <div | ||||
| ref={viewerRef} | |||||
| id={viewerRef} | |||||
| className="pdf-viewer-container" | className="pdf-viewer-container" | ||||
| style={{ | style={{ | ||||
| width: '100%', | width: '100%', | ||||
| @@ -10,7 +10,6 @@ import AbilityContext from "../components/AbilityProvider"; | |||||
| // render - login | // render - login | ||||
| const ClientSearchPage = Loadable(lazy( () => import('pages/client/ClientSearchPage'))); | const ClientSearchPage = Loadable(lazy( () => import('pages/client/ClientSearchPage'))); | ||||
| const ClientMaintainPage = Loadable(lazy( () => import('pages/client/ClientMaintainPage'))); | const ClientMaintainPage = Loadable(lazy( () => import('pages/client/ClientMaintainPage'))); | ||||
| const PDF = Loadable(lazy( () => import('pages/pdf'))); | |||||
| // ==============================|| AUTH ROUTING ||============================== // | // ==============================|| AUTH ROUTING ||============================== // | ||||
| @@ -41,16 +40,6 @@ const ClientRoutes =() => { | |||||
| ) | ) | ||||
| ), | ), | ||||
| }, | }, | ||||
| { | |||||
| path: 'pdf', | |||||
| element: ( | |||||
| handleRouteAbility( | |||||
| ability.can('VIEW', 'DASHBOARD'), | |||||
| <PDF />, | |||||
| <Navigate to="/" /> | |||||
| ) | |||||
| ), | |||||
| }, | |||||
| ] | ] | ||||
| }; | }; | ||||
| }; | }; | ||||
| @@ -59,6 +59,7 @@ export const DELETE_FILE_PATH = "/file" | |||||
| export const GET_FILE_PATH = "/file/dl" | export const GET_FILE_PATH = "/file/dl" | ||||
| export const GET_THUMBNAIL_PATH = "/file/thumbnail" | export const GET_THUMBNAIL_PATH = "/file/thumbnail" | ||||
| export const POST_THUMBNAIL_PATH = "/file/thumbnail/ul" | export const POST_THUMBNAIL_PATH = "/file/thumbnail/ul" | ||||
| export const GET_PDF_PATH = "/pdf/template" | |||||
| export const GET_CLIENT_PATH = "/client" | export const GET_CLIENT_PATH = "/client" | ||||
| export const POST_CLIENT_PATH = "/client/save" | export const POST_CLIENT_PATH = "/client/save" | ||||
| export const GET_EVENT_PATH = "/event" | export const GET_EVENT_PATH = "/event" | ||||
| @@ -261,11 +261,11 @@ export function removeObjectWithId(arr, id) { | |||||
| /** | /** | ||||
| * Display the date array in string format, default format is 'yyyy-MM-dd'. | * Display the date array in string format, default format is 'yyyy-MM-dd'. | ||||
| * | * | ||||
| * @param {*} queryDateArray - The date array to display. | |||||
| * @param {*} dateInput - The date value to be displayed, can be array or timestamp. | |||||
| * @param {*} [formatOption] - Set to True to display also the timestamp, or input custom format text. | * @param {*} [formatOption] - Set to True to display also the timestamp, or input custom format text. | ||||
| */ | */ | ||||
| export function getDateString(queryDateArray, formatOption=false) { | |||||
| if (queryDateArray === null || queryDateArray === undefined) { | |||||
| export function getDateString(dateInput, formatOption=false) { | |||||
| if (dateInput === null || dateInput === undefined) { | |||||
| return null; | return null; | ||||
| } | } | ||||
| @@ -276,17 +276,26 @@ export function getDateString(queryDateArray, formatOption=false) { | |||||
| dateFormat = formatOption; | dateFormat = formatOption; | ||||
| } | } | ||||
| return format( | |||||
| new Date( | |||||
| let inputType = 0; // Array | |||||
| if (!Array.isArray(dateInput)) { | |||||
| inputType = 1; | |||||
| } | |||||
| let date = new Date(); | |||||
| if (inputType == 0) { | |||||
| let queryDateArray = dateInput; | |||||
| date = new Date( | |||||
| queryDateArray[0], | queryDateArray[0], | ||||
| queryDateArray[1]-1, | queryDateArray[1]-1, | ||||
| queryDateArray[2], | queryDateArray[2], | ||||
| queryDateArray[3] !== undefined ? queryDateArray[3] : 0, | queryDateArray[3] !== undefined ? queryDateArray[3] : 0, | ||||
| queryDateArray[4] !== undefined ? queryDateArray[4] : 0, | queryDateArray[4] !== undefined ? queryDateArray[4] : 0, | ||||
| queryDateArray[5] !== undefined ? queryDateArray[5] : 0 | queryDateArray[5] !== undefined ? queryDateArray[5] : 0 | ||||
| ), | |||||
| dateFormat | |||||
| ); | |||||
| ); | |||||
| } else { | |||||
| date = new Date(dateInput); | |||||
| } | |||||
| return format(date, dateFormat); | |||||
| } | } | ||||
| export const isOptionEqualToValue = (option, value) => { | export const isOptionEqualToValue = (option, value) => { | ||||