From 4cca40e93b518a3a71b7811826c93b5db172e4e9 Mon Sep 17 00:00:00 2001 From: Tom Herold Date: Thu, 25 Apr 2024 16:17:27 +0200 Subject: [PATCH 1/9] refactor antd table columns as arrays instead of react elements --- .../javascripts/admin/task/task_list_view.tsx | 344 +++++++++--------- .../components/fixed_expandable_table.tsx | 24 +- .../advanced_dataset/dataset_table.tsx | 64 ++-- 3 files changed, 215 insertions(+), 217 deletions(-) diff --git a/frontend/javascripts/admin/task/task_list_view.tsx b/frontend/javascripts/admin/task/task_list_view.tsx index 965f37f671..c1134cbb40 100644 --- a/frontend/javascripts/admin/task/task_list_view.tsx +++ b/frontend/javascripts/admin/task/task_list_view.tsx @@ -1,6 +1,6 @@ import { Link } from "react-router-dom"; import { PropTypes } from "@scalableminds/prop-types"; -import { Table, Tag, Spin, Button, Input, Modal, Card, Alert, App } from "antd"; +import { Tag, Spin, Button, Input, Modal, Card, Alert, App, TableProps } from "antd"; import { CheckCircleOutlined, ClockCircleOutlined, @@ -39,7 +39,6 @@ import messages from "messages"; import FixedExpandableTable from "components/fixed_expandable_table"; import UserSelectionComponent from "admin/user/user_selection_component"; -const { Column } = Table; const { Search, TextArea } = Input; type Props = { @@ -237,6 +236,176 @@ function TaskListView({ initialFieldValues }: Props) { const marginRight = { marginRight: 20, }; + + const columns: TableProps["columns"] = [ + { + title: "ID", + dataIndex: "id", + key: "id", + sorter: Utils.localeCompareBy((task) => task.id), + className: "monospace-id", + width: 100, + }, + { + title: "Project", + dataIndex: "projectName", + key: "projectName", + width: 130, + sorter: Utils.localeCompareBy((task) => task.projectName), + render: (projectName: string) => {projectName}, + }, + { + title: "Type", + dataIndex: "type", + key: "type", + width: 200, + sorter: Utils.localeCompareBy((task) => task.type.summary), + render: (taskType: APITaskType) => ( + {taskType.summary} + ), + }, + { + title: "Dataset", + dataIndex: "dataSet", + key: "dataSet", + sorter: Utils.localeCompareBy((task) => task.dataSet), + }, + { + title: "Stats", + dataIndex: "status", + key: "status", + render: (status: APITask["status"], task: APITask) => ( +
+ + + {status.pending} + +
+ + + {status.active} + +
+ + + {status.finished} + +
+ + + {formatSeconds((task.tracingTime || 0) / 1000)} + +
+ ), + filters: [ + { + text: "Has Pending Instances", + value: "pending", + }, + { + text: "Has Active Instances", + value: "active", + }, + { + text: "Has Finished Instances", + value: "finished", + }, + ], + onFilter: (key: any, task: APITask) => task.status[key as unknown as keyof TaskStatus] > 0, + }, + { + title: "Edit Position / Bounding Box", + dataIndex: "editPosition", + key: "editPosition", + width: 150, + render: (_, task: APITask) => ( +
+ {formatTuple(task.editPosition)}
+ {formatTuple(task.boundingBoxVec6)} +
+ ), + }, + { + title: "Experience", + dataIndex: "neededExperience", + key: "neededExperience", + sorter: Utils.localeCompareBy((task) => task.neededExperience.domain), + width: 250, + render: (neededExperience: APITask["neededExperience"]) => + neededExperience.domain !== "" || neededExperience.value > 0 ? ( + + {neededExperience.domain} : {neededExperience.value} + + ) : null, + }, + { + title: "Creation Date", + dataIndex: "created", + key: "created", + width: 200, + sorter: Utils.compareBy((task) => task.created), + render: (created: APITask["created"]) => , + defaultSortOrder: "descend", + }, + { + title: "Action", + key: "actions", + width: 170, + fixed: "right", + render: (_, task: APITask) => ( + <> + {task.status.finished > 0 ? ( + + ) : null} + + {task.status.pending > 0 ? ( +
+ + + Manually Assign to User + +
+ ) : null} + {task.status.finished > 0 ? ( +
+ { + const includesVolumeData = task.type.tracingType !== "skeleton"; + return downloadAnnotationAPI(task.id, "CompoundTask", includesVolumeData); + }} + title="Download all Finished Annotations" + icon={} + > + Download + +
+ ) : null} +
+ + + Delete + +
+ + ), + }, + ]; + return (
@@ -323,6 +492,7 @@ function TaskListView({ initialFieldValues }: Props) { - ((task) => task.id)} - className="monospace-id" - width={100} - /> - ((task) => task.projectName)} - render={(projectName: string) => {projectName}} - /> - ((task) => task.type.summary)} - render={(taskType: APITaskType) => ( - {taskType.summary} - )} - /> - ((task) => task.dataSet)} - /> - ( -
- - - {status.pending} - -
- - - {status.active} - -
- - - {status.finished} - -
- - - {formatSeconds((task.tracingTime || 0) / 1000)} - -
- )} - filters={[ - { - text: "Has Pending Instances", - value: "pending", - }, - { - text: "Has Active Instances", - value: "active", - }, - { - text: "Has Finished Instances", - value: "finished", - }, - ]} - onFilter={(key, task: APITask) => task.status[key as unknown as keyof TaskStatus] > 0} - /> - ( -
- {formatTuple(task.editPosition)}
- {formatTuple(task.boundingBoxVec6)} -
- )} - /> - ((task) => task.neededExperience.domain)} - width={250} - render={(neededExperience) => - neededExperience.domain !== "" || neededExperience.value > 0 ? ( - - {neededExperience.domain} : {neededExperience.value} - - ) : null - } - /> - ((task) => task.created)} - render={(created) => } - defaultSortOrder={"descend"} - /> - ( - <> - {task.status.finished > 0 ? ( - - ) : null} - - {task.status.pending > 0 ? ( -
- - - Manually Assign to User - -
- ) : null} - {task.status.finished > 0 ? ( -
- { - const includesVolumeData = task.type.tracingType !== "skeleton"; - return downloadAnnotationAPI(task.id, "CompoundTask", includesVolumeData); - }} - title="Download all Finished Annotations" - icon={} - > - Download - -
- ) : null} -
- - - Delete - -
- - )} - /> -
+ /> + {getAnonymousTaskLinkModal()}
diff --git a/frontend/javascripts/components/fixed_expandable_table.tsx b/frontend/javascripts/components/fixed_expandable_table.tsx index 1ff32bab5f..b26531bdfa 100644 --- a/frontend/javascripts/components/fixed_expandable_table.tsx +++ b/frontend/javascripts/components/fixed_expandable_table.tsx @@ -1,9 +1,6 @@ import { Button, Table, TableProps } from "antd"; import { GetRowKey } from "antd/lib/table/interface"; import * as React from "react"; -type Props = TableProps & { - children: Array | null>; -}; type State = { expandedRows: Array; @@ -15,7 +12,7 @@ type State = { * and the scroll prop as this is already done by the wrapper. */ -export default class FixedExpandableTable extends React.PureComponent { +export default class FixedExpandableTable extends React.PureComponent { state: State = { expandedRows: [], }; @@ -52,16 +49,10 @@ export default class FixedExpandableTable extends React.PureComponent el) - // @ts-ignore The previous filter removes null - .map((child: React.ReactElement) => { - // @ts-ignore - const columnFixed: boolean = expandedRows.length > 0 ? false : child.props.fixed; - return React.cloneElement(child, { - // @ts-ignore - fixed: columnFixed, - }); + const columnsWithAdjustedFixedProp: TableProps["columns"] = (this.props.columns || []) + .map((column) => { + const columnFixed = expandedRows.length > 0 ? false : column.fixed; + return { ...column, fixed: columnFixed }; }); const expandableProp = { ...expandable, @@ -81,9 +72,8 @@ export default class FixedExpandableTable extends React.PureComponent - {columnsWithAdjustedFixedProp} - + columns={columnsWithAdjustedFixedProp} + /> ); } } diff --git a/frontend/javascripts/dashboard/advanced_dataset/dataset_table.tsx b/frontend/javascripts/dashboard/advanced_dataset/dataset_table.tsx index 4b7ba12a85..c300ac88c6 100644 --- a/frontend/javascripts/dashboard/advanced_dataset/dataset_table.tsx +++ b/frontend/javascripts/dashboard/advanced_dataset/dataset_table.tsx @@ -1,6 +1,6 @@ import { FileOutlined, FolderOpenOutlined, PlusOutlined, WarningOutlined } from "@ant-design/icons"; import { Link } from "react-router-dom"; -import { Dropdown, MenuProps, Table, Tag, Tooltip } from "antd"; +import { Dropdown, MenuProps, Table, TableProps, Tag, Tooltip } from "antd"; import type { FilterValue, SorterResult, TablePaginationConfig } from "antd/lib/table/interface"; import * as React from "react"; import _ from "lodash"; @@ -354,6 +354,7 @@ class DatasetRenderer { class FolderRenderer { data: FolderItemWithName; datasetTable: DatasetTable; + constructor(data: FolderItemWithName, datasetTable: DatasetTable) { this.data = data; this.datasetTable = datasetTable; @@ -573,6 +574,36 @@ class DatasetTable extends React.PureComponent { selectedRowKeys = [context.selectedFolder?.key]; } + const columns: TableProps["columns"] = [ + { + title: "Name", + dataIndex: "name", + key: "name", + sorter: Utils.localeCompareBy((rowRenderer) => rowRenderer.data.name), + sortOrder: sortedInfo.columnKey === "name" ? sortedInfo.order : undefined, + render: (_name: string, rowRenderer: RowRenderer) => rowRenderer.renderNameColumn(), + }, + { + width: 180, + title: "Creation Date", + dataIndex: "created", + key: "created", + sorter: Utils.compareBy((rowRenderer) => + isRecordADataset(rowRenderer.data) ? rowRenderer.data.created : 0, + ), + sortOrder: sortedInfo.columnKey === "created" ? sortedInfo.order : undefined, + render: (_created, rowRenderer: RowRenderer) => rowRenderer.renderCreationDateColumn(), + }, + + { + width: 200, + title: "Actions", + key: "actions", + fixed: "right", + render: (__, rowRenderer: RowRenderer) => rowRenderer.renderActionsColumn(), + }, + ]; + return ( { renderer.getRowKey()} components={components} pagination={{ @@ -729,35 +761,7 @@ class DatasetTable extends React.PureComponent { context.setSelectedFolder(null); }, }} - > - ((rowRenderer) => rowRenderer.data.name)} - sortOrder={sortedInfo.columnKey === "name" ? sortedInfo.order : undefined} - render={(_name: string, renderer: RowRenderer) => renderer.renderNameColumn()} - /> - ((rowRenderer) => - isRecordADataset(rowRenderer.data) ? rowRenderer.data.created : 0, - )} - sortOrder={sortedInfo.columnKey === "created" ? sortedInfo.order : undefined} - render={(_created, rowRenderer: RowRenderer) => rowRenderer.renderCreationDateColumn()} - /> - - rowRenderer.renderActionsColumn()} - /> - + /> ); } From 6ed0ac1de3cf446b41dd7a5c1f6c70adfe6ed1f6 Mon Sep 17 00:00:00 2001 From: Tom Herold Date: Fri, 26 Apr 2024 15:30:05 +0200 Subject: [PATCH 2/9] fix linting --- frontend/javascripts/components/fixed_expandable_table.tsx | 2 +- .../javascripts/dashboard/advanced_dataset/dataset_table.tsx | 3 +-- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/frontend/javascripts/components/fixed_expandable_table.tsx b/frontend/javascripts/components/fixed_expandable_table.tsx index b26531bdfa..3ec89301fd 100644 --- a/frontend/javascripts/components/fixed_expandable_table.tsx +++ b/frontend/javascripts/components/fixed_expandable_table.tsx @@ -27,7 +27,7 @@ export default class FixedExpandableTable extends React.PureComponent Date: Thu, 25 Apr 2024 16:17:58 +0200 Subject: [PATCH 3/9] fix dayjs types --- .../admin/statistic/time_tracking_overview.tsx | 2 +- .../admin/time/time_line_chart_view.tsx | 4 ++-- .../javascripts/admin/time/time_line_view.tsx | 15 +++++---------- 3 files changed, 8 insertions(+), 13 deletions(-) diff --git a/frontend/javascripts/admin/statistic/time_tracking_overview.tsx b/frontend/javascripts/admin/statistic/time_tracking_overview.tsx index bf4728d01b..c5ef5b3522 100644 --- a/frontend/javascripts/admin/statistic/time_tracking_overview.tsx +++ b/frontend/javascripts/admin/statistic/time_tracking_overview.tsx @@ -15,7 +15,7 @@ import messages from "messages"; import Toast from "libs/toast"; import { useSelector } from "react-redux"; import { OxalisState } from "oxalis/store"; -import dayjs, { Dayjs } from "antd/node_modules/dayjs"; +import dayjs, { type Dayjs } from "dayjs"; const { Column } = Table; const { RangePicker } = DatePicker; diff --git a/frontend/javascripts/admin/time/time_line_chart_view.tsx b/frontend/javascripts/admin/time/time_line_chart_view.tsx index 66e27eb159..48f07a8a89 100644 --- a/frontend/javascripts/admin/time/time_line_chart_view.tsx +++ b/frontend/javascripts/admin/time/time_line_chart_view.tsx @@ -1,7 +1,7 @@ import { Chart } from "react-google-charts"; import * as React from "react"; import { getWindowBounds } from "libs/utils"; -import dayjs from "dayjs"; +import type { Dayjs } from "dayjs"; export type ColumnDefinition = { id?: string; @@ -11,7 +11,7 @@ export type ColumnDefinition = { }; export type RowContent = [string, string, string, Date, Date]; -export type DateRange = [dayjs.Dayjs, dayjs.Dayjs]; +export type DateRange = [Dayjs, Dayjs]; type Props = { columns: Array; rows: Array; diff --git a/frontend/javascripts/admin/time/time_line_view.tsx b/frontend/javascripts/admin/time/time_line_view.tsx index 97c1a30916..ba564045fb 100644 --- a/frontend/javascripts/admin/time/time_line_view.tsx +++ b/frontend/javascripts/admin/time/time_line_view.tsx @@ -3,8 +3,7 @@ import * as React from "react"; import ReactDOMServer from "react-dom/server"; import { connect } from "react-redux"; import _ from "lodash"; -import dayjs from "dayjs"; -import antddayjs from "antd/node_modules/dayjs"; +import dayjs, { type Dayjs } from "dayjs"; import FormattedDate from "components/formatted_date"; import { formatMilliseconds, formatDurationToMinutesAndSeconds } from "libs/format_utils"; import { isUserAdminOrTeamManager } from "libs/utils"; @@ -238,16 +237,16 @@ class TimeLineView extends React.PureComponent { user: prevState.users.find((u) => u.id === userId), })); }; - - handleDateChange = async (antdDates: [antddayjs.Dayjs | null, antddayjs.Dayjs | null]) => { - if (antdDates[0] == null || antdDates[1] == null) return; + // import type NoUndefinedRangeValueType from "antd/locale" + handleDateChange = async (antdDates: [Dayjs | null, Dayjs | null] | null) => { + if (antdDates == null || antdDates[0] == null || antdDates[1] == null) return; // to ease the load on the server restrict date range selection to three month if (Math.abs(antdDates[0].diff(antdDates[1], "days")) > 3 * 31) { Toast.error(messages["timetracking.date_range_too_long"]); return; } - const dates: DateRange = [this.getDayJsObject(antdDates[0]), this.getDayJsObject(antdDates[1])]; + const dates: DateRange = [antdDates[0], antdDates[1]]; // Force an interval of at least one minute. const dateRange: DateRange = dates[0].isSame(dates[1], "minute") ? [dates[0].startOf("day"), dates[0].add(1, "minute")] @@ -302,10 +301,6 @@ class TimeLineView extends React.PureComponent { return ReactDOMServer.renderToStaticMarkup(tooltip); } - getDayJsObject = (antdDate: antddayjs.Dayjs) => { - return dayjs(antdDate.valueOf()); - }; - render() { const columns: Array = [ { From 88bc730ae1b741a8f2315ff565047325c0c18e81 Mon Sep 17 00:00:00 2001 From: Tom Herold Date: Fri, 26 Apr 2024 15:37:33 +0200 Subject: [PATCH 4/9] formatting --- frontend/javascripts/components/fixed_expandable_table.tsx | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/frontend/javascripts/components/fixed_expandable_table.tsx b/frontend/javascripts/components/fixed_expandable_table.tsx index 3ec89301fd..dcfb480d1b 100644 --- a/frontend/javascripts/components/fixed_expandable_table.tsx +++ b/frontend/javascripts/components/fixed_expandable_table.tsx @@ -49,11 +49,12 @@ export default class FixedExpandableTable extends React.PureComponent { + const columnsWithAdjustedFixedProp: TableProps["columns"] = (this.props.columns || []).map( + (column) => { const columnFixed = expandedRows.length > 0 ? false : column.fixed; return { ...column, fixed: columnFixed }; - }); + }, + ); const expandableProp = { ...expandable, expandedRowKeys: expandedRows, From 8f35114a787b13ceeb8e891a2c9352571134f1af Mon Sep 17 00:00:00 2001 From: Tom Herold Date: Fri, 26 Apr 2024 15:37:35 +0200 Subject: [PATCH 5/9] Revert "fix dayjs types" This reverts commit 1cf2f45a27f0becce8a60235953688a248bb0e04. --- .../admin/statistic/time_tracking_overview.tsx | 2 +- .../admin/time/time_line_chart_view.tsx | 4 ++-- .../javascripts/admin/time/time_line_view.tsx | 15 ++++++++++----- 3 files changed, 13 insertions(+), 8 deletions(-) diff --git a/frontend/javascripts/admin/statistic/time_tracking_overview.tsx b/frontend/javascripts/admin/statistic/time_tracking_overview.tsx index c5ef5b3522..bf4728d01b 100644 --- a/frontend/javascripts/admin/statistic/time_tracking_overview.tsx +++ b/frontend/javascripts/admin/statistic/time_tracking_overview.tsx @@ -15,7 +15,7 @@ import messages from "messages"; import Toast from "libs/toast"; import { useSelector } from "react-redux"; import { OxalisState } from "oxalis/store"; -import dayjs, { type Dayjs } from "dayjs"; +import dayjs, { Dayjs } from "antd/node_modules/dayjs"; const { Column } = Table; const { RangePicker } = DatePicker; diff --git a/frontend/javascripts/admin/time/time_line_chart_view.tsx b/frontend/javascripts/admin/time/time_line_chart_view.tsx index 48f07a8a89..66e27eb159 100644 --- a/frontend/javascripts/admin/time/time_line_chart_view.tsx +++ b/frontend/javascripts/admin/time/time_line_chart_view.tsx @@ -1,7 +1,7 @@ import { Chart } from "react-google-charts"; import * as React from "react"; import { getWindowBounds } from "libs/utils"; -import type { Dayjs } from "dayjs"; +import dayjs from "dayjs"; export type ColumnDefinition = { id?: string; @@ -11,7 +11,7 @@ export type ColumnDefinition = { }; export type RowContent = [string, string, string, Date, Date]; -export type DateRange = [Dayjs, Dayjs]; +export type DateRange = [dayjs.Dayjs, dayjs.Dayjs]; type Props = { columns: Array; rows: Array; diff --git a/frontend/javascripts/admin/time/time_line_view.tsx b/frontend/javascripts/admin/time/time_line_view.tsx index ba564045fb..97c1a30916 100644 --- a/frontend/javascripts/admin/time/time_line_view.tsx +++ b/frontend/javascripts/admin/time/time_line_view.tsx @@ -3,7 +3,8 @@ import * as React from "react"; import ReactDOMServer from "react-dom/server"; import { connect } from "react-redux"; import _ from "lodash"; -import dayjs, { type Dayjs } from "dayjs"; +import dayjs from "dayjs"; +import antddayjs from "antd/node_modules/dayjs"; import FormattedDate from "components/formatted_date"; import { formatMilliseconds, formatDurationToMinutesAndSeconds } from "libs/format_utils"; import { isUserAdminOrTeamManager } from "libs/utils"; @@ -237,16 +238,16 @@ class TimeLineView extends React.PureComponent { user: prevState.users.find((u) => u.id === userId), })); }; - // import type NoUndefinedRangeValueType from "antd/locale" - handleDateChange = async (antdDates: [Dayjs | null, Dayjs | null] | null) => { - if (antdDates == null || antdDates[0] == null || antdDates[1] == null) return; + + handleDateChange = async (antdDates: [antddayjs.Dayjs | null, antddayjs.Dayjs | null]) => { + if (antdDates[0] == null || antdDates[1] == null) return; // to ease the load on the server restrict date range selection to three month if (Math.abs(antdDates[0].diff(antdDates[1], "days")) > 3 * 31) { Toast.error(messages["timetracking.date_range_too_long"]); return; } - const dates: DateRange = [antdDates[0], antdDates[1]]; + const dates: DateRange = [this.getDayJsObject(antdDates[0]), this.getDayJsObject(antdDates[1])]; // Force an interval of at least one minute. const dateRange: DateRange = dates[0].isSame(dates[1], "minute") ? [dates[0].startOf("day"), dates[0].add(1, "minute")] @@ -301,6 +302,10 @@ class TimeLineView extends React.PureComponent { return ReactDOMServer.renderToStaticMarkup(tooltip); } + getDayJsObject = (antdDate: antddayjs.Dayjs) => { + return dayjs(antdDate.valueOf()); + }; + render() { const columns: Array = [ { From fc1eefb948a140bac9e1e8c4483542f0308caa53 Mon Sep 17 00:00:00 2001 From: Tom Herold Date: Fri, 26 Apr 2024 15:51:45 +0200 Subject: [PATCH 6/9] updated readme --- CHANGELOG.unreleased.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.unreleased.md b/CHANGELOG.unreleased.md index ce5baddb40..a3f6799c2a 100644 --- a/CHANGELOG.unreleased.md +++ b/CHANGELOG.unreleased.md @@ -26,6 +26,7 @@ For upgrade instructions, please check the [migration guide](MIGRATIONS.released - Toasts are shown until WEBKNOSSOS is running in the active browser tab again. Also, the content of most toasts that show errors or warnings is printed to the browser's console. [#7741](https://github.com/scalableminds/webknossos/pull/7741) - Improved UI speed when editing the description of an annotation. [#7769](https://github.com/scalableminds/webknossos/pull/7769) - Updated dataset animations to use the new meshing API. Animitation now support ad-hoc meshes and mappings. [#7692](https://github.com/scalableminds/webknossos/pull/7692) +- Slightly refactored the ``component to use columns as props. [#7772](https://github.com/scalableminds/webknossos/pull/7772) ### Fixed From b0ca82f14f85edb3e3c744807ae44108c20bec74 Mon Sep 17 00:00:00 2001 From: Tom Herold Date: Mon, 6 May 2024 10:21:49 +0200 Subject: [PATCH 7/9] Update frontend/javascripts/components/fixed_expandable_table.tsx Co-authored-by: MichaelBuessemeyer <39529669+MichaelBuessemeyer@users.noreply.github.com> --- frontend/javascripts/components/fixed_expandable_table.tsx | 3 --- 1 file changed, 3 deletions(-) diff --git a/frontend/javascripts/components/fixed_expandable_table.tsx b/frontend/javascripts/components/fixed_expandable_table.tsx index dcfb480d1b..82df610e69 100644 --- a/frontend/javascripts/components/fixed_expandable_table.tsx +++ b/frontend/javascripts/components/fixed_expandable_table.tsx @@ -46,9 +46,6 @@ export default class FixedExpandableTable extends React.PureComponent this.setState({ expandedRows: [] })} /> ); - // Don't use React.Children.map here, since this adds .$ prefixes - // to the keys. However, the keys are needed when managing the sorters - // of the table. const columnsWithAdjustedFixedProp: TableProps["columns"] = (this.props.columns || []).map( (column) => { const columnFixed = expandedRows.length > 0 ? false : column.fixed; From 129fa857f07aa6f276d425caf37ea21c3238c044 Mon Sep 17 00:00:00 2001 From: Tom Herold Date: Mon, 6 May 2024 13:56:35 +0200 Subject: [PATCH 8/9] Update frontend/javascripts/admin/task/task_list_view.tsx Co-authored-by: MichaelBuessemeyer <39529669+MichaelBuessemeyer@users.noreply.github.com> --- frontend/javascripts/admin/task/task_list_view.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/javascripts/admin/task/task_list_view.tsx b/frontend/javascripts/admin/task/task_list_view.tsx index c1134cbb40..c4e08a4ebc 100644 --- a/frontend/javascripts/admin/task/task_list_view.tsx +++ b/frontend/javascripts/admin/task/task_list_view.tsx @@ -352,7 +352,7 @@ function TaskListView({ initialFieldValues }: Props) { key: "actions", width: 170, fixed: "right", - render: (_, task: APITask) => ( + render: (_unused, task: APITask) => ( <> {task.status.finished > 0 ? (
From b3681915cfc8a47e1e5b584e58537b2d335b1494 Mon Sep 17 00:00:00 2001 From: Tom Herold Date: Tue, 14 May 2024 09:32:17 +0200 Subject: [PATCH 9/9] fix typing error --- .../javascripts/components/fixed_expandable_table.tsx | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/frontend/javascripts/components/fixed_expandable_table.tsx b/frontend/javascripts/components/fixed_expandable_table.tsx index dcfb480d1b..c73d8ab80a 100644 --- a/frontend/javascripts/components/fixed_expandable_table.tsx +++ b/frontend/javascripts/components/fixed_expandable_table.tsx @@ -1,6 +1,6 @@ import { Button, Table, TableProps } from "antd"; import { GetRowKey } from "antd/lib/table/interface"; -import * as React from "react"; +import React from "react"; type State = { expandedRows: Array; @@ -25,6 +25,12 @@ export default class FixedExpandableTable extends React.PureComponent row[rowKey]) : []; } + componentDidUpdate(prevProps: Readonly>): void { + if (prevProps.dataSource !== this.props.dataSource) { + this.setState({ expandedRows: [] }); + } + } + render() { const { expandedRows } = this.state; const { className, expandable, ...restProps } = this.props;