🏠 Home 

Work Search Record CSV Upload

Adds a CSV Upload Button


Install this script?
// ==UserScript==
// @name         Work Search Record CSV Upload
// @namespace    https://brightentompkins.com
// @version      0.1
// @description  Adds a CSV Upload Button
// @author       vantaboard <[email protected]>
// @match        https://uio.edd.ca.gov/UIO/Pages/ExternalUser/Certification/FormCCA4581RegularDUAWorkSearchRecord.aspx
// @icon         https://www.google.com/s2/favicons?sz=64&domain=ca.gov
// @license      MIT
// @grant        none
// ==/UserScript==
function CSVToArray(strData, strDelimiter = ',') {
const objPattern = new RegExp(
`(\\${strDelimiter}|\\r?\\n|\\r|^)(?:"([^"]*(?:""[^"]*)*)"|([^"\\${strDelimiter}\\r\\n]*))`,
'gi'
);
const arrData = [[]];
let arrMatches = null;
while ((arrMatches = objPattern.exec(strData))) {
const strMatchedDelimiter = arrMatches[1];
if (
strMatchedDelimiter.length &&
strMatchedDelimiter !== strDelimiter
) {
arrData.push([]);
}
let strMatchedValue;
if (arrMatches[2]) {
strMatchedValue = arrMatches[2].replace(new RegExp('""', 'g'), '"');
} else {
strMatchedValue = arrMatches[3];
}
arrData[arrData.length - 1].push(strMatchedValue);
}
arrData.pop();
return arrData;
}
function getLabel(input) {
let element = input;
while (element) {
if (element.tagName === 'LABEL') {
return element.innerText;
}
if (element.querySelector('label')) {
return [...element.querySelectorAll('label')].slice(-1)[0]
.innerText;
}
element = element.parentElement;
}
}
function fill(input, value) {
console.log(`Setting ${getLabel(input).trim()} to ${value}`);
input.value = value;
input.dispatchEvent(new Event('change'));
}
function flatArray(...args) {
const arr = [];
args.forEach((arg) => {
if (!arg) {
return;
}
Array.isArray(arg) ? arr.push(...arg) : arr.push(arg);
});
return arr;
}
function wrapInputId(
token,
suffix,
prefix = [
'contentMain',
'contentMain',
'ucRegularDUA4581WorkSearchRecordV2',
'frmFormWorkSearchInformation',
],
postToken = 'ctl00',
delimiter = '_'
) {
return `#${flatArray(prefix, token, postToken, suffix).join(delimiter)}`;
}
const inputs = [
{
regex: new RegExp(/date.+contact/i),
formatter: (value) =>
new Intl.DateTimeFormat('en-US', {
year: 'numeric',
month: '2-digit',
day: '2-digit',
}).format(new Date(value)),
suffix: 'txtDatePicker',
token: 'prtDateOfContact',
},
{
regex: new RegExp(/type.+work|work.+type/i),
suffix: 'txtValue',
token: 'prtTypeOfWork',
},
{
regex: new RegExp(/employer.+agency|agency.+employer/i),
suffix: 'txtValue',
token: 'prtEmployerAgencyName',
},
{
regex: new RegExp(/contact.+type|type.+contact/i),
formatter: (value) =>
({
Mail: 6656,
Fax: 6657,
Email: 6658,
'In-Person': 6659,
Online: 6660,
Phone: 6661,
}[String(value).trim()]),
suffix: 'ddlValue',
token: 'prtContactType',
},
{
regex: new RegExp(/outcome.+contact|contact.+outcome/i),
formatter: (value) =>
({
Applied: 6662,
'No Decision': 6663,
Hired: 6664,
'Not Hiring': 6665,
Pending: 6666,
Interviewed: 6667,
'Interview Date Set': 6668,
'No response from employer': 6669,
}[String(value).trim()]),
suffix: 'ddlValue',
token: 'prtOutcomeWorkInquiry',
},
{
regex: new RegExp(/person.+contacted|contacted.+person/i),
suffix: 'txtValue',
token: 'prtWorkSearchPersonContacted',
},
{
regex: new RegExp(/email|website|url/i),
suffix: 'txtValue',
token: 'prtWebSiteURLEmailContact',
},
{
regex: new RegExp(/phone|fax/i),
suffix: 'txtValue',
token: 'prtPhoneFaxNumber',
},
{
regex: new RegExp(/address.+1|1.+address/i),
suffix: 'txtValue',
token: 'prtAddress1',
},
{
regex: new RegExp(/address.+2|2.+address/i),
suffix: 'txtValue',
token: 'prtAddress2',
},
{
regex: new RegExp(/city/i),
suffix: 'txtValue',
token: 'prtCity',
},
{
regex: new RegExp(/state|province/i),
suffix: 'txtValue',
token: 'prtOtherState',
},
{
regex: new RegExp(/postal|zip/i),
suffix: 'txtValue',
token: 'prtPostalCode',
},
{
regex: new RegExp(/country/i),
formatter: (value) =>
({
Afghanistan: 329,
Akrotiri: 377,
Albania: 405,
Algeria: 406,
Andorra: 407,
Angola: 450,
Anguilla: 378,
Antarctica: 341,
'Antigua and Barbuda': 283,
Argentina: 360,
Armenia: 408,
Aruba: 478,
'Ashmore and Cartier Islands': 268,
Australia: 361,
Austria: 409,
Azerbaijan: 342,
'Bahamas, The': 319,
Bahrain: 410,
Bangladesh: 343,
Barbados: 379,
'Bassas da India': 297,
Belarus: 411,
Belgium: 412,
Belize: 451,
Benin: 479,
Bermuda: 413,
Bhutan: 452,
Bolivia: 414,
'Bosnia and Herzegovina': 275,
Botswana: 380,
'Bouvet Island': 311,
Brazil: 453,
'British Indian Ocean Territory': 267,
'British Virgin Islands': 276,
Brunei: 454,
Bulgaria: 381,
'Burkina Faso': 320,
Burma: 480,
Burundi: 415,
Cambodia: 382,
Cameroon: 383,
Canada: 448,
'Cape Verde': 344,
'Cayman Islands': 303,
'Central African Republic': 270,
Chad: 505,
Chile: 481,
China: 482,
'Christmas Island': 291,
'Clipperton Island': 287,
'Cocos (Keeling) Islands': 273,
Colombia: 384,
Comoros: 416,
'Congo, Democratic Republic of the': 262,
'Congo, Republic of the': 277,
'Cook Islands': 321,
'Coral Sea Islands': 288,
'Costa Rica': 345,
// eslint-disable-next-line quotes
"Cote d'Ivoire": 312,
Croatia: 417,
Cuba: 506,
Cyprus: 455,
'Czech Republic': 304,
Denmark: 418,
Dhekelia: 385,
Djibouti: 386,
Dominica: 387,
'Dominican Republic': 286,
Ecuador: 419,
Egypt: 483,
'El Salvador': 330,
'Equatorial Guinea': 289,
Eritrea: 420,
Estonia: 421,
Ethiopia: 388,
'Europa Island': 313,
'Falkland Islands (Islas Malvinas)': 263,
'Faroe Islands': 314,
Fiji: 507,
Finland: 422,
France: 456,
'French Guiana': 315,
'French Polynesia': 292,
'French Southern and Antarctic Lands': 261,
Gabon: 484,
'Gambia, The': 331,
'Gaza Strip': 346,
Georgia: 423,
Germany: 424,
Ghana: 485,
Gibraltar: 362,
'Glorioso Islands': 293,
Greece: 457,
Greenland: 363,
Grenada: 425,
Guadeloupe: 347,
Guam: 508,
Guatemala: 364,
Guernsey: 389,
Guinea: 458,
'Guinea-Bissau': 316,
Guyana: 459,
Haiti: 486,
'Heard Island and McDonald Islands': 264,
'Holy See (Vatican City)': 274,
Honduras: 390,
'Hong Kong': 365,
Hungary: 426,
Iceland: 427,
India: 487,
Indonesia: 366,
Iran: 509,
Iraq: 510,
Ireland: 428,
'Isle of Man': 332,
Israel: 460,
Italy: 488,
Jamaica: 429,
'Jan Mayen': 367,
Japan: 489,
Jersey: 461,
Jordan: 462,
'Juan de Nova Island': 284,
Kazakhstan: 348,
Kenya: 490,
Kiribati: 391,
'Korea, North': 322,
'Korea, South': 323,
Kuwait: 463,
Kyrgyzstan: 349,
Laos: 511,
Latvia: 464,
Lebanon: 430,
Lesotho: 431,
Liberia: 432,
Libya: 491,
Liechtenstein: 317,
Lithuania: 368,
Luxembourg: 350,
Macau: 492,
Macedonia: 369,
Madagascar: 351,
Malawi: 465,
Malaysia: 392,
Maldives: 393,
Mali: 512,
Malta: 493,
'Marshall Islands': 294,
Martinique: 352,
Mauritania: 353,
Mauritius: 370,
Mayotte: 433,
Mexico: 449,
'Micronesia, Federated States of': 266,
Moldova: 434,
Monaco: 466,
Mongolia: 394,
Montserrat: 354,
Morocco: 435,
Mozambique: 355,
Namibia: 436,
Nauru: 494,
'Navassa Island': 305,
Nepal: 495,
Netherlands: 333,
'Netherlands Antilles': 281,
'New Caledonia': 318,
'New Zealand': 334,
Nicaragua: 371,
Niger: 496,
Nigeria: 437,
Niue: 513,
'Norfolk Island': 306,
'Northern Mariana Islands': 271,
Norway: 467,
Oman: 514,
Pakistan: 395,
Palau: 497,
Panama: 468,
'Papua New Guinea': 295,
'Paracel Islands': 298,
Paraguay: 396,
Peru: 515,
Philippines: 335,
'Pitcairn Islands': 296,
Poland: 469,
Portugal: 397,
'Puerto Rico': 336,
Qatar: 498,
Reunion: 438,
Romania: 439,
Russia: 470,
Rwanda: 471,
'S Georgia and S Sandwich Islands': 260,
'Saint Helena': 324,
'Saint Kitts and Nevis': 278,
'Saint Lucia': 337,
'Saint Pierre and Miquelon': 269,
'Saint Vincent and the Grenadines': 265,
Samoa: 499,
'San Marino': 356,
'Sao Tome and Principe': 279,
'Saudi Arabia': 325,
Senegal: 440,
'Serbia and Montenegro': 280,
Seychelles: 357,
'Sierra Leone': 326,
Singapore: 372,
Slovakia: 398,
Slovenia: 399,
'Solomon Islands': 299,
Somalia: 441,
'South Africa': 327,
Spain: 500,
'Spratly Islands': 300,
'Sri Lanka': 373,
Sudan: 501,
Suriname: 400,
Svalbard: 401,
Swaziland: 374,
Sweden: 472,
Switzerland: 338,
Syria: 502,
Taiwan: 473,
Tajikistan: 358,
Tanzania: 402,
Thailand: 403,
'Timor-Leste': 339,
Togo: 516,
Tokelau: 442,
Tonga: 503,
'Trinidad and Tobago': 285,
'Tromelin Island': 301,
Tunisia: 443,
Turkey: 474,
Turkmenistan: 328,
'Turks and Caicos Islands': 272,
Tuvalu: 475,
Uganda: 476,
Ukraine: 444,
'United Arab Emirates': 282,
'United Kingdom': 307,
'United States': 310,
Uruguay: 445,
Uzbekistan: 359,
Vanuatu: 446,
Venezuela: 375,
Vietnam: 447,
'Virgin Islands': 308,
'Wake Island': 340,
'Wallis and Futuna': 290,
'West Bank': 376,
'Western Sahara': 309,
Yemen: 504,
Zambia: 477,
Zimbabwe: 404,
}[String(value).trim()]),
suffix: 'ddlValue',
token: 'prtCountry',
},
];
function inputByHeaders(headersArray) {
const headers = headersArray.map((header) => {
const input = inputs.find(({regex}) => regex.test(header));
if (!input) {
return null;
}
return input;
}, []);
return headers;
}
const wrapWeekId = (token) =>
wrapInputId(
token,
'',
[
'contentMain',
'contentMain',
'ucFormCCA4581RegularDUACertificationWeeks',
],
''
);
function load(data) {
const {headers, rows} = data;
headers.forEach((header) => {
if (!header) {
return;
}
const {token, suffix} = header;
const element = document.querySelector(wrapInputId(token, suffix));
if (!element) {
throw new Error(`Could not find element for ${token}`);
}
header.element = element;
});
const row = rows[0];
headers.forEach((header, index) => {
if (!header) {
return;
}
const {element, formatter} = header;
try {
const value = formatter ? formatter(row[index]) : row[index];
fill(element, value);
} catch (error) {
if (error instanceof Error && error.name === 'RangeError') {
console.warn(
`Error filling ${getLabel(element)
.toString()
.trim()} with ${row[index]}`
);
}
throw error;
}
});
const additionalButton = document.querySelector(
wrapInputId('prtISAdditionalWorkSerach', ['rblValue', '0'])
);
const nextButton = document.querySelector(
wrapInputId('btnNext', '', ['contentMain', 'contentMain'], '')
);
additionalButton.click();
nextButton.click();
}
const weekNumber = document.querySelector(wrapWeekId('lblWeekNumber'));
const weekEnd = document.querySelector(wrapWeekId('lblWeekEndDate'));
const weekHeader = weekEnd.parentElement;
weekHeader.style.display = 'flex';
weekHeader.style.alignItems = 'center';
weekNumber.style.padding = '0 0.5rem';
const csvUploadInput = document.createElement('input');
csvUploadInput.style.display = 'none';
const csvUploadIcon = document.createElement('span');
csvUploadIcon.classList.add('ca-gov-icon-file-csv');
const csvUploadText = document.createElement('span');
csvUploadText.innerText = 'Upload CSV';
csvUploadText.style.fontSize = '1rem';
csvUploadText.style.userSelect = 'none';
csvUploadInput.type = 'file';
csvUploadInput.accept = '.csv';
csvUploadInput.addEventListener('change', (event) => {
const file = event.target.files[0];
const reader = new FileReader();
reader.onload = (event) => {
const csv = event.target.result;
const csvArray = CSVToArray(csv);
const [headers, ...rows] = csvArray;
if (!rows.length) {
return;
}
const inputHeaders = inputByHeaders(headers);
window.localStorage.setItem('csvArray', JSON.stringify(csvArray));
const data = {
headers: inputHeaders,
rows,
};
load(data);
};
reader.readAsText(file);
});
const csvUploadLabel = document.createElement('label');
csvUploadLabel.classList.add('nav-item');
csvUploadLabel.style.marginLeft = '5px';
csvUploadLabel.style.display = 'flex';
csvUploadLabel.style.alignItems = 'center';
csvUploadLabel.appendChild(csvUploadInput);
csvUploadLabel.appendChild(csvUploadIcon);
csvUploadLabel.appendChild(csvUploadText);
weekHeader.appendChild(csvUploadLabel);
const csvArray = JSON.parse(window.localStorage.getItem('csvArray'));
if (csvArray) {
const [headers, ...rows] = csvArray;
rows.shift();
if (!rows.length) {
window.localStorage.removeItem('csvArray');
}
if (rows.length) {
window.localStorage.setItem(
'csvArray',
JSON.stringify([headers, ...rows])
);
const inputHeaders = inputByHeaders(headers);
const data = {
headers: inputHeaders,
rows,
};
load(data);
}
}