Skip to content

Commit

Permalink
Create separate file selectors for the 3 types of files and no longer…
Browse files Browse the repository at this point in the history
… infer the type based on file name.
  • Loading branch information
ocielliottc committed Sep 6, 2024
1 parent 23bfe9e commit d8f9080
Show file tree
Hide file tree
Showing 4 changed files with 108 additions and 77 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -69,19 +69,43 @@ public ReportDataController(ReportDataServices reportDataServices,
}

@Post(uri="/upload", consumes = MediaType.MULTIPART_FORM_DATA)
public Mono<List<String>> upload(@Part("file") Publisher<CompletedFileUpload> file) {
return Flux.from(file)
.subscribeOn(Schedulers.boundedElastic())
.map(part -> {
try {
reportDataServices.store(part);
return part.getFilename();
} catch(IOException ex) {
LOG.error(ex.toString());
return "";
}
})
.collectList();
public Mono<List<List<String>>> upload(
@Part("comp") Publisher<CompletedFileUpload> comp,
@Part("curr") Publisher<CompletedFileUpload> curr,
@Part("pos") Publisher<CompletedFileUpload> pos) {
// There is probably an easier and better way to do this!
Mono<List<String>> compHist = Flux.from(comp)
.subscribeOn(Schedulers.boundedElastic())
.map(part -> uploadHelper(
ReportDataServices.DataType.compensationHistory, part)
).collectList();
Mono<List<String>> currInfo = Flux.from(curr)
.subscribeOn(Schedulers.boundedElastic())
.map(part -> uploadHelper(
ReportDataServices.DataType.currentInformation, part)
).collectList();
Mono<List<String>> posHist = Flux.from(pos)
.subscribeOn(Schedulers.boundedElastic())
.map(part -> uploadHelper(
ReportDataServices.DataType.positionHistory, part)
).collectList();

Flux<List<String>> merged = Flux.empty();
merged = merged.mergeWith(compHist);
merged = merged.mergeWith(currInfo);
merged = merged.mergeWith(posHist);
return merged.collectList();
}

private String uploadHelper(ReportDataServices.DataType dataType,
CompletedFileUpload file) {
try {
reportDataServices.store(dataType, file);
return file.getFilename();
} catch(IOException ex) {
LOG.error(ex.toString());
return "";
}
}

@Get
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package com.objectcomputing.checkins.services.reports;

import com.objectcomputing.checkins.exceptions.BadArgException;
import com.objectcomputing.checkins.exceptions.NotFoundException;

import io.micronaut.http.multipart.CompletedFileUpload;
Expand All @@ -13,7 +12,7 @@ public enum DataType {
compensationHistory, positionHistory, currentInformation
}

void store(CompletedFileUpload file) throws IOException, BadArgException;
void store(DataType dataType, CompletedFileUpload file) throws IOException;

ByteBuffer get(DataType dataType) throws NotFoundException;
}
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ public ReportDataServicesImpl(


@Override
public void store(CompletedFileUpload file) throws IOException, BadArgException {
public void store(DataType dataType, CompletedFileUpload file) throws IOException {
MemberProfile currentUser = currentUserServices.getCurrentUser();
boolean isAdmin = currentUserServices.isAdmin();
validate(!isAdmin, NOT_AUTHORIZED_MSG);
Expand All @@ -67,20 +67,6 @@ public void store(CompletedFileUpload file) throws IOException, BadArgException
storedUploads.put(id, perUser);
}

// Translate the file name to a data type that we know about.
String fileName = file.getFilename().toLowerCase();
DataType dataType;
if (fileName.contains("comp")) {
dataType = DataType.compensationHistory;
} else if (fileName.contains("position")) {
dataType = DataType.positionHistory;
} else if (fileName.contains("current") ||
fileName.contains("information")) {
dataType = DataType.currentInformation;
} else {
throw new BadArgException("Unable to determine data type: " + fileName);
}

// Update the timestamp to allow us to check later to see if we
// need to remove this user's data.
perUser.timestamp = new Date();
Expand Down
116 changes: 69 additions & 47 deletions web-ui/src/pages/MeritReportPage.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,9 @@ const MeritReportPage = () => {
const [searchResults, setSearchResults] = useState([]);
const [allSearchResults, setAllSearchResults] = useState([]);
const [editedSearchRequest, setEditedSearchRequest] = useState([]);
const [selectedFile, setSelectedFile] = useState(null);
const [selectedCompHist, setSelectedCompHist] = useState(null);
const [selectedCurrInfo, setSelectedCurrInfo] = useState(null);
const [selectedPosHist, setSelectedPosHist] = useState(null);
const [reviewPeriodId, setReviewPeriodId] = useState([]);
const [reviewPeriods, setReviewPeriods] = useState([]);

Expand Down Expand Up @@ -109,51 +111,51 @@ const MeritReportPage = () => {
return formatDate(date);
};

const onFileSelected = e => {
setSelectedFile(e.target.files);
const onCompHistSelected = e => {
setSelectedCompHist(e.target.files[0]);
};

const upload = async files => {
if (!files) {
const onCurrInfoSelected = e => {
setSelectedCurrInfo(e.target.files[0]);
};

const onPosHistSelected = e => {
setSelectedPosHist(e.target.files[0]);
};

const upload = async () => {
if (!selectedCompHist || !selectedCurrInfo || !selectedPosHist) {
return;
}

let errors;
let success = 0;
for (let i = 0; i < files.length; i++) {
const file = files[i];
let formData = new FormData();
formData.append('file', file);
const res = await uploadData("/services/report/data/upload",
csrf, formData);
if (res?.error) {
const error = res?.error?.message;
if (errors) {
errors += "\n" + error;
} else {
errors = error;
}
}
if (res?.payload?.data) {
success++;
}
}
const files = [
{label: 'comp', file: selectedCompHist },
{label: 'curr', file: selectedCurrInfo },
{label: 'pos', file: selectedPosHist },
];

if (errors) {
let formData = new FormData();
for (let file of files) {
formData.append(file.label, file.file);
}
const res = await uploadData("/services/report/data/upload",
csrf, formData);
if (res?.error) {
const error = res?.error?.message;
dispatch({
type: UPDATE_TOAST,
payload: {
severity: 'error',
toast: errors
toast: error
}
});
} else {
}
if (res?.payload?.data) {
dispatch({
type: UPDATE_TOAST,
payload: {
severity: 'success',
toast: success == 1 ? 'File was successfully uploaded' :
'Files were successfully uploaded'
toast: 'Files were successfully uploaded'
}
});
}
Expand Down Expand Up @@ -198,10 +200,6 @@ const MeritReportPage = () => {
return data;
};

const uploadLabel = (files) => {
return files.length == 1 ? "Upload File" : "Upload Files";
};

const uploadDocument = async (directory, name, text) => {
if (!directory || !name || !text) {
return;
Expand Down Expand Up @@ -477,30 +475,54 @@ const MeritReportPage = () => {
setReviewPeriodId(newValue);
};

const checkMark = "✓";

return (
<div className="merit-report-page">
<Button color="primary" className="space-between">
<label htmlFor="file-upload">
<h3>Choose CSV Files</h3>
<label htmlFor="file-upload-comp">
<h3>Compenstion History File {selectedCompHist && checkMark}</h3>
<input
accept=".csv"
id="file-upload-comp"
onChange={onCompHistSelected}
style={{ display: 'none' }}
type="file"
/>
</label>
</Button>
<Button color="primary" className="space-between">
<label htmlFor="file-upload-curr">
<h3>Current Information File {selectedCurrInfo && checkMark}</h3>
<input
accept=".csv"
id="file-upload-curr"
onChange={onCurrInfoSelected}
style={{ display: 'none' }}
type="file"
/>
</label>
</Button>
<Button color="primary" className="space-between">
<label htmlFor="file-upload-pos">
<h3>Position History File {selectedPosHist && checkMark}</h3>
<input
accept=".csv"
id="file-upload"
onChange={onFileSelected}
id="file-upload-pos"
onChange={onPosHistSelected}
style={{ display: 'none' }}
type="file"
multiple
/>
</label>
</Button>
<div className="buttons space-between">
{selectedFile && (
<Button
color="primary"
onClick={() => upload(selectedFile)}
>
{uploadLabel(selectedFile)}
</Button>
)}
<Button
color="primary"
onClick={() => upload()}
disabled={!selectedCompHist || !selectedCurrInfo || !selectedPosHist}
>
Upload Files
</Button>
</div>
<MemberSelector
className="merit-member-selector space-between"
Expand Down

0 comments on commit d8f9080

Please sign in to comment.