Integrated old with new classes. Header Correction not working. Can't hold selected value.

associator_rewrite
Griffiths Lott 3 years ago
parent 0d29079c30
commit 72113dc863
  1. 230
      FILUPLOAD_DIFF
  2. 4
      backend/appsettings.json
  3. 15
      src/App.vue
  4. 120
      src/components/FileUpload.vue
  5. 63
      src/components/HeaderCorrection.vue
  6. 2
      src/components/MissingHeaderBox.vue
  7. 4
      src/headerTemplate.js
  8. 8
      src/helpers.js

@ -0,0 +1,230 @@
<template> <template>
<form> <form>
<input type="file" id="uploadInput" accept=".xlsx" @chang <input type="file" id="uploadInput" accept=".xlsx" @chang
<button type="submit" @click.prevent="parseUpload" :disab <button type="submit" @click.prevent="parseUpload" :disab
</form> </form>
</template> </template>
<script> <script>
import { read, utils } from "xlsx"; import { read, utils } from "xlsx";
import { store } from '../store.js' | import { store, clearStore } from '../store.js'
import { HeaderAssociator } from '../helpers.js' | import { UserHeader } from "@/userHeader";
> import { HeaderTemplate, associateHeaders } from "@/headerTem
>
function findFirstNonBlankRow(worksheet) { function findFirstNonBlankRow(worksheet) {
const range = utils.decode_range(worksheet['!ref']); const range = utils.decode_range(worksheet['!ref']);
// We'll check at most of 20 rows // We'll check at most of 20 rows
for (let row = range.s.r; row <= Math.min(range.e.r,20); ro for (let row = range.s.r; row <= Math.min(range.e.r,20); ro
var headerRow = true; var headerRow = true;
for (let col = 0; col < 20; col++) { for (let col = 0; col < 20; col++) {
const cell = worksheet[utils.encode_cell({ r: row, c: c const cell = worksheet[utils.encode_cell({ r: row, c: c
if (!cell || cell.v === '') { if (!cell || cell.v === '') {
headerRow = false; headerRow = false;
break; break;
} }
} }
if (headerRow) { if (headerRow) {
return row; return row;
} }
} }
return null; return null;
} }
export default { export default {
name: 'FileUpload', name: 'FileUpload',
data() { data() {
return { return {
// User uploaded file // User uploaded file
userFile: null, userFile: null,
// Header Template provided by server // Header Template provided by server
headerTemplateList: [], | headerTemplateList: null,
> userHeaders: [],
// Defines whether data row is checked agianst value re // Defines whether data row is checked agianst value re
validateData: true, | invalidData: [],
// Store data for access by other components // Store data for access by other components
store, store,
// Controls whether or not the user can submit a file // Controls whether or not the user can submit a file
// - When a file is selected, then disabled when submit // - When a file is selected, then disabled when submit
canSubmit: false, canSubmit: false,
} }
}, },
async mounted() { async mounted() {
// We want to get the lastest template header specificati // We want to get the lastest template header specificati
try { try {
const configRequestOptions = { const configRequestOptions = {
method: 'GET', method: 'GET',
redirect: 'follow', redirect: 'follow',
}; };
const resp = await fetch(process.env.VUE_APP_TEMPLATE_H const resp = await fetch(process.env.VUE_APP_TEMPLATE_H
let respJson = await resp.json(); let respJson = await resp.json();
console.log(respJson); | console.info("RespJ: ", respJson);
this.headerTemplateList = respJson["HeaderTemplate"]; <
//FIXME: This is only for testing purposes, REMOVE THIS //FIXME: This is only for testing purposes, REMOVE THIS
this.validateData = true;//respJson["ValidateData"]; this.validateData = true;//respJson["ValidateData"];
console.log(this.headerTemplateList); | this.headerTemplateList = respJson["HeaderTemplate"].ma
console.log(this.validateData); | return new HeaderTemplate (headerTemplate["Header"],h
> this.validateData, headerTemplate["ValueRegex"], he
> });
> // Sort this list to make association faster
> this.headerTemplateList.sort((a,b) => {
> const ha = a.header.toLowerCase();
> const hb = b.header.toLowerCase();
> if (ha < hb) return -1;
> if (ha > hb) return 1;
> return 0;
> });
> console.info("Recieved HeaderTemplateList: ", this.head
} catch (error) { } catch (error) {
//FIXME: emit error internal issues //FIXME: emit error internal issues
console.error(error); console.error(error);
} }
}, },
methods: { methods: {
fileSelected(event) { fileSelected(event) {
// Make sure the user can't still act on the old file // Make sure the user can't still act on the old file
this.$emit('parsed-upload', null); | this.$emit('parsed-upload', null, []);
// Clear old file data // Clear old file data
store.missingHeaders = []; | this.invalidData = [];
store.documentHeaders = []; | this.userHeaders = [];
> clearStore();
>
> // If the user had previously selected a file,
> // we need to clear the old header associations
> if (this.userFile !== null) {
> this.headerTemplateList.map(headerTemplate => {
> headerTemplate.userHeader = null;
> })
> }
>
this.userFile = event.target.files[0]; this.userFile = event.target.files[0];
this.canSubmit = true; this.canSubmit = true;
}, },
getHeaders(worksheet, sheetName, headerIndex) { getHeaders(worksheet, sheetName, headerIndex) {
// Store the found headers // Store the found headers
var combinedHeadersString = ""; <
// Use the range to make sure we don't go out of bounds // Use the range to make sure we don't go out of bounds
const range = utils.decode_range(worksheet['!ref']); const range = utils.decode_range(worksheet['!ref']);
for (let col = 0; col < range.e.c; col++){ for (let col = 0; col < range.e.c; col++){
let cellAddress = utils.encode_cell({c: col, r: heade let cellAddress = utils.encode_cell({c: col, r: heade
let cellObj = worksheet[cellAddress]; let cellObj = worksheet[cellAddress];
// n represents number type (which is probably the st // n represents number type (which is probably the st
if (cellObj === undefined || cellObj.t === 'n') { bre if (cellObj === undefined || cellObj.t === 'n') { bre
// Add the header to the combined headers string | let dataAddress = utils.encode_cell({c: col, r: heade
combinedHeadersString += cellObj.v; | let dataValue = worksheet[dataAddress] ? worksheet[da
let headerAssociator = new HeaderAssociator(cellObj.v |
if (!this.validateData) {headerAssociator.isValidData | // Record the user header
store.documentHeaders.push(headerAssociator); | let userHeader = new UserHeader(cellObj.v, sheetName,
> this.userHeaders.push(userHeader);
} }
return combinedHeadersString; <
}, },
async parseUpload() { async parseUpload() {
this.canSubmit = false; this.canSubmit = false;
const fileBuffer = await this.userFile.arrayBuffer(); const fileBuffer = await this.userFile.arrayBuffer();
var workbook = await read(fileBuffer, {type: 'array'}); var workbook = await read(fileBuffer, {type: 'array'});
if (workbook === null) { if (workbook === null) {
//FIXME: Emit bad spreadsheet to app //FIXME: Emit bad spreadsheet to app
console.error(`No workbook found! Could not parse fil console.error(`No workbook found! Could not parse fil
return; return;
} }
var validWorksheets = [] | let validWorksheets = false;
var combinedHeadersString = ''; <
// Go through each worksheet // Go through each worksheet
for (let sheetName of workbook.SheetNames) { for (let sheetName of workbook.SheetNames) {
// Open the actual worksheet // Open the actual worksheet
let worksheet = workbook.Sheets[sheetName]; let worksheet = workbook.Sheets[sheetName];
// Find the first non-blank row of 20 // Find the first non-blank row of 20
var headerIndex = findFirstNonBlankRow(worksheet); var headerIndex = findFirstNonBlankRow(worksheet);
if (headerIndex === null) { if (headerIndex === null) {
// Probably not a sheet we need to process // Probably not a sheet we need to process
console.warn(`${sheetName} | No header row found!`) console.warn(`${sheetName} | No header row found!`)
} }
// Add the header to the combined headers string | // getHeaders will created the UserHeader objects
// getHeaders will created the AssociatedHeaders obje | this.getHeaders(worksheet, sheetName, headerIndex);
combinedHeadersString += this.getHeaders(worksheet, s | validWorksheets = true;
// Note which worksheets are actually being processed <
validWorksheets.push(sheetName); <
} }
if (validWorksheets.length === 0) { | if (!validWorksheets) {
//FIXME: emit bad spreadsheet to App //FIXME: emit bad spreadsheet to App
console.error("No worksheets found!"); console.error("No worksheets found!");
return; return;
} }
// Check each template regex against the combined heade | // Sort the user headers to make association faster
for (const headerTemplate of this.headerTemplateList) { | this.userHeaders.sort((a,b) => {
// 'i' option means ignore case | const ha = a.label.toLowerCase();
let headerRegex = RegExp(headerTemplate["HeaderRegex" | const hb = b.label.toLowerCase();
let headerName = headerTemplate["Header"]; | if (ha < hb) return -1;
| if (ha > hb) return 1;
// Check to see if the template header is present in | return 0;
let searchResults = headerRegex.exec(combinedHeadersS | });
if (searchResults === null) { |
store.missingHeaders.push(headerName); | // console.log("User Headers:", this.userHeaders);
continue; | // console.log("Template Headers:", this.headerTemplate
} | let processedArrays = associateHeaders(this.userHeaders
let docHeader = searchResults[0]; |
> store.unassociatedUserHeaders = processedArrays[0];
> store.unassociatedTemplateHeaders = this.headerTemplate
> !headerTemplate.isAssociated();
> });
> this.invalidData = processedArrays[1];
> console.log("Invalid Data:", this.invalidData);
> console.log("Unassociated:", store.unAssociated);
>
> console.log("Updated Template Headers:", this.headerTem
// Find the associated header <
for (let headerAssociator of store.documentHeaders) { <
if (headerAssociator.isSet()) {continue} <
if (headerAssociator.documentHeader === docHeader) <
// Set the associated template header <
headerAssociator.swapTemplateHeader(headerName); <
<
if (this.validateData) { <
// If we want to validate the data, then check <
let isNullable = headerTemplate["Nullable"]; <
let headerAddress = utils.decode_cell(headerAss <
// Now we can get the value of the cell below t <
let valueCellAddress = utils.encode_cell(header <
// We need to know which worksheet this cell be <
let worksheet = workbook.Sheets[headerAssociato <
let valueObj = worksheet[valueCellAddress]; <
// Check if the cell is null, if so does it mat <
if (valueObj !== undefined ) { <
// Test the value against regex <
let valueRegex = RegExp(headerTemplate["Value <
let dataValue = valueObj.v.toString(); <
let isValid = valueRegex.test(dataValue); <
if (!isValid) { <
// record the invalid data and set isValidD <
headerAssociator.invalidData(dataValue); <
} <
} else { <
// isValid matches isNullable <
headerAssociator.isValidData = isNullable; <
} <
} <
// We found the header and processed it so stop l <
break; <
} <
} <
} <
//TODO: Remove logs <
console.log(`Document headers (${store.documentHeaders. <
console.log(`Missing headers (${store.missingHeaders.le <
// emit the uploaded file & parsed data up to parent // emit the uploaded file & parsed data up to parent
this.$emit('parsed-upload', this.userFile); | this.$emit('parsed-upload', this.userFile, this.invalid
} }
} }
} }
</script> </script>

@ -19,7 +19,7 @@
{"Header": "Customer Physical City", "HeaderRegex": "(cust(omers?)?\\s?\\w*\\s?city)" ,"ValueRegex": "(\\w+\\s?)+", "Nullable": true},
{"Header": "Customer Physical State", "HeaderRegex": "(cust(omers?)?\\s?\\w*\\s?state)" ,"ValueRegex": "\\w+", "Nullable": true},
{"Header": "Customer Physical Zip", "HeaderRegex": "(cust(omers?)?\\s?\\w*\\s?zip\\s?(code)?)" ,"ValueRegex": "\\d{5}-?(\\d{4})?", "Nullable": true},
{"Header": "Date Booked", "HeaderRegex": "(date\\s?booked)" ,"ValueRegex": "[1-2]?\\d\\/\\d{1,2}\\/(20)?\\d{2}", "Nullable": true},
{"Header": "Date Booked", "HeaderRegex": "DATEVALUE" ,"ValueRegex": "[1-2]?\\d\\/\\d{1,2}\\/(20)?\\d{2}", "Nullable": true},
{"Header": "Term (Months)", "HeaderRegex": "(term\\s?(\\(?months\\)?)?)" ,"ValueRegex": "\\d{1,3}", "Nullable": true},
{"Header": "Payment Amount", "HeaderRegex": "(pa?yme?n?t\\s?am(oun)?t)" ,"ValueRegex": "(\\d{1,2},?)*\\d+(.\\d{2})?", "Nullable": true},
{"Header": "Financed Amount", "HeaderRegex": "(financed\\s?am(oun)?t)" ,"ValueRegex": "(\\d{1,2},?)*\\d+(.\\d{2})?", "Nullable": true},
@ -34,7 +34,7 @@
{"Header": "PG State", "HeaderRegex": "((pg|guarantor)\\s?state)" ,"ValueRegex": "\\d{5}-?(\\d{4})?", "Nullable": true},
{"Header": "PG Zip", "HeaderRegex": "((pg|guarantor)\\s?zip)" ,"ValueRegex": "\\d{3}-?\\d{2}-?\\d{3}", "Nullable": true},
{"Header": "PG SSN", "HeaderRegex": "((pg|guarantor)\\s?ssn)" ,"ValueRegex": "[0-2]?\\d\\/\\d{1,2}\\/(19|20)?\\d{2}", "Nullable": true},
{"Header": "DOB", "HeaderRegex": "(dob|date of birth)" ,"ValueRegex": "\\d{3}", "Nullable": true},
{"Header": "DOB", "HeaderRegex": "DATEVALUE" ,"ValueRegex": "\\d{3}", "Nullable": true},
{"Header": "PG1 FICO", "HeaderRegex": "(pg\\d?\\s?FICO)" ,"ValueRegex": "(\\d{1,2},?)*\\d+(.\\d{2})?", "Nullable": true}
]
}

@ -1,9 +1,9 @@
<template>
<div v-if="invalidDataHeaders.length > 0">
<div v-if="invalidDataHeaders.length > 1000">
<h2>Invalid Headers</h2>
<ul>
<li v-for="header in invalidDataHeaders" :key="header.documentHeader">
{{ header.documentHeader }}
<li v-for="header in invalidDataHeaders" :key="header.label">
{{ header.label }}
</li>
</ul>
</div>
@ -42,8 +42,7 @@ export default {
};
},
methods: {
processUpload(userFile) {
console.log(store.documentHeaders);
processUpload(userFile, invalidHeaders) {
// handle null
if (userFile === null) {
this.invalidDataHeaders = [];
@ -55,10 +54,8 @@ export default {
this.userFile = userFile;
// filter the documentHeaders to get the invalid headers
this.invalidDataHeaders = this.store.documentHeaders.filter(
(header) => !header.isValidData
);
console.log(this.invalidDataHeaders);
this.invalidDataHeaders = invalidHeaders;
//console.log(this.invalidDataHeaders);
// set isUploaded to true
this.isUploaded = true;

@ -9,7 +9,8 @@
import { read, utils } from "xlsx";
import { store } from '../store.js'
import { HeaderAssociator } from '../helpers.js'
import { UserHeader } from "@/userHeader";
import { HeaderTemplate, associateHeaders } from "@/headerTemplate";
function findFirstNonBlankRow(worksheet) {
const range = utils.decode_range(worksheet['!ref']);
@ -58,10 +59,21 @@ export default {
const resp = await fetch(process.env.VUE_APP_TEMPLATE_HEADERS_ENDPOINT, configRequestOptions);
let respJson = await resp.json();
console.log(respJson);
this.headerTemplateList = respJson["HeaderTemplate"];
this.headerTemplateList = respJson["HeaderTemplate"].map(headerTemplate => {
return new HeaderTemplate (headerTemplate["Header"],headerTemplate["HeaderRegex"],
this.validateData, headerTemplate["ValueRegex"], headerTemplate["Nullable"]);
});
// Sort this list to make association faster
this.headerTemplateList.sort((a,b) => {
const ha = a.header.toLowerCase();
const hb = b.header.toLowerCase();
if (ha < hb) return -1;
if (ha > hb) return 1;
return 0;
});
console.info("Recieved HeaderTemplateList: ", this.headerTemplateList);
//FIXME: This is only for testing purposes, REMOVE THIS
this.validateData = true;//respJson["ValidateData"];
console.log(this.headerTemplateList);
console.log(this.validateData);
} catch (error) {
//FIXME: emit error internal issues
@ -76,6 +88,14 @@ export default {
// Clear old file data
store.missingHeaders = [];
store.documentHeaders = [];
// If the user had previously selected a file,
// we need to clear the old header associations
if (this.userFile !== null) {
this.headerTemplateList.map(headerTemplate => {
headerTemplate.userHeader = null;
})
}
this.userFile = event.target.files[0];
this.canSubmit = true;
@ -83,7 +103,6 @@ export default {
getHeaders(worksheet, sheetName, headerIndex) {
// Store the found headers
var combinedHeadersString = "";
// Use the range to make sure we don't go out of bounds
const range = utils.decode_range(worksheet['!ref']);
for (let col = 0; col < range.e.c; col++){
@ -91,13 +110,13 @@ export default {
let cellObj = worksheet[cellAddress];
// n represents number type (which is probably the start of cashflow dates)
if (cellObj === undefined || cellObj.t === 'n') { break }
// Add the header to the combined headers string
combinedHeadersString += cellObj.v;
let headerAssociator = new HeaderAssociator(cellObj.v, sheetName, cellAddress);
if (!this.validateData) {headerAssociator.isValidData = true;}
store.documentHeaders.push(headerAssociator);
let dataAddress = utils.encode_cell({c: col, r: headerIndex + 1});
let dataValue = worksheet[dataAddress] ? worksheet[dataAddress].v : null;
// Record the user header
let userHeader = new UserHeader(cellObj.v, sheetName, cellAddress, dataValue);
store.documentHeaders.push(userHeader);
}
return combinedHeadersString;
},
async parseUpload() {
@ -111,8 +130,7 @@ export default {
return;
}
var validWorksheets = []
var combinedHeadersString = '';
let validWorksheets = false;
// Go through each worksheet
for (let sheetName of workbook.SheetNames) {
// Open the actual worksheet
@ -123,73 +141,39 @@ export default {
// Probably not a sheet we need to process
console.warn(`${sheetName} | No header row found!`);
}
// Add the header to the combined headers string
// getHeaders will created the AssociatedHeaders objects
combinedHeadersString += this.getHeaders(worksheet, sheetName, headerIndex);
// Note which worksheets are actually being processed
validWorksheets.push(sheetName);
// getHeaders will created the UserHeader objects
this.getHeaders(worksheet, sheetName, headerIndex);
validWorksheets = true;
}
if (validWorksheets.length === 0) {
if (!validWorksheets) {
//FIXME: emit bad spreadsheet to App
console.error("No worksheets found!");
return;
}
// Check each template regex against the combined headers string
for (const headerTemplate of this.headerTemplateList) {
// 'i' option means ignore case
let headerRegex = RegExp(headerTemplate["HeaderRegex"],"i");
let headerName = headerTemplate["Header"];
// Sort the user headers to make association faster
store.documentHeaders.sort((a,b) => {
const ha = a.label.toLowerCase();
const hb = b.label.toLowerCase();
if (ha < hb) return -1;
if (ha > hb) return 1;
return 0;
});
// Check to see if the template header is present in the combined headers string
let searchResults = headerRegex.exec(combinedHeadersString);
if (searchResults === null) {
store.missingHeaders.push(headerName);
continue;
}
let docHeader = searchResults[0];
console.log("User Headers:", this.userHeaders);
console.log("Template Headers:", this.headerTemplateList);
let processedArrays = associateHeaders(store.documentHeaders, this.headerTemplateList);
console.log("UPDATED Template Headers:", this.headerTemplateList);
store.missingHeaders = this.headerTemplateList.filter(headerTemplate => !headerTemplate.isAssociated());
store.documentHeaders = processedArrays[0];
//TODO: Deal with invalid headers
let invalidHeaders = processedArrays[1];
// Find the associated header
for (let headerAssociator of store.documentHeaders) {
if (headerAssociator.isSet()) {continue}
if (headerAssociator.documentHeader === docHeader) {
// Set the associated template header
headerAssociator.swapTemplateHeader(headerName);
if (this.validateData) {
// If we want to validate the data, then check the data against the regex
let isNullable = headerTemplate["Nullable"];
let headerAddress = utils.decode_cell(headerAssociator.docHeaderAddress);
// Now we can get the value of the cell below the header
let valueCellAddress = utils.encode_cell(headerAddress.r + 1);
// We need to know which worksheet this cell belongs to
let worksheet = workbook.Sheets[headerAssociator.docWorksheetName];
let valueObj = worksheet[valueCellAddress];
// Check if the cell is null, if so does it matter?
if (valueObj !== undefined ) {
// Test the value against regex
let valueRegex = RegExp(headerTemplate["ValueRegex"],'i');
let dataValue = valueObj.v.toString();
let isValid = valueRegex.test(dataValue);
if (!isValid) {
// record the invalid data and set isValidData to false
headerAssociator.invalidData(dataValue);
}
} else {
// isValid matches isNullable
headerAssociator.isValidData = isNullable;
}
}
// We found the header and processed it so stop looking
break;
}
}
}
//TODO: Remove logs
console.log(`Document headers (${store.documentHeaders.length}): ${store.documentHeaders}`);
console.log(`Missing headers (${store.missingHeaders.length}): ${store.missingHeaders}`);
console.log(`Missing headers (${store.missingHeaders.length})`, store.missingHeaders);
// emit the uploaded file & parsed data up to parent
this.$emit('parsed-upload', this.userFile);
this.$emit('parsed-upload', this.userFile, invalidHeaders);
}
}
}

@ -4,11 +4,11 @@
<h3 class="text-center">{{itemText}}</h3>
</div>
<div class="box-body">
<select class="form-control" @change="updateSelectedDocHeader($event)">
<option>{{firstValue}}</option>
<option v-for="headerIndex in filteredHeaders" :key="headerIndex" :value="headerIndex">{{store.documentHeaders[headerIndex].documentHeader}}</option>
<select id="sel" class="form-control" @change="changeSelectedHeader($event)">
<option :value="itemText"></option>
<option v-for="({ label }, index) in store.documentHeaders" :key="itemText+index" :value="index">{{ label }}</option>
</select>
<button type="button" class="btn btn-primary" @click="changeA" :disabled="this.selectedDocHeaderIndex === null">Confirm Choice</button>
<button type="button" class="btn btn-primary" @click="changeA" :disabled="isConfirmed">Confirm Choice</button>
</div>
</div>
</template>
@ -22,51 +22,52 @@ export default {
type: String,
required: true
},
headerTemplateIndex: Number,
},
data() {
return {
selectedDocHeaderIndex: null,
selectedHeader: "",
confirmedHeader: null,
isConfirmed: false,
store
}
},
methods: {
updateSelectedDocHeader(event) {
// If a correction was previously made, update the parent a correction was unmade
if (this.isConfirmed) { this.$emit('header-change', -1); }
this.isConfirmed = false;
// If the old index is not null, we need to update it's docHeader to be null
if (this.selectedDocHeaderIndex !== null) {
this.store.documentHeaders[this.selectedDocHeaderIndex].swapTemplateHeader(null);
}
// Set the new index of the doc header
this.selectedDocHeaderIndex = event.target.value;
console.log(this.selectedDocHeaderIndex);
changeSelectedHeader(event) {
this.selectedHeader = event.target.value;
},
changeA() {
// Change the templateHeader in the docHeader at selectedDocHeader
console.warn("BEFORE ",store.documentHeaders);
this.confirmedHeader = this.selectedHeader !== "" ? store.documentHeaders.splice(this.selectedHeader,1)[0] : null;
console.info("confirmedHeader ",this.confirmedHeader);
let oldHeader = store.missingHeaders[this.headerTemplateIndex]
.swapUserHeader(this.confirmedHeader);
this.isConfirmed = true;
this.store.documentHeaders[this.selectedDocHeaderIndex].templateHeader = this.itemText;
console.warn("AFTER ",store.documentHeaders);
if (oldHeader) {
store.documentHeaders.push(oldHeader);
store.documentHeaders.sort((a,b) => {
const ha = a.label.toLowerCase();
const hb = b.label.toLowerCase();
if (ha < hb) return -1;
if (ha > hb) return 1;
return 0;
});
}
console.warn("AFTER 2",store.documentHeaders);
document.getElementById('sel').value = this.itemText;
this.$emit('header-change', 1);
}
},
computed: {
filteredHeaders() {
// Get the index of headers that are invalid
return store.documentHeaders.reduce((acc, header, index) => {
if (!header.isSet()) {
acc.push(index);
}
return acc;
}, []);
},
firstValue() {
// When a doc header is confirmed it is removed from the list, we need to set it here
// If no doc header is confirmed, allow the user to select a null
return this.isConfirmed ? this.store.documentHeaders[this.selectedDocHeaderIndex].documentHeader : null
return this.isConfirmed ? store.missingHeaders[this.headerTemplateIndex].userHeader.label : null;
}
}
}
</script>

@ -2,7 +2,7 @@
<div v-if="store.missingHeaders.length > 0" class="missing-headers" :style="isFixed ? {'background-color': '#0a6e11'} : {'background-color': '#990b0b'}" >
<h1>Missing Headers:</h1>
<div class="grid" :style="isFixed ? {'background-color': '#0b3b0e'} : {'background-color': '#800000'}">
<HeaderCorrection @header-change="itemChanged" v-for="header in store.missingHeaders" :key="header" :itemText="header"/>
<HeaderCorrection @header-change="itemChanged" v-for="({header}, index) in store.missingHeaders" :key="header.header" :itemText="header" :header-template-index="index"/>
</div>
<button v-if="this.isFixed" class="submit-button" @click="submitCorrections">Submit Corrections</button>
</div>

@ -2,6 +2,8 @@
* Represents a HeaderTemplate for associating UserHeaders in an uploaded Excel file.
*/
export class HeaderTemplate {
userHeader = null;
/**
* Creates a new HeaderTemplate.
* @param {string} header - The label for this HeaderTemplate.
@ -97,7 +99,7 @@ export class HeaderTemplate {
* Checks if this HeaderTemplate is associated with a UserHeader.
* @returns {boolean} - Returns true if associated, false otherwise.
*/
isAssociated() { typeof this.userHeaders!== 'undefined' && this.userHeaders!== null; }
isAssociated() { return this.userHeader !== null }
swapUserHeader(newUserHeader = null) {
let oldUserHeader = this.userHeader;

@ -38,12 +38,12 @@ export class HeaderAssociator {
this.docHeaderAddress = address
}
set isValidData(newValidData) {
set validAssociatedData(newValidData) {
if (typeof newValidData !== 'boolean') {
console.error(`${this.documentHeader} | HeaderAssociator.validData must be a boolean: ${newValidData}`);
this.isValidData = false;
this.validAssociatedData = false;
}
else this.isValidData = newValidData;
else this.validAssociatedData = newValidData;
}
swapTemplateHeader(newTemplateHeader) {
@ -58,7 +58,7 @@ export class HeaderAssociator {
invalidData(dataSample) {
// If data is found to be invalid, set isValidData to false and record the data
this.docData = dataSample
this.isValidData = false
this.validAssociatedData = false
}
isSet() {

Loading…
Cancel
Save