Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add all csv info to displayed table on successful task creation #5491

Merged
merged 10 commits into from
Jun 1, 2021
Merged
76 changes: 41 additions & 35 deletions frontend/javascripts/admin/task/task_create_form_view.js
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand Down Expand Up @@ -117,14 +117,13 @@ export function downloadTasksAsCSV(tasks: Array<APITask>) {
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);
}
Expand All @@ -138,14 +137,6 @@ export function handleTaskCreationResponse(response: TaskCreationResponseContain
const subHeadingStyle = { fontWeight: "bold" };
const displayResultsStyle = { maxHeight: 300, overflow: "auto" };

const warningsContent =
warnings.length > 0 ? (
<div>
<div style={subHeadingStyle}>There were warnings during task creation:</div>
<div>{warnings.join("\n")}</div>
</div>
) : null;

tasks.forEach((taskResponse: TaskCreationResponse, i: number) => {
if (taskResponse.status === 200 && taskResponse.success) {
if (!teamName) {
Expand All @@ -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 ? (
<div>
<div style={subHeadingStyle}>
<WarningOutlined style={{ color: "var(--ant-warning)" }} /> There were warnings during
task creation:
</div>
<div style={{ whiteSpace: "pre-line" }}>{warnings.join("\n")}</div>
</div>
) : null;

const failedTasksAsString = failedTasks.join("");
const successfulTasksContent =
successfulTasks.length <= maxDisplayedTasksCount ? (
Expand All @@ -165,7 +174,7 @@ export function handleTaskCreationResponse(response: TaskCreationResponseContain
{successfulTasks.map(task => taskToShortText(task)).join("\n")}
</pre>
) : (
"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 ? (
Expand All @@ -184,37 +193,34 @@ export function handleTaskCreationResponse(response: TaskCreationResponseContain
{warningsContent}
{successfulTasks.length > 0 ? (
<div>
<div style={{ display: "flex", justifyContent: "center", margin: 20 }}>
<Button onClick={() => downloadTasksAsCSV(successfulTasks)} type="primary">
Download task info as CSV
</Button>
</div>
<div style={subHeadingStyle}> Successful Tasks: </div>
<div style={displayResultsStyle}>{successfulTasksContent}</div>
</div>
) : null}
{successfulTasks.length > 0 ? (
<React.Fragment>
<br />
<Button onClick={() => downloadTasksAsCSV(successfulTasks)}>
Download task info as CSV
</Button>
<br />
</React.Fragment>
) : null}
{failedTasks.length > 0 ? (
<React.Fragment>
<Divider />
<div>
<br />
<div style={{ display: "flex", justifyContent: "center", margin: 20 }}>
<Button
onClick={() => {
const blob = new Blob([failedTasksAsString], {
type: "text/plain;charset=utf-8",
});
saveAs(blob, "failed-tasks.csv");
}}
>
Download failed task info as CSV
</Button>
</div>
<div style={subHeadingStyle}> Failed Tasks:</div>
<div style={displayResultsStyle}> {failedTasksContent}</div>
<br />
<Button
onClick={() => {
const blob = new Blob([failedTasksAsString], {
type: "text/plain;charset=utf-8",
});
saveAs(blob, "failed-tasks.csv");
}}
>
Download failed task info as CSV
</Button>
<br />
</div>
</React.Fragment>
Expand Down
8 changes: 6 additions & 2 deletions frontend/javascripts/components/formatted_date.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,12 @@ const defaultTimeFormat = "YYYY-MM-DD HH:mm";
* a pure string representation. In all other cases, please prefer the
* <FormattedDate /> 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({
Expand Down