Skip to content

Commit

Permalink
feat(UI): Import CSV-license file PAGE
Browse files Browse the repository at this point in the history
Signed-off-by: dushimsam <[email protected]>
  • Loading branch information
dushimsam committed Sep 6, 2022
1 parent cf11dae commit 7aa63ba
Show file tree
Hide file tree
Showing 9 changed files with 237 additions and 3 deletions.
6 changes: 6 additions & 0 deletions src/Routes.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ const DeleteUser = React.lazy(() => import("pages/Admin/Users/Delete"));
const AddUser = React.lazy(() => import("pages/Admin/Users/Add"));
const EditUser = React.lazy(() => import("pages/Admin/Users/Edit"));
const AddLicense = React.lazy(() => import("pages/Admin/License/Create"));
const ImportLicense = React.lazy(() => import("pages/Admin/License/Import"));
const SelectLicense = React.lazy(() =>
import("pages/Admin/License/SelectLicense")
);
Expand Down Expand Up @@ -302,6 +303,11 @@ const Routes = () => {
path={routes.admin.license.selectLicense}
component={SelectLicense}
/>
<AdminLayout
exact
path={routes.admin.license.import}
component={ImportLicense}
/>
<AdminLayout
exact
path={routes.admin.users.delete}
Expand Down
20 changes: 20 additions & 0 deletions src/api/licenses.js
Original file line number Diff line number Diff line change
Expand Up @@ -67,3 +67,23 @@ export const createCandidateLicenseApi = ({
},
});
};

export const importLicenseCsvApi = (fileInput, delimiter, enclosure) => {
const url = endpoints.license.importCsv();
const formdata = new FormData();

if (fileInput) {
formdata.append("file_input", fileInput);
formdata.append("delimiter", delimiter);
formdata.append("enclosure", enclosure);
}
return sendRequest({
url,
method: "POST",
isMultipart: true,
headers: {
Authorization: getToken(),
},
body: formdata,
});
};
36 changes: 35 additions & 1 deletion src/api/licenses.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,11 @@
import sendRequest from "api/sendRequest";
import endpoints from "constants/endpoints";
import { getToken } from "shared/authHelper";
import { createCandidateLicenseApi, getAllLicenseApi } from "api/licenses";
import {
createCandidateLicenseApi,
getAllLicenseApi,
importLicenseCsvApi,
} from "api/licenses";

jest.mock("api/sendRequest");

