diff --git a/CHANGELOG.unreleased.md b/CHANGELOG.unreleased.md index 8e8724fb8da..f044e79643e 100644 --- a/CHANGELOG.unreleased.md +++ b/CHANGELOG.unreleased.md @@ -21,6 +21,7 @@ For upgrade instructions, please check the [migration guide](MIGRATIONS.released - The visibility of meshes can now be toggled via the meshes tab. [#5346](https://github.com/scalableminds/webknossos/pull/5345) - Added an icon to the info tab of a tracing that links to the dataset settings. It's located next to the dataset name. [#5462](https://github.com/scalableminds/webknossos/pull/5462) - When exporting an user bounding box to tiff, the active mapping will now be applied to the exported data, as well. [#5474](https://github.com/scalableminds/webknossos/pull/5474) +- Changed the layout of the modal that informs the user about the success of task creations and changed the naming schema for the downloadable csv file containing the information about created tasks. [#5491](https://github.com/scalableminds/webknossos/pull/5491) ### Fixed - Fixed that the row selection in the user table wasn't properly preserved when filtering the table and (un)selecting rows. [#5486](https://github.com/scalableminds/webknossos/pull/5486) diff --git a/frontend/javascripts/admin/task/task_create_form_view.js b/frontend/javascripts/admin/task/task_create_form_view.js index 8c13975530b..28413d4ac3b 100644 --- a/frontend/javascripts/admin/task/task_create_form_view.js +++ b/frontend/javascripts/admin/task/task_create_form_view.js @@ -18,7 +18,7 @@ import { import { FormInstance } from "antd/lib/form"; import Toast from "libs/toast"; import React from "react"; -import { InboxOutlined } from "@ant-design/icons"; +import { InboxOutlined, WarningOutlined } from "@ant-design/icons"; import _ from "lodash"; import type { APIDataset, APITaskType, APIProject, APIScript, APITask } from "types/api_flow_types"; @@ -117,14 +117,13 @@ export function downloadTasksAsCSV(tasks: Array) { if (tasks.length < 0) { return; } - const maybeTaskPlural = tasks.length > 2 ? "tasks" : "task"; + const maybeTaskPlural = tasks.length > 1 ? "task_ids" : "task_id"; const lastCreationTime = Math.max(...tasks.map(task => task.created)); - const currentDateAsString = formatDateInLocalTimeZone(lastCreationTime); - const allTeamNames = _.uniq(tasks.map(task => task.team)); - const teamName = allTeamNames.length > 1 ? "multiple_teams" : allTeamNames[0]; + const currentDateAsString = formatDateInLocalTimeZone(lastCreationTime, "YYYY-MM-DD_HH-mm"); + const allProjectNames = _.uniq(tasks.map(task => task.projectName)).join("_"); const allTasksAsStrings = tasks.map(task => taskToText(task)).join("\n"); const csv = [TASK_CSV_HEADER, allTasksAsStrings].join("\n"); - const filename = `${teamName}-${maybeTaskPlural}-${currentDateAsString}.csv`; + const filename = `${maybeTaskPlural}_${allProjectNames}_${currentDateAsString}.csv`; const blob = new Blob([csv], { type: "text/plain;charset=utf-8" }); saveAs(blob, filename); } @@ -138,14 +137,6 @@ export function handleTaskCreationResponse(response: TaskCreationResponseContain const subHeadingStyle = { fontWeight: "bold" }; const displayResultsStyle = { maxHeight: 300, overflow: "auto" }; - const warningsContent = - warnings.length > 0 ? ( -
-
There were warnings during task creation:
-
{warnings.join("\n")}
-
- ) : null; - tasks.forEach((taskResponse: TaskCreationResponse, i: number) => { if (taskResponse.status === 200 && taskResponse.success) { if (!teamName) { @@ -156,6 +147,24 @@ export function handleTaskCreationResponse(response: TaskCreationResponseContain failedTasks.push(`Line ${i}: ${taskResponse.error} \n`); } }); + + const allProjectNames = _.uniq(successfulTasks.map(task => task.projectName)); + if (allProjectNames.length > 1) { + warnings.push( + `You created tasks for multiple projects at a time: ${allProjectNames.join(", ")}.`, + ); + } + const warningsContent = + warnings.length > 0 ? ( +
+
+ There were warnings during + task creation: +
+
{warnings.join("\n")}
+
+ ) : null; + const failedTasksAsString = failedTasks.join(""); const successfulTasksContent = successfulTasks.length <= maxDisplayedTasksCount ? ( @@ -165,7 +174,7 @@ export function handleTaskCreationResponse(response: TaskCreationResponseContain {successfulTasks.map(task => taskToShortText(task)).join("\n")} ) : ( - "Too many tasks to show, please use CSV download for a full list." + "Too many tasks to show, please use CSV download above for a full list." ); const failedTasksContent = failedTasks.length <= maxDisplayedTasksCount ? ( @@ -184,37 +193,34 @@ export function handleTaskCreationResponse(response: TaskCreationResponseContain {warningsContent} {successfulTasks.length > 0 ? (
+
+ +
Successful Tasks:
{successfulTasksContent}
) : null} - {successfulTasks.length > 0 ? ( - -
- -
-
- ) : null} {failedTasks.length > 0 ? (
-
+
+ +
Failed Tasks:
{failedTasksContent}

-
diff --git a/frontend/javascripts/components/formatted_date.js b/frontend/javascripts/components/formatted_date.js index 4774e6c1aa9..2982c4b63fd 100644 --- a/frontend/javascripts/components/formatted_date.js +++ b/frontend/javascripts/components/formatted_date.js @@ -10,8 +10,12 @@ const defaultTimeFormat = "YYYY-MM-DD HH:mm"; * a pure string representation. In all other cases, please prefer the * component below. */ -export function formatDateInLocalTimeZone(date?: number = Date.now()): string { - return moment(date).format(defaultTimeFormat); +export function formatDateInLocalTimeZone( + date?: number = Date.now(), + format?: ?string = null, +): string { + format = format || defaultTimeFormat; + return moment(date).format(format); } export default function FormattedDate({