Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions lang/en-US.json
Original file line number Diff line number Diff line change
Expand Up @@ -1190,8 +1190,8 @@
"Review.Dashboard.tasksReviewedByMe": "Tasks Reviewed by Me",
"Review.Dashboard.tasksToBeReviewed": "Tasks to be Reviewed",
"Review.Dashboard.title": "Review Overview",
"Review.Task.fields.featureId.label": "Feature Id",
"Review.Task.fields.id.label": "Internal Id",
"Review.Task.fields.featureId.label": "OSM ID",
"Review.Task.fields.id.label": "Task ID",
"Review.TaskAnalysisTable.configureColumns": "Configure columns",
"Review.TaskAnalysisTable.controls.fixTask.label": "Fix",
"Review.TaskAnalysisTable.controls.metaReviewTask.label": "Meta Review",
Expand Down Expand Up @@ -1375,8 +1375,8 @@
"Task.taskTags.modify.label": "Modify MR Tags",
"Task.taskTags.update.label": "Update MR Tags",
"Task.unsave.control.tooltip": "Stop Tracking",
"TaskAnalysisTable.columns.searchFeatureId.placeholder": "Search feature ID...",
"TaskAnalysisTable.columns.searchId.placeholder": "Search ID...",
"TaskAnalysisTable.columns.searchFeatureId.placeholder": "Search OSM ID...",
"TaskAnalysisTable.columns.searchId.placeholder": "Search Task ID...",
"TaskAnalysisTable.columns.searchMapper.placeholder": "Search mapper...",
"TaskAnalysisTable.columns.searchMetaReviewer.placeholder": "Search meta reviewer...",
"TaskAnalysisTable.columns.searchReviewer.placeholder": "Search reviewer...",
Expand Down Expand Up @@ -1566,8 +1566,8 @@
"Widgets.ReviewNearbyTasksWidget.displayBundledTasksLabel": "Display Bundled Tasks Only",
"Widgets.ReviewNearbyTasksWidget.label": "Nearby Tasks",
"Widgets.ReviewNearbyTasksWidget.noVirtualChallenges": "Nearby tasks are not available for virtual challenges.",
"Widgets.ReviewNearbyTasksWidget.popup.fields.name.label": "Feature Id:",
"Widgets.ReviewNearbyTasksWidget.popup.fields.taskId.label": "Internal Id:",
"Widgets.ReviewNearbyTasksWidget.popup.fields.name.label": "OSM ID:",
"Widgets.ReviewNearbyTasksWidget.popup.fields.taskId.label": "Task ID:",
"Widgets.ReviewNearbyTasksWidget.restoreDefaultFiltersLabel": "Restore Default Filters",
"Widgets.ReviewNearbyTasksWidget.saveCurrentFiltersLabel": "Save Current Filters",
"Widgets.ReviewNearbyTasksWidget.simultaneousTasks": "Working on {taskCount, number} tasks together",
Expand Down
8 changes: 4 additions & 4 deletions src/components/TaskAnalysisTable/Messages.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,12 @@ export default defineMessages({

idLabel: {
id: "Review.Task.fields.id.label",
defaultMessage: "Internal Id",
defaultMessage: "Task ID",
},

featureIdLabel: {
id: "Review.Task.fields.featureId.label",
defaultMessage: "Feature Id",
defaultMessage: "OSM ID",
},

unbundle: {
Expand Down Expand Up @@ -282,12 +282,12 @@ export default defineMessages({

searchFeatureIdPlaceholder: {
id: "TaskAnalysisTable.columns.searchFeatureId.placeholder",
defaultMessage: "Search feature ID...",
defaultMessage: "Search OSM ID...",
},

searchIdPlaceholder: {
id: "TaskAnalysisTable.columns.searchId.placeholder",
defaultMessage: "Search ID...",
defaultMessage: "Search Task ID...",
},

clearFilterLabel: {
Expand Down
61 changes: 47 additions & 14 deletions src/components/TaskAnalysisTable/columns/taskColumns.jsx
Original file line number Diff line number Diff line change
@@ -1,32 +1,65 @@
import _kebabCase from "lodash/kebabCase";
import { FormattedDate, FormattedMessage, FormattedTime } from "react-intl";
import { Link } from "react-router-dom";
import AsIdentifiableFeature from "../../../interactions/TaskFeature/AsIdentifiableFeature";
import { loadObjectsIntoJOSM } from "../../../services/Editor/Editor";
import { messagesByPriority } from "../../../services/Task/TaskPriority/TaskPriority";
import { keysByStatus, messagesByStatus } from "../../../services/Task/TaskStatus/TaskStatus";
import SvgSymbol from "../../SvgSymbol/SvgSymbol";
import messages from "../Messages";
import TableSearchFilter from "../TableSearchFilter";
import { StatusLabel } from "../TaskTableHelpers";

const osmIdForTask = (task) => {
const feature = task?.geometries?.features?.[0];
if (!feature) return null;
const identifiable = AsIdentifiableFeature(feature);
const osmId = identifiable.osmId();
const osmType = identifiable.osmType();
if (!osmId || !osmType) return null;
return `${osmType[0]}${osmId}`;
};

/**
* Creates the Feature ID column
* Creates the OSM ID column
*/
export const createFeatureIdColumn = (props) => ({
id: "featureId",
Header: props.intl.formatMessage(messages.featureIdLabel),
accessor: (t) => t.name || t.title,
Cell: ({ value }) => (
<div
style={{
overflow: "hidden",
whiteSpace: "nowrap",
textOverflow: "ellipsis",
width: "100%",
}}
>
{value || ""}
</div>
),
accessor: (t) => osmIdForTask(t) || t.name || t.title,
Cell: ({ value, row }) => {
const josmId = osmIdForTask(row.original);
const content = (
<div
style={{
overflow: "hidden",
whiteSpace: "nowrap",
textOverflow: "ellipsis",
width: "100%",
}}
>
{value || ""}
</div>
);

if (!josmId) {
return content;
}

return (
<a
href={`http://127.0.0.1:8111/load_object?objects=${josmId}&new_layer=true`}
onClick={(e) => {
e.preventDefault();
loadObjectsIntoJOSM([josmId], true);
}}
className="mr-links-green-lighter"
title="Open in JOSM"
>
{content}
</a>
);
},
Filter: ({ column: { filterValue, setFilter } }) => (
<TableSearchFilter
filterValue={filterValue}
Expand Down
4 changes: 2 additions & 2 deletions src/components/Widgets/NearbyTasksWidget/Messages.js
Original file line number Diff line number Diff line change
Expand Up @@ -51,12 +51,12 @@ export default defineMessages({

taskIdLabel: {
id: "Widgets.ReviewNearbyTasksWidget.popup.fields.taskId.label",
defaultMessage: "Internal Id:",
defaultMessage: "Task ID:",
},

nameLabel: {
id: "Widgets.ReviewNearbyTasksWidget.popup.fields.name.label",
defaultMessage: "Feature Id:",
defaultMessage: "OSM ID:",
},

statusLabel: {
Expand Down
32 changes: 30 additions & 2 deletions src/components/Widgets/NearbyTasksWidget/TaskMarkerContent.jsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,21 @@
import { Component } from "react";
import { FormattedMessage } from "react-intl";
import { Link } from "react-router-dom";
import AsIdentifiableFeature from "../../../interactions/TaskFeature/AsIdentifiableFeature";
import { loadObjectsIntoJOSM } from "../../../services/Editor/Editor";
import { messagesByPriority } from "../../../services/Task/TaskPriority/TaskPriority";
import { messagesByStatus } from "../../../services/Task/TaskStatus/TaskStatus";
import messages from "./Messages";

const osmIdForFeature = (feature) => {
if (!feature) return null;
const identifiable = AsIdentifiableFeature(feature);
const osmId = identifiable.osmId();
const osmType = identifiable.osmType();
if (!osmId || !osmType) return null;
return `${osmType[0]}${osmId}`;
};

/**
* The content to show in the popup when a task marker is clicked.
*/
Expand All @@ -17,6 +28,11 @@ class TaskMarkerContent extends Component {
this.props.marker.options.priority ?? this.props.marker.options.taskPriority
];

const firstFeature = this.props.marker.options.geometries?.features?.[0];
const josmId = osmIdForFeature(firstFeature);
const nameValue =
josmId || this.props.marker.options.name || firstFeature?.id;

return (
<div className="mr-flex mr-justify-center">
<div className="mr-flex-col mr-w-full">
Expand All @@ -25,8 +41,20 @@ class TaskMarkerContent extends Component {
<FormattedMessage {...messages.nameLabel} />
</div>
<div className="mr-w-1/2 mr-text-left">
{this.props.marker.options.name ||
this.props.marker.options.geometries?.features[0]?.id}
{josmId ? (
<a
href={`http://127.0.0.1:8111/load_object?objects=${josmId}&new_layer=true`}
onClick={(e) => {
e.preventDefault();
loadObjectsIntoJOSM([josmId], true);
}}
title="Open in JOSM"
>
{nameValue}
</a>
) : (
nameValue
)}
</div>
</div>

Expand Down
4 changes: 2 additions & 2 deletions src/components/Widgets/TaskBundleWidget/Messages.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,12 @@ export default defineMessages({

taskIdLabel: {
id: "Widgets.ReviewNearbyTasksWidget.popup.fields.taskId.label",
defaultMessage: "Internal Id:",
defaultMessage: "Task ID:",
},

nameLabel: {
id: "Widgets.ReviewNearbyTasksWidget.popup.fields.name.label",
defaultMessage: "Feature Id:",
defaultMessage: "OSM ID:",
},

statusLabel: {
Expand Down
31 changes: 29 additions & 2 deletions src/components/Widgets/TaskBundleWidget/TaskMarkerContent.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,21 @@ import { Component } from "react";
import { FormattedMessage } from "react-intl";
import { Link } from "react-router-dom";
import AsCooperativeWork from "../../../interactions/Task/AsCooperativeWork";
import AsIdentifiableFeature from "../../../interactions/TaskFeature/AsIdentifiableFeature";
import { loadObjectsIntoJOSM } from "../../../services/Editor/Editor";
import { messagesByPriority } from "../../../services/Task/TaskPriority/TaskPriority";
import { messagesByStatus } from "../../../services/Task/TaskStatus/TaskStatus";
import messages from "./Messages";

const osmIdForFeature = (feature) => {
if (!feature) return null;
const identifiable = AsIdentifiableFeature(feature);
const osmId = identifiable.osmId();
const osmType = identifiable.osmType();
if (!osmId || !osmType) return null;
return `${osmType[0]}${osmId}`;
};

/**
* The content to show in the popup when a task marker is clicked.
*/
Expand Down Expand Up @@ -95,6 +106,10 @@ class TaskMarkerContent extends Component {
!AsCooperativeWork(this.props.task).isTagType() &&
this.props.marker.options.taskId !== this.props.task.id;

const firstFeature = this.props.marker.options.geometries?.features?.[0];
const josmId = osmIdForFeature(firstFeature);
const nameValue = josmId || this.props.marker.options.name || firstFeature?.id;

return (
<div className="mr-flex mr-justify-center">
<div className="mr-flex-col mr-w-full">
Expand All @@ -103,8 +118,20 @@ class TaskMarkerContent extends Component {
<FormattedMessage {...messages.nameLabel} />
</div>
<div className="mr-w-1/2 mr-text-left">
{this.props.marker.options.name ||
this.props.marker.options.geometries?.features[0]?.id}
{josmId ? (
<a
href={`http://127.0.0.1:8111/load_object?objects=${josmId}&new_layer=true`}
onClick={(e) => {
e.preventDefault();
loadObjectsIntoJOSM([josmId], true);
}}
title="Open in JOSM"
>
{nameValue}
</a>
) : (
nameValue
)}
</div>
</div>

Expand Down
4 changes: 2 additions & 2 deletions src/pages/Review/TasksReview/Messages.js
Original file line number Diff line number Diff line change
Expand Up @@ -151,12 +151,12 @@ export default defineMessages({

idLabel: {
id: "Review.Task.fields.id.label",
defaultMessage: "Internal Id",
defaultMessage: "Task ID",
},

featureIdLabel: {
id: "Review.Task.fields.featureId.label",
defaultMessage: "Feature Id",
defaultMessage: "OSM ID",
},

statusLabel: {
Expand Down
36 changes: 33 additions & 3 deletions src/pages/Review/TasksReview/TasksReviewTable.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ import WithSavedFilters from "../../../components/HOCs/WithSavedFilters/WithSave
import IntlDatePicker from "../../../components/IntlDatePicker/IntlDatePicker";
import InTableTagFilter from "../../../components/KeywordAutosuggestInput/InTableTagFilter";
import PaginationControl from "../../../components/PaginationControl/PaginationControl";
import AsIdentifiableFeature from "../../../interactions/TaskFeature/AsIdentifiableFeature";
import { loadObjectsIntoJOSM } from "../../../services/Editor/Editor";
import ManageSavedFilters from "../../../components/SavedFilters/ManageSavedFilters";
import SavedFiltersList from "../../../components/SavedFilters/SavedFiltersList";
import SvgSymbol from "../../../components/SvgSymbol/SvgSymbol";
Expand Down Expand Up @@ -716,6 +718,16 @@ const GearDropdown = ({
);
};

const osmIdForTask = (task) => {
const feature = task?.geometries?.features?.[0];
if (!feature) return null;
const identifiable = AsIdentifiableFeature(feature);
const osmId = identifiable.osmId();
const osmType = identifiable.osmType();
if (!osmId || !osmType) return null;
return `${osmType[0]}${osmId}`;
};

export const setupColumnTypes = (props, openComments, criteria) => {
const handleClick = (e, linkTo) => {
e.preventDefault();
Expand Down Expand Up @@ -766,7 +778,7 @@ export const setupColumnTypes = (props, openComments, criteria) => {
<SearchFilter
value={filterValue}
onChange={setFilter}
placeholder="Search ID..."
placeholder="Search Task ID..."
inputClassName={inputStyles}
/>
{filterValue && (
Expand All @@ -790,7 +802,25 @@ export const setupColumnTypes = (props, openComments, criteria) => {
columns.featureId = {
id: "featureId",
Header: props.intl.formatMessage(messages.featureIdLabel),
accessor: (row) => row.name || row.title,
accessor: (row) => osmIdForTask(row) || row.name || row.title,
Cell: ({ value, row }) => {
const josmId = osmIdForTask(row.original);
if (!josmId) {
return value || "";
}
return (
<a
href={`http://127.0.0.1:8111/load_object?objects=${josmId}&new_layer=true`}
onClick={(e) => {
e.preventDefault();
loadObjectsIntoJOSM([josmId], true);
}}
title="Open in JOSM"
>
{value}
</a>
);
},
width: 120,
minWidth: 80,
disableSortBy: true,
Expand All @@ -799,7 +829,7 @@ export const setupColumnTypes = (props, openComments, criteria) => {
<SearchFilter
value={filterValue}
onChange={setFilter}
placeholder="Search feature ID..."
placeholder="Search OSM ID..."
inputClassName={inputStyles}
/>
{filterValue && (
Expand Down
7 changes: 4 additions & 3 deletions src/services/Task/TaskReview/TaskReview.js
Original file line number Diff line number Diff line change
Expand Up @@ -272,7 +272,8 @@ const buildQueryFilters = function (criteria, addedColumns) {
return capitalizedKey.charAt(0).toUpperCase() + capitalizedKey.slice(1);
});
//Fix Headers
displayedColumns = displayedColumns.map((e) => (e === "Id" ? "Internal Id" : e));
displayedColumns = displayedColumns.map((e) => (e === "Id" ? "Task ID" : e));
displayedColumns = displayedColumns.map((e) => (e === "Feature Id" ? "OSM ID" : e));
displayedColumns = displayedColumns.map((e) => (e === "Mapper Controls" ? "Actions" : e));
displayedColumns = displayedColumns.map((e) => (e === "Reviewer Controls" ? "Actions" : e));
displayedColumns = displayedColumns.map((e) => (e === "Review Requested By" ? "Mapper" : e));
Expand Down Expand Up @@ -470,7 +471,7 @@ export const loadNextReviewTask = function (criteria = {}, lastTaskId, asMetaRev
);

return function (dispatch) {
const params = { sort, order, ...searchParameters, asMetaReview };
const params = { sort, order, ...searchParameters, asMetaReview, includeTags: true };
if (Number.isFinite(lastTaskId)) {
params.lastTaskId = lastTaskId;
}
Expand All @@ -497,7 +498,7 @@ export const fetchTaskForReview = function (taskId, includeMapillary = false) {
return new Endpoint(api.task.startReview, {
schema: taskSchema(),
variables: { id: taskId },
params: { mapillary: includeMapillary },
params: { mapillary: includeMapillary, includeTags: true },
})
.execute()
.then((normalizedResults) => {
Expand Down
Loading