diff --git a/src/components/Widgets/TaskPropertiesWidget/Messages.js b/src/components/Widgets/TaskPropertiesWidget/Messages.js
index e02e33ff8..f6f6af0f6 100644
--- a/src/components/Widgets/TaskPropertiesWidget/Messages.js
+++ b/src/components/Widgets/TaskPropertiesWidget/Messages.js
@@ -18,4 +18,14 @@ export default defineMessages({
id: "Widgets.TaskPropertiesWidget.task.label",
defaultMessage: "Task {taskId}",
},
+
+ expandAll: {
+ id: "Widgets.TaskPropertiesWidget.expandAll",
+ defaultMessage: "Expand All",
+ },
+
+ collapseAll: {
+ id: "Widgets.TaskPropertiesWidget.collapseAll",
+ defaultMessage: "Collapse All",
+ },
})
diff --git a/src/components/Widgets/TaskPropertiesWidget/TaskPropertiesWidget.jsx b/src/components/Widgets/TaskPropertiesWidget/TaskPropertiesWidget.jsx
index c74691638..f3d23a152 100644
--- a/src/components/Widgets/TaskPropertiesWidget/TaskPropertiesWidget.jsx
+++ b/src/components/Widgets/TaskPropertiesWidget/TaskPropertiesWidget.jsx
@@ -1,4 +1,4 @@
-import { Component } from 'react'
+import React, { useState } from 'react'
import { FormattedMessage } from 'react-intl'
import _get from 'lodash/get'
import _map from 'lodash/map'
@@ -19,45 +19,91 @@ const descriptor = {
defaultHeight: 6,
}
-export default class TaskPropertiesWidget extends Component {
- render() {
- const taskList = _get(this.props.taskBundle, 'tasks') || [this.props.task]
- const propertyLists = _map(taskList, (task) => {
- const featurePropertiesList = AsMappableTask(task).osmFeatureProperties(this.props.osmElements)
-
- return (
-
-
-
-
- {
- featurePropertiesList.map((feature, index) => {
- return (
-
-
- {feature.properties?.id || feature.geometry?.type}
-
-
-
- )
- })
- }
-
- )
- })
+const TaskPropertiesWidget = (props) => {
+ const taskList = _get(props.taskBundle, 'tasks') || [props.task];
+ const initialCollapsedState = {};
+
+ taskList.forEach((task) => {
+ const featurePropertiesList = AsMappableTask(task).osmFeatureProperties(props.osmElements);
+ featurePropertiesList.forEach((_, index) => {
+ initialCollapsedState[`${task.id}-${index}`] = true;
+ });
+ });
+
+ const [collapsed, setCollapsed] = useState(initialCollapsedState);
+ const [allCollapsed, setAllCollapsed] = useState(true);
+
+ const toggleCollapseAll = () => {
+ const newCollapsedState = {};
+ taskList.forEach((task) => {
+ const featurePropertiesList = AsMappableTask(task).osmFeatureProperties(props.osmElements);
+ featurePropertiesList.forEach((_, index) => {
+ newCollapsedState[`${task.id}-${index}`] = !allCollapsed;
+ });
+ });
+ setCollapsed(newCollapsedState);
+ setAllCollapsed(!allCollapsed);
+ }
+
+ const toggleCollapse = (index) => {
+ setCollapsed(prevState => ({
+ ...prevState,
+ [index]: !prevState[index],
+ }));
+ }
+ const propertyLists = _map(taskList, (task) => {
+ const featurePropertiesList = AsMappableTask(task).osmFeatureProperties(props.osmElements)
return (
- }
- >
- {propertyLists}
-
+
+ {
+ featurePropertiesList.map((feature, index) => {
+ const featureIndex = `${task.id}-${index}`;
+ const isCollapsed = collapsed[featureIndex];
+ return (
+
+
toggleCollapse(featureIndex)}>
+
+
+
+
+
+ {feature.properties?.id || feature.geometry?.type}
+
+
+
+ {isCollapsed ? '▼' : '▲'}
+
+
+ {!isCollapsed && (
+
+ )}
+
+ )
+ })
+ }
+
)
- }
+ })
+
+ return (
+ }
+ rightHeaderControls={
+
+ {allCollapsed ? : }
+
+ }
+ >
+ {propertyLists}
+
+ )
}
registerWidgetType(TaskPropertiesWidget, descriptor)
+
+export default TaskPropertiesWidget;