From 664e815441cb9d7271fc9667f0d1438a0d3d35d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Yoshioka=20Tsuneo=20=28=E5=90=89=E5=B2=A1=20=E6=81=92?= =?UTF-8?q?=E5=A4=AB=29?= Date: Sat, 8 Mar 2025 16:44:13 +0900 Subject: [PATCH 1/2] Fix item list sorting --- .../app/components/items-list/ItemsList.tsx | 4 ++- .../items-list/classes/ItemsSource.js | 7 +++++ .../items-list/components/ItemsTable.jsx | 29 +++++++++++++++---- client/app/pages/queries-list/QueriesList.jsx | 1 + 4 files changed, 35 insertions(+), 6 deletions(-) diff --git a/client/app/components/items-list/ItemsList.tsx b/client/app/components/items-list/ItemsList.tsx index 4ef13790f4..c13cb809b4 100644 --- a/client/app/components/items-list/ItemsList.tsx +++ b/client/app/components/items-list/ItemsList.tsx @@ -28,6 +28,7 @@ export interface Controller { orderByField?: string; orderByReverse: boolean; toggleSorting: (orderByField: string) => void; + setSorting: (orderByField: string, orderByReverse: boolean) => void; // pagination page: number; @@ -139,10 +140,11 @@ export function wrap( this.props.onError!(error); const initialState = this.getState({ ...itemsSource.getState(), isLoaded: false }); - const { updatePagination, toggleSorting, updateSearch, updateSelectedTags, update, handleError } = itemsSource; + const { updatePagination, toggleSorting, setSorting, updateSearch, updateSelectedTags, update, handleError } = itemsSource; this.state = { ...initialState, toggleSorting, // eslint-disable-line react/no-unused-state + setSorting, // eslint-disable-line react/no-unused-state updateSearch: debounce(updateSearch, 200), // eslint-disable-line react/no-unused-state updateSelectedTags, // eslint-disable-line react/no-unused-state updatePagination, // eslint-disable-line react/no-unused-state diff --git a/client/app/components/items-list/classes/ItemsSource.js b/client/app/components/items-list/classes/ItemsSource.js index f32e8ee3a8..f44f98ecab 100644 --- a/client/app/components/items-list/classes/ItemsSource.js +++ b/client/app/components/items-list/classes/ItemsSource.js @@ -130,6 +130,13 @@ export class ItemsSource { this._changed({ sorting: true }); }; + setSorting = (orderByField, orderByReverse) => { + this._sorter.setField(orderByField); + this._sorter.setReverse(orderByReverse); + this._savedOrderByField = this._sorter.field; + this._changed({ sorting: true }); + }; + updateSearch = searchTerm => { // here we update state directly, but later `fetchData` will update it properly this._searchTerm = searchTerm; diff --git a/client/app/components/items-list/components/ItemsTable.jsx b/client/app/components/items-list/components/ItemsTable.jsx index 87e41ed180..78a9828646 100644 --- a/client/app/components/items-list/components/ItemsTable.jsx +++ b/client/app/components/items-list/components/ItemsTable.jsx @@ -110,6 +110,7 @@ export default class ItemsTable extends React.Component { orderByField: PropTypes.string, orderByReverse: PropTypes.bool, toggleSorting: PropTypes.func, + setSorting: PropTypes.func, "data-test": PropTypes.string, rowKey: PropTypes.oneOfType([PropTypes.string, PropTypes.func]), }; @@ -127,7 +128,7 @@ export default class ItemsTable extends React.Component { }; prepareColumns() { - const { orderByField, orderByReverse, toggleSorting } = this.props; + const { orderByField, orderByReverse } = this.props; const orderByDirection = orderByReverse ? "descend" : "ascend"; return map( @@ -136,9 +137,6 @@ export default class ItemsTable extends React.Component { column => extend(column, { orderByField: column.orderByField || column.field }) ), (column, index) => { - // Bind click events only to sortable columns - const onHeaderCell = column.sorter ? () => ({ onClick: () => toggleSorting(column.orderByField) }) : null; - // Wrap render function to pass correct arguments const render = isFunction(column.render) ? (text, row) => column.render(text, row.item) : identity; @@ -146,7 +144,6 @@ export default class ItemsTable extends React.Component { key: "column" + index, dataIndex: ["item", column.field], defaultSortOrder: column.orderByField === orderByField ? orderByDirection : null, - onHeaderCell, render, }); } @@ -179,6 +176,27 @@ export default class ItemsTable extends React.Component { }) : null; + const onChange = (pagination, filters, sorter, extra) => { + const action = extra?.action; + if (action === "sort") { + const propsColumn = this.props.columns.find(column => column.field === sorter.field[1]); + if (!propsColumn.sorter) { + return; + } + let orderByField = propsColumn.orderByField; + const orderByReverse = sorter.order === "descend"; + + if (orderByReverse === undefined) { + orderByField = null; + } + if (this.props.setSorting) { + this.props.setSorting(orderByField, orderByReverse); + } else { + this.props.toggleSorting(orderByField); + } + } + }; + const { showHeader } = this.props; if (this.props.loading) { if (isEmpty(tableDataProps.dataSource)) { @@ -200,6 +218,7 @@ export default class ItemsTable extends React.Component { rowKey={this.getRowKey} pagination={false} onRow={onTableRow} + onChange={onChange} data-test={this.props["data-test"]} {...tableDataProps} /> diff --git a/client/app/pages/queries-list/QueriesList.jsx b/client/app/pages/queries-list/QueriesList.jsx index f49358d457..be220ed96a 100644 --- a/client/app/pages/queries-list/QueriesList.jsx +++ b/client/app/pages/queries-list/QueriesList.jsx @@ -160,6 +160,7 @@ function QueriesList({ controller }) { orderByField={controller.orderByField} orderByReverse={controller.orderByReverse} toggleSorting={controller.toggleSorting} + setSorting={controller.setSorting} /> Date: Sun, 9 Mar 2025 00:32:02 +0900 Subject: [PATCH 2/2] fix styling for restyled report --- .../items-list/classes/ItemsSource.js | 18 +++++++------- .../items-list/components/ItemsTable.jsx | 24 +++++++++---------- client/app/pages/queries-list/QueriesList.jsx | 14 +++++------ 3 files changed, 27 insertions(+), 29 deletions(-) diff --git a/client/app/components/items-list/classes/ItemsSource.js b/client/app/components/items-list/classes/ItemsSource.js index f44f98ecab..583541874c 100644 --- a/client/app/components/items-list/classes/ItemsSource.js +++ b/client/app/components/items-list/classes/ItemsSource.js @@ -39,14 +39,12 @@ export class ItemsSource { const customParams = {}; const context = { ...this.getCallbackContext(), - setCustomParams: params => { + setCustomParams: (params) => { extend(customParams, params); }, }; return this._beforeUpdate().then(() => { - const fetchToken = Math.random() - .toString(36) - .substr(2); + const fetchToken = Math.random().toString(36).substr(2); this._currentFetchToken = fetchToken; return this._fetcher .fetch(changes, state, context) @@ -59,7 +57,7 @@ export class ItemsSource { return this._afterUpdate(); } }) - .catch(error => this.handleError(error)); + .catch((error) => this.handleError(error)); }); } @@ -124,7 +122,7 @@ export class ItemsSource { }); }; - toggleSorting = orderByField => { + toggleSorting = (orderByField) => { this._sorter.toggleField(orderByField); this._savedOrderByField = this._sorter.field; this._changed({ sorting: true }); @@ -137,7 +135,7 @@ export class ItemsSource { this._changed({ sorting: true }); }; - updateSearch = searchTerm => { + updateSearch = (searchTerm) => { // here we update state directly, but later `fetchData` will update it properly this._searchTerm = searchTerm; // in search mode ignore the ordering and use the ranking order @@ -152,7 +150,7 @@ export class ItemsSource { this._changed({ search: true, pagination: { page: true } }); }; - updateSelectedTags = selectedTags => { + updateSelectedTags = (selectedTags) => { this._selectedTags = selectedTags; this._paginator.setPage(1); this._changed({ tags: true, pagination: { page: true } }); @@ -160,7 +158,7 @@ export class ItemsSource { update = () => this._changed(); - handleError = error => { + handleError = (error) => { if (isFunction(this.onError)) { this.onError(error); } @@ -179,7 +177,7 @@ export class ResourceItemsSource extends ItemsSource { processResults: (results, context) => { let processItem = getItemProcessor(context); processItem = isFunction(processItem) ? processItem : identity; - return map(results, item => processItem(item, context)); + return map(results, (item) => processItem(item, context)); }, }); } diff --git a/client/app/components/items-list/components/ItemsTable.jsx b/client/app/components/items-list/components/ItemsTable.jsx index 78a9828646..496bb3c8cd 100644 --- a/client/app/components/items-list/components/ItemsTable.jsx +++ b/client/app/components/items-list/components/ItemsTable.jsx @@ -44,7 +44,7 @@ export const Columns = { date(overrides) { return extend( { - render: text => formatDate(text), + render: (text) => formatDate(text), }, overrides ); @@ -52,7 +52,7 @@ export const Columns = { dateTime(overrides) { return extend( { - render: text => formatDateTime(text), + render: (text) => formatDateTime(text), }, overrides ); @@ -62,7 +62,7 @@ export const Columns = { { width: "1%", className: "text-nowrap", - render: text => durationHumanize(text), + render: (text) => durationHumanize(text), }, overrides ); @@ -70,7 +70,7 @@ export const Columns = { timeAgo(overrides, timeAgoCustomProps = undefined) { return extend( { - render: value => , + render: (value) => , }, overrides ); @@ -133,8 +133,8 @@ export default class ItemsTable extends React.Component { return map( map( - filter(this.props.columns, column => (isFunction(column.isAvailable) ? column.isAvailable() : true)), - column => extend(column, { orderByField: column.orderByField || column.field }) + filter(this.props.columns, (column) => (isFunction(column.isAvailable) ? column.isAvailable() : true)), + (column) => extend(column, { orderByField: column.orderByField || column.field }) ), (column, index) => { // Wrap render function to pass correct arguments @@ -150,7 +150,7 @@ export default class ItemsTable extends React.Component { ); } - getRowKey = record => { + getRowKey = (record) => { const { rowKey } = this.props; if (rowKey) { if (isFunction(rowKey)) { @@ -169,8 +169,8 @@ export default class ItemsTable extends React.Component { // Bind events only if `onRowClick` specified const onTableRow = isFunction(this.props.onRowClick) - ? row => ({ - onClick: event => { + ? (row) => ({ + onClick: (event) => { this.props.onRowClick(event, row.item); }, }) @@ -179,7 +179,7 @@ export default class ItemsTable extends React.Component { const onChange = (pagination, filters, sorter, extra) => { const action = extra?.action; if (action === "sort") { - const propsColumn = this.props.columns.find(column => column.field === sorter.field[1]); + const propsColumn = this.props.columns.find((column) => column.field === sorter.field[1]); if (!propsColumn.sorter) { return; } @@ -200,12 +200,12 @@ export default class ItemsTable extends React.Component { const { showHeader } = this.props; if (this.props.loading) { if (isEmpty(tableDataProps.dataSource)) { - tableDataProps.columns = tableDataProps.columns.map(column => ({ + tableDataProps.columns = tableDataProps.columns.map((column) => ({ ...column, sorter: false, render: () => , })); - tableDataProps.dataSource = range(10).map(key => ({ key: `${key}` })); + tableDataProps.dataSource = range(10).map((key) => ({ key: `${key}` })); } else { tableDataProps.loading = { indicator: null }; } diff --git a/client/app/pages/queries-list/QueriesList.jsx b/client/app/pages/queries-list/QueriesList.jsx index be220ed96a..2a200e98b4 100644 --- a/client/app/pages/queries-list/QueriesList.jsx +++ b/client/app/pages/queries-list/QueriesList.jsx @@ -166,9 +166,9 @@ function QueriesList({ controller }) { showPageSizeSelect totalCount={controller.totalItemsCount} pageSize={controller.itemsPerPage} - onPageSizeChange={itemsPerPage => controller.updatePagination({ itemsPerPage })} + onPageSizeChange={(itemsPerPage) => controller.updatePagination({ itemsPerPage })} page={controller.page} - onChange={page => controller.updatePagination({ page })} + onChange={(page) => controller.updatePagination({ page })} /> @@ -197,7 +197,7 @@ const QueriesListPage = itemsList( }[currentPage]; }, getItemProcessor() { - return item => new Query(item); + return (item) => new Query(item); }, }), () => new UrlStateStorage({ orderByField: "created_at", orderByReverse: true }) @@ -208,7 +208,7 @@ routes.register( routeWithUserSession({ path: "/queries", title: "Queries", - render: pageProps => , + render: (pageProps) => , }) ); routes.register( @@ -216,7 +216,7 @@ routes.register( routeWithUserSession({ path: "/queries/favorites", title: "Favorite Queries", - render: pageProps => , + render: (pageProps) => , }) ); routes.register( @@ -224,7 +224,7 @@ routes.register( routeWithUserSession({ path: "/queries/archive", title: "Archived Queries", - render: pageProps => , + render: (pageProps) => , }) ); routes.register( @@ -232,6 +232,6 @@ routes.register( routeWithUserSession({ path: "/queries/my", title: "My Queries", - render: pageProps => , + render: (pageProps) => , }) );