Expand Down Expand Up @@ -54,6 +58,7 @@ describe("licenses", () => {
const licenseUrl = "licenseUrl";
const mergeRequest = "mergeRequest";
const url = endpoints.admin.license.createCandidateLicense();
sendRequest.mockImplementation(() => true);

expect(
createCandidateLicenseApi({
Expand Down Expand Up @@ -85,3 +90,32 @@ describe("licenses", () => {
);
});
});

test("importLicenseCsvApi", () => {
const url = endpoints.license.importCsv();
const expectedBody = new FormData();
const delimiter = "shortName";
const enclosure = "fullName";
const fileInput = "fileInput";

expectedBody.append("file_input", fileInput);
expectedBody.append("delimiter", delimiter);
expectedBody.append("enclosure", enclosure);

sendRequest.mockImplementation(() => true);

expect(importLicenseCsvApi(fileInput, delimiter, enclosure)).toBe(
sendRequest({})
);
expect(sendRequest).toHaveBeenCalledWith(
expect.objectContaining({
url,
method: "POST",
isMultipart: true,
headers: {
Authorization: getToken(),
},
body: expectedBody,
})
);
});
6 changes: 6 additions & 0 deletions src/components/Header/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -312,6 +312,12 @@ const Header = () => {
>
CSV Export
</NavDropdown.Item>
<NavDropdown.Item
as={Link}
to={routes.admin.license.import}
>
CSV Import
</NavDropdown.Item>
<NavDropdown.Item
as={Link}
to={routes.admin.license.selectLicense}
Expand Down
7 changes: 7 additions & 0 deletions src/constants/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,13 @@ export const initialMessageSearch = {
text: "",
};

// constants used in Import License component
export const initialImportCsvLicense = {
fileInput: null,
delimiter: ",",
enclosure: '"',
};

// constants used in Upload/file component
export const initialStateFile = {
folderId: 1,
Expand Down
1 change: 1 addition & 0 deletions src/constants/endpoints.js
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ const endpoints = {
license: {
get: () => `${apiUrl}/license`,
createCandidateLicense: () => `${apiUrl}/license`,
importCsv: () => `${apiUrl}/license/import-csv`,
},
info: {
info: () => `${apiUrl}/info`,
Expand Down
1 change: 1 addition & 0 deletions src/constants/routes.js
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ const routes = {
create: "/admin/license/create",
selectLicense: "/admin/selectLicense",
licenseCSV: "/licenseCSV/fossology-license-export.csv",
import: "/admin/license/import",
},
mantainance: "/admin/mantainance",
},
Expand Down
149 changes: 149 additions & 0 deletions src/pages/Admin/License/Import/index.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
/*
Copyright (C) 2022 Samuel Dushimimana ([email protected])
SPDX-License-Identifier: GPL-2.0
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
version 2 as published by the Free Software Foundation.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License along
with this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/

import React, { useState } from "react";

// Title
import Title from "components/Title";
import { initialImportCsvLicense, initialMessage } from "constants/constants";
import { Alert, Button, InputContainer, Spinner } from "components/Widgets";
import { importLicenseCsv } from "services/licenses";

const ImportLicense = () => {
// Data required for importing the csv file
const [uploadFileData, setUploadFileData] = useState(initialImportCsvLicense);
// State Variables for handling Error Boundaries
const [loading, setLoading] = useState(false);
const [showMessage, setShowMessage] = useState(false);
const [message, setMessage] = useState(initialMessage);

const handleChange = (e) => {
if (e.target.type === "fileInput") {
setUploadFileData({
...uploadFileData,
[e.target.name]: e.target.files[0],
});
} else {
setUploadFileData({
...uploadFileData,
[e.target.name]: e.target.value,
});
}
};

const handleSubmit = async (e) => {
e.preventDefault();
try {
setLoading(true);
const { data } = await importLicenseCsv(uploadFileData);
setMessage({
type: "success",
text: data.message,
});
setUploadFileData(initialImportCsvLicense);
} catch (error) {
setMessage({
type: "danger",
text: error.message,
});
} finally {
setLoading(false);
setShowMessage(true);
}
};
return (
<>
<Title title="Admin Obligation CSV Import" />
<div className="main-container my-3">
<div className="row">
<div className="col-lg-8 col-md-12 col-sm-12 col-12">
{showMessage && (
<Alert
type={message.type}
setShow={setShowMessage}
message={message.text}
/>
)}
<h1 className="font-size-main-heading">
Admin Obligation CSV Import
</h1>
</div>
<div className="col-lg-8 col-md-12 col-sm-12 col-12">
<p>
This option permits uploading a CSV file from your computer to
Your FOSSology server has imposed a maximum upload file size of
700Mbytes.
</p>
</div>
<div className="col-lg-8 col-md-12 col-sm-12 col-12">
<span>Select the CSV-file to upload:</span>
<InputContainer
type="file"
name="fileInput"
id="upload-file-input"
onChange={(e) => handleChange(e)}
/>
</div>
<div className="col-lg-8 col-md-12 col-sm-12 col-12">
<div>
<InputContainer
type="text"
name="name"
id="delimiter"
onChange={handleChange}
value={uploadFileData.delimiter}
>
Delimiter:
</InputContainer>
</div>

<div>
<InputContainer
type="text"
name="name"
id="admin-group-add-name"
onChange={handleChange}
placeholder="Group name"
value={uploadFileData.enclosure}
>
Enclosure:
</InputContainer>
</div>
</div>
<div className="col-lg-8 col-md-12 col-sm-12 col-12">
<Button type="submit" onClick={handleSubmit} className="mt-4">
{loading ? (
<Spinner
as="span"
animation="border"
size="sm"
role="status"
aria-hidden="true"
/>
) : (
"Add"
)}
</Button>
</div>
</div>
</div>
</>
);
};

export default ImportLicense;
14 changes: 12 additions & 2 deletions src/services/licenses.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
Copyright (C) 2021 Shruti Agarwal ([email protected]), Aman Dwivedi ([email protected])
Copyright (C) 2021 Shruti Agarwal ([email protected]), Aman Dwivedi ([email protected]) , Samuel Dushimimana ([email protected])
SPDX-License-Identifier: GPL-2.0
Expand All @@ -16,7 +16,11 @@
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/

import { getAllLicenseApi, createCandidateLicenseApi } from "api/licenses";
import {
getAllLicenseApi,
createCandidateLicenseApi,
importLicenseCsvApi,
} from "api/licenses";

// Fetching the licenses with their kind i.e (candidate, main, all)
export const getAllLicense = (licenseData) => {
Expand All @@ -30,3 +34,9 @@ export const createCandidateLicense = (licenseData) => {
return res;
});
};

export const importLicenseCsv = ({ fileInput, delimiter, enclosure }) => {
return importLicenseCsvApi(fileInput, delimiter, enclosure).then((res) => {
return res;
});
};

0 comments on commit 7aa63ba

Please sign in to comment.