CSV generation button on SignupListPage

This commit is contained in:
Aarni Halinen
2020-12-05 17:45:51 +02:00
parent b444c8e2f6
commit 8e5cd96755
3 changed files with 47 additions and 9 deletions
+14
View File
@@ -976,6 +976,15 @@
"csstype": "^2.2.0"
}
},
"@types/react-csv": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/@types/react-csv/-/react-csv-1.1.1.tgz",
"integrity": "sha512-sP8AxGrFJ/kb7ygFpGkssdD/vKSTqdZDJbw3pJKTCa1C0UoT+0+rdUWy2fZqvhvvdpHG+OCJ4G8O7OZqVIa+BA==",
"dev": true,
"requires": {
"@types/react": "*"
}
},
"@types/react-dom": {
"version": "16.8.4",
"resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-16.8.4.tgz",
@@ -14999,6 +15008,11 @@
"tiny-invariant": "^1.0.4"
}
},
"react-csv": {
"version": "2.0.3",
"resolved": "https://registry.npmjs.org/react-csv/-/react-csv-2.0.3.tgz",
"integrity": "sha512-exyAdFLAxtuM4wNwLYrlKyPYLiJ7e0mv9tqPAd3kq+k1CiJFtznevR3yP0icv5q/y200w+lzNgi7TQn1Wrhu0w=="
},
"react-dom": {
"version": "16.8.6",
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-16.8.6.tgz",
+2
View File
@@ -47,6 +47,7 @@
"@types/js-cookie": "2.2.4",
"@types/node": "10.14.7",
"@types/react": "16.8.18",
"@types/react-csv": "1.1.1",
"@types/react-dom": "16.8.4",
"@types/react-helmet": "6.0.0",
"@types/react-jsonschema-form": "1.7.3",
@@ -122,6 +123,7 @@
"normalize.css": "8.0.1",
"query-string": "6.5.0",
"react-beautiful-dnd": "10.1.1",
"react-csv": "2.0.3",
"react-helmet": "5.2.1",
"react-jsonschema-form": "^1.8.1",
"react-markdown": "4.3.1",
+31 -9
View File
@@ -1,9 +1,12 @@
import React, { useEffect, useState } from "react";
import { Helmet } from "react-helmet";
import { RouteComponentProps } from "react-router-dom";
import styled from "styled-components";
import { CSVLink } from "react-csv";
import AdminListCommon from "@views/admin/AdminListCommon";
import { SignupForm, getForm, getSignups } from "@models/SignupForm";
import { Signup, deleteSignup } from "@models/Signup";
import { Button } from "@components/index";
interface MatchParams {
id?: string;
@@ -11,6 +14,9 @@ interface MatchParams {
type SignupEmailPageProps = RouteComponentProps<MatchParams>;
const StyledButton = styled(Button)<{ colorOverride: "red" | "green" }>`
background-color: ${(p: any) => p.colorOverride};
`;
const SignupEmailPage: React.FC<SignupEmailPageProps> = ({ match: { params: { id } } }) => {
const [signupForm, setSignupForm] = useState<SignupForm>(null);
@@ -24,13 +30,6 @@ const SignupEmailPage: React.FC<SignupEmailPageProps> = ({ match: { params: { id
}, [id]);
const questions = signupForm ? signupForm.questions.map(q => ({
title: q.name,
id: q.id
})) : [];
const title = signupForm ? signupForm.title_fi : "Loading...";
const confirmDelete = async (signup: Signup, question: any) => {
if(confirm(`Delete: ${signup.id}: ${signup.answer[question.id]}; Are you sure?`) === true) {
try {
@@ -42,6 +41,21 @@ const SignupEmailPage: React.FC<SignupEmailPageProps> = ({ match: { params: { id
}
}
const title = signupForm ? signupForm.title_fi : "Loading...";
const questions = signupForm ? signupForm.questions.map(q => ({
title: q.name,
id: q.id
})) : [];
// Generate 2-dimensional array where rows are signups and columns are answers to questions.
const CSVData = signups.map((s) => questions.map(q => s.answer[q.id]));
// Add reserve signup "header"
if (signupForm?.quota) {
CSVData.splice(signupForm.quota, 0, ["RESERVE-SIGNUPS"]);
}
return (
<AdminListCommon>
<Helmet>
@@ -54,8 +68,16 @@ const SignupEmailPage: React.FC<SignupEmailPageProps> = ({ match: { params: { id
{questions.map(q => (
<th key={q.id}>{q.title}</th>
))}
<th>
<CSVLink data={CSVData} headers={questions.map(q => q.title)} separator=";">
<StyledButton colorOverride="green" type="filled">
Download CSV
</StyledButton>
</CSVLink>
</th>
</tr>
</thead>
<tbody>
{signups.map(s => (
<tr key={s.id}>
@@ -65,9 +87,9 @@ const SignupEmailPage: React.FC<SignupEmailPageProps> = ({ match: { params: { id
</td>
))}
<td>
<button onClick={() => confirmDelete(s, questions[0])}>
<StyledButton colorOverride="red" type="filled" onClick={() => confirmDelete(s, questions[0])}>
Delete
</button>
</StyledButton>
</td>
</tr>
))}