From 7a77ec00a7a6d56bc212af8e81dca23fdcd061e4 Mon Sep 17 00:00:00 2001 From: Jason Chuang Date: Sat, 8 Aug 2026 16:13:11 +0800 Subject: [PATCH] CR023 - application server-side sorting --- src/components/FiDataGrid.js | 40 ++++++++++++++++++- .../ListPanel/SearchPublicNoticeForm.js | 27 +++++++++++-- .../ListPanel/SearchPublicNoticeTable.js | 32 +++------------ src/pages/PublicNotice/Search_GLD/DataGrid.js | 17 ++++---- .../PublicNotice/Search_GLD/SearchForm.js | 27 +++++++++++-- 5 files changed, 101 insertions(+), 42 deletions(-) diff --git a/src/components/FiDataGrid.js b/src/components/FiDataGrid.js index aa427df..d64d9ec 100644 --- a/src/components/FiDataGrid.js +++ b/src/components/FiDataGrid.js @@ -14,7 +14,7 @@ import { getSearchCriteria, checkSearchCriteriaPath } from "auth/utils"; export function FiDataGrid({ rows, columns, sx, autoHeight = true, hideFooterSelectedRowCount, rowModesModel, editMode, pageSizeOptions, filterItems, customPageSize, doLoad, applyGridOnReady, applySearch, - tab, height, maxHeight, pagination = true, ...props }) { + tab, height, maxHeight, pagination = true, serverSorting = false, ...props }) { const intl = useIntl(); const [_rows, set_rows] = useState([]); const [_doLoad, set_doLoad] = useState({}); @@ -27,6 +27,7 @@ export function FiDataGrid({ rows, columns, sx, autoHeight = true, const [page, setPage] = useState(0); const [pageSize, setPageSize] = useState(10); + const [sortModel, setSortModel] = useState([]); // const [_autoHeight, set_autoHeight] = useState(true); const [myHideFooterSelectedRowCount, setMyHideFooterSelectedRowCount] = useState(true); const [_sx, set_sx] = useState({ @@ -78,11 +79,45 @@ export function FiDataGrid({ rows, columns, sx, autoHeight = true, setPage(0); setPageSize(parseInt(event.target.value, 10)); } + if (serverSorting) { + if (doLoad.params?.sort && doLoad.params?.direction) { + setSortModel([{ + field: doLoad.params.sort, + sort: String(doLoad.params.direction).toLowerCase() + }]); + } else { + setSortModel([]); + } + } set_doLoad(doLoad); setLoading(true) } }, [doLoad]); + const handleSortModelChange = (newModel) => { + if (!serverSorting) return; + setSortModel(newModel); + setPage(0); + + const params = { ...(_doLoad.params || {}) }; + if (newModel?.length > 0 && newModel[0].field && newModel[0].sort) { + params.sort = newModel[0].field; + params.direction = newModel[0].sort; + } else { + delete params.sort; + delete params.direction; + } + params.start = 0; + params.limit = pageSize; + + if (applySearch != undefined) { + applySearch(params); + } else { + set_doLoad({ ..._doLoad, params }); + setLoading(true); + } + }; + useEffect(() => { getDataList(); }, [_doLoad, page]); @@ -261,6 +296,9 @@ export function FiDataGrid({ rows, columns, sx, autoHeight = true, filterModel={{ items: _filterItems }} loading={loading} paginationMode={pagination ? "server" : undefined} + sortingMode={serverSorting ? "server" : undefined} + sortModel={serverSorting ? sortModel : undefined} + onSortModelChange={serverSorting ? handleSortModelChange : undefined} sx={{ ..._sx, '& .MuiDataGrid-virtualScroller': { diff --git a/src/pages/PublicNotice/ListPanel/SearchPublicNoticeForm.js b/src/pages/PublicNotice/ListPanel/SearchPublicNoticeForm.js index 499a53a..99655bb 100644 --- a/src/pages/PublicNotice/ListPanel/SearchPublicNoticeForm.js +++ b/src/pages/PublicNotice/ListPanel/SearchPublicNoticeForm.js @@ -95,18 +95,37 @@ const SearchPublicNoticeForm = ({ applySearch, searchCriteria, onGridReady }) => start:0, limit:10 }; + if (searchCriteria?.sort && searchCriteria?.direction) { + temp.sort = searchCriteria.sort; + temp.direction = searchCriteria.direction; + } applySearch(temp); }; function resetForm() { setType([]); setStatus(localStorage.getItem('userData').creditor?ComboData.publicNoticeStatic_Creditor[0]:ComboData.publicNoticeStatic[0]); - setMinDate(DateUtils.dateValue(new Date().setDate(new Date().getDate()-14))) - setMaxDate(DateUtils.dateValue(new Date())) + const dateFrom = DateUtils.dateValue(new Date().setDate(new Date().getDate() - 14)); + const dateTo = DateUtils.dateValue(new Date()); + setMinDate(dateFrom); + setMaxDate(dateTo); reset({ - appNo:"" + appNo: "", + careOf: "", + contact: "" + }); + localStorage.setItem('searchCriteria', ""); + // Reset form criteria and sorting first, then reload with backend default sort + applySearch({ + appNo: "", + dateFrom, + dateTo, + contact: "", + careOf: "", + status: "", + start: 0, + limit: 10 }); - localStorage.setItem('searchCriteria',"") } return ( diff --git a/src/pages/PublicNotice/ListPanel/SearchPublicNoticeTable.js b/src/pages/PublicNotice/ListPanel/SearchPublicNoticeTable.js index befa7f5..b64e07b 100644 --- a/src/pages/PublicNotice/ListPanel/SearchPublicNoticeTable.js +++ b/src/pages/PublicNotice/ListPanel/SearchPublicNoticeTable.js @@ -45,6 +45,7 @@ export default function SearchPublicNoticeTable({ searchCriteria, applyGridOnRea id: 'appNo', field: 'appNo', headerName: intl.formatMessage({ id: 'applicationId' }), + sortable: true, width: isMdOrLg ? 'auto' : 160, flex: isMdOrLg ? 1 : undefined, renderHeader: renderHeaderWithAria, @@ -56,6 +57,7 @@ export default function SearchPublicNoticeTable({ searchCriteria, applyGridOnRea id: 'created', field: 'created', headerName: intl.formatMessage({ id: 'submitDate' }), + sortable: true, width: isMdOrLg ? 'auto' : 160, flex: isMdOrLg ? 1 : undefined, renderHeader: renderHeaderWithAria, @@ -63,36 +65,11 @@ export default function SearchPublicNoticeTable({ searchCriteria, applyGridOnRea return DateUtils.datetimeStr(params?.value); } }, - // { - // id: 'contactPerson', - // field: 'contactPerson', - // headerName: '聯絡人', - // flex: 2, - // renderCell: (params) => { - // let phone = JSON.parse(params.row.contactTelNo); - // let faxNo = JSON.parse(params.row.contactFaxNo); - - // let contact = ""; - // if (phone) { - // contact = "電話: " + phone?.countryCode + " " + phone?.phoneNumber - // } - - // if (faxNo && faxNo?.faxNumber) { - // if (contact != "") - // contact = contact + ", " - // contact = contact + "傳真:" + faxNo?.countryCode + " " + faxNo?.faxNumber - // } - - // return (<> - // {params?.value}
- // {contact} - // ); - // } - // }, { id: 'remarks', field: 'remarks', headerName: isORGLoggedIn() ? intl.formatMessage({ id: 'gazetteCount2_1' }) : intl.formatMessage({ id: 'myRemarks' }), + sortable: true, width: isMdOrLg ? 'auto' : 400, flex: isMdOrLg ? 3 : undefined, renderHeader: renderHeaderWithAria, @@ -124,6 +101,7 @@ export default function SearchPublicNoticeTable({ searchCriteria, applyGridOnRea id: 'status', field: 'status', headerName: intl.formatMessage({ id: 'status' }), + sortable: true, width: 200, renderHeader: renderHeaderWithAria, renderCell: (params) => { @@ -134,6 +112,7 @@ export default function SearchPublicNoticeTable({ searchCriteria, applyGridOnRea field: 'actions', type: 'actions', headerName: '', + sortable: false, width: 150, renderHeader: renderHeaderWithAria, cellClassName: 'actions', @@ -157,6 +136,7 @@ export default function SearchPublicNoticeTable({ searchCriteria, applyGridOnRea 'auto'} onRowDoubleClick={handleRowDoubleClick} applyGridOnReady = {applyGridOnReady} diff --git a/src/pages/PublicNotice/Search_GLD/DataGrid.js b/src/pages/PublicNotice/Search_GLD/DataGrid.js index 214f7de..d00ca7d 100644 --- a/src/pages/PublicNotice/Search_GLD/DataGrid.js +++ b/src/pages/PublicNotice/Search_GLD/DataGrid.js @@ -67,9 +67,9 @@ export default function SearchPublicNoticeTable({ searchCriteria, applyGridOnRea const columns = [ { - field: 'actions', + field: 'appNo', headerName: 'Application No.', - sortable: false, + sortable: true, width: 150, cellClassName: 'actions', renderHeader: renderHeaderWithAria, @@ -81,7 +81,7 @@ export default function SearchPublicNoticeTable({ searchCriteria, applyGridOnRea id: 'mode', field: 'mode', headerName: 'Mode', - sortable: false, + sortable: true, width: 100, renderHeader: renderHeaderWithAria, renderCell: (params) => { @@ -92,7 +92,7 @@ export default function SearchPublicNoticeTable({ searchCriteria, applyGridOnRea id: 'status', field: 'status', headerName: 'Status', - sortable: false, + sortable: true, width: 240, renderHeader: renderHeaderWithAria, renderCell: (params) => { @@ -103,7 +103,7 @@ export default function SearchPublicNoticeTable({ searchCriteria, applyGridOnRea id: 'withProof', field: 'withProof', headerName: 'With Proof', - sortable: false, + sortable: true, width: 120, renderHeader: renderHeaderWithAria, renderCell: (params) => { @@ -114,7 +114,7 @@ export default function SearchPublicNoticeTable({ searchCriteria, applyGridOnRea id: 'created', field: 'created', headerName: 'Submit Date', - sortable: false, + sortable: true, flex: 1, minWidth: 200, renderHeader: renderHeaderWithAria, @@ -126,7 +126,7 @@ export default function SearchPublicNoticeTable({ searchCriteria, applyGridOnRea id: 'contactPerson', field: 'contactPerson', headerName: 'Client / Payment Means', - sortable: false, + sortable: true, minWidth: 250, flex: 2, renderHeader: renderHeaderWithAria, @@ -146,7 +146,7 @@ export default function SearchPublicNoticeTable({ searchCriteria, applyGridOnRea id: 'issueNoAndCode', field: 'issueNoAndCode', headerName: 'Gazette Issue No. / Gazette Code', - sortable: false, + sortable: true, flex: 1.5, minWidth: 350, renderHeader: renderHeaderWithAria, @@ -220,6 +220,7 @@ export default function SearchPublicNoticeTable({ searchCriteria, applyGridOnRea { setSelectedRowItems(newSelection); }} diff --git a/src/pages/PublicNotice/Search_GLD/SearchForm.js b/src/pages/PublicNotice/Search_GLD/SearchForm.js index 664c69d..2d26630 100644 --- a/src/pages/PublicNotice/Search_GLD/SearchForm.js +++ b/src/pages/PublicNotice/Search_GLD/SearchForm.js @@ -96,6 +96,10 @@ const SearchPublicNoticeForm = ({ applySearch, searchCriteria, issueComboData, o start:0, limit:10 }; + if (searchCriteria?.sort && searchCriteria?.direction) { + temp.sort = searchCriteria.sort; + temp.direction = searchCriteria.direction; + } applySearch(temp); // setSearchReady(true) }; @@ -117,14 +121,31 @@ const SearchPublicNoticeForm = ({ applySearch, searchCriteria, issueComboData, o setGroupSelected({}); setSelectedStatus({key: 0, label: 'All', type: 'all'}); setSelectedMode({key: 0, label: 'All', type: 'all'}); - setMinDate(DateUtils.dateValue(new Date().setDate(new Date().getDate()-14))) - setMaxDate(DateUtils.dateValue(new Date())) + const dateFrom = DateUtils.dateValue(new Date().setDate(new Date().getDate() - 14)); + const dateTo = DateUtils.dateValue(new Date()); + setMinDate(dateFrom); + setMaxDate(dateTo); reset({ appNo:"", contact:"", groupNo:"" }); - localStorage.setItem('searchCriteria',"") + localStorage.setItem('searchCriteria',""); + // Reset form criteria and sorting first, then reload with backend default sort + applySearch({ + appNo: "", + dateFrom, + dateTo, + contact: "", + status: "", + orgId: "", + issueId: "", + groupNo: "", + gazettGroup: "", + mode: "", + start: 0, + limit: 10 + }); } const getIssueLabel=(data)=> {