profile-studio/app/app.js

546 lines
12 KiB
JavaScript

//------------------------------------------------------------------------------------------
/*
* The root application.
*/
//------------------------------------------------------------------------------------------
/**
* Define all the routes in the application/
*/
var router = new VueRouter({
routes: [
{ path: '/', component: homeComponent },
{ path: '/section/basics', component: sectionBasicsComponent },
{ path: '/section/work', component: sectionWorkComponent },
{ path: '/section/volunteer', component: sectionVolunteerComponent },
{ path: '/section/education', component: sectionEducationComponent },
{ path: '/section/awards', component: sectionAwardsComponent },
{ path: '/section/publications', component: sectionPublicationsComponent },
{ path: '/section/skills', component: sectionSkillsComponent },
{ path: '/section/languages', component: sectionLanguagesComponent },
{ path: '/section/interests', component: sectionInterestsComponent },
{ path: '/section/references', component: sectionReferencesComponent },
{ path: '/section/projects', component: sectionProjectsComponent },
{ path: '/preview', component: previewResumeComponent },
{ path: '/import', component: importComponent },
{ path: '/export', component: exportComponent },
{ path: '/about', component: aboutComponent }
]
});
var app = new Vue({
el: '#app',
router: router,
components:
{
},
data:
{
status: "laading",
sections: {},
/**
* Details of the current page/route.
*/
activePage: {
id: "",
title: "",
fontAwesomeIconCss: ""
},
countryCodes: []
},
created()
{
this.sections = models.newDefaultSections();
console.log("this.sections=", this.sections);
//-- Register all components
pageComponents.registerComponents();
//-- Get the component for the initial route path
var initialRoute = this.$route.path;
var component = pageComponents.getComponentByPath(initialRoute);
this.setActivePageByComponent(component);
},
destroyed()
{
},
mounted()
{
this.loadCountryCodes();
this.loadFromStorage();
// Set the "current" main navigation item based on the current route.
this.selectMenuItemForCurrentUrl();
this.$nextTick(function () {
// Code that will run only after the entire view has been rendered.
// Once the app is fully rendered, hide the overlay.
this.hideFullPageOverlay();
});
this.status = "loaded"; // Now we can start watching for changes in 'sections' data.
},
methods: {
/**
* Set details of the currently selected "page" (route) from a registered component.
*
* @param object component Object containing the details of a registered component.
*/
setActivePageByComponent: function(component)
{
this.activePage.id = component.id;
this.activePage.title = component.title;
this.activePage.fontAwesomeIconCss = component.fontAwesomeIcon;
},
/**
* Reset and clear the details of the active page.
*/
clearActivePage: function()
{
this.activePage.id = "";
this.activePage.title = "";
this.activePage.fontAwesomeIconCss = "";
},
loadFromStorage: function()
{
var savedData = storage.getLocalStorage("sections");
this.populateSections(savedData);
},
populateSections: function(data)
{
if (data)
{
// Data previously saved.
for (var key in data)
{
if (data.hasOwnProperty(key))
{
this.sections[key] = data[key];
}
}
}
},
loadCountryCodes: function()
{
console.log("loadCountryCodes(): data", countryCodes);
this.countryCodes.push({
"code": "",
"name": "--Select a country--"
});
for (var property in countryCodes)
{
this.countryCodes.push({
"code": property,
"name": countryCodes[property]
});
}
},
displayLocation: function()
{
/*
<preview-field label="Address" v-bind:value="$root.sections.basics.location.address"></preview-field>
<preview-field label="Postal/Zip Code" v-bind:value="$root.sections.basics.location.postalCode"></preview-field>
<preview-field label="City" v-bind:value="$root.sections.basics.location.city"></preview-field>
<preview-field label="Country Code" v-bind:value="$root.sections.basics.location.countryCode"></preview-field>
<preview-field label="Region" v-bind:value="$root.sections.basics.location.region"></preview-field>
*/
return this.sections.basics.location.city + ", " + this.sections.basics.location.countryCode;
},
skillLevelAsPercent: function(index)
{
var level = this.$root.sections.skills[index].level;
if (level.toLowerCase() == "master" || level.toLowerCase() == "expert")
{
return 100;
}
else if (level.toLowerCase() == "proficient")
{
return 75;
}
else if (level.toLowerCase() == "basic" || level.toLowerCase() == "beginner")
{
return 25;
}
else
{
return 50;
}
},
languageFluencyAsPercent: function(index)
{
var fluency = this.$root.sections.skills[index].level;
if (fluency.toLowerCase() == "master" || fluency.toLowerCase() == "expert")
{
return 100;
}
else if (fluency.toLowerCase() == "proficient")
{
return 75;
}
else if (fluency.toLowerCase() == "basic" || fluency.toLowerCase() == "beginner")
{
return 25;
}
else
{
return 50;
}
},
workEndDate: function(index)
{
var endDate = this.$root.sections.work[index].endDate;
if (endDate == "") return "Current";
return endDate;
},
projectEndDate: function(index)
{
var endDate = this.$root.sections.projects[index].endDate;
if (endDate == "") return "Current";
return endDate;
},
dateMonthYear: function(dateString)
{
var dt = new Date(dateString);
return dt.getFullYear() + ", " + this.getMonthName(dt.getMonth() + 1);
},
getMonthName: function(monthNumber)
{
if (monthNumber == 1) return "January";
if (monthNumber == 2) return "February";
if (monthNumber == 3) return "March";
if (monthNumber == 4) return "April";
if (monthNumber == 5) return "May";
if (monthNumber == 6) return "June";
if (monthNumber == 7) return "July";
if (monthNumber == 8) return "August";
if (monthNumber == 9) return "September";
if (monthNumber == 10) return "October";
if (monthNumber == 11) return "November";
if (monthNumber == 12) return "December";
return "";
},
/**
* Clear save data and reset the sections structure.
*/
resetResume: function()
{
var response = confirm("Are you sure you want to clear your saved resume?");
if (response == true)
{
this.sections = models.newDefaultSections();
alert("Your resume has been cleared.");
}
return false;
},
saveResume: function()
{
var response = confirm("Resume saved");
storage.setLocalStorage("sections", this.$root.sections);
alert("Resume saved");
return false;
},
/**
* Open the sidebar on smaller screens.
*/
w3_open: function()
{
var mySidebar = document.getElementById("mySidebar");
var overlayBg = document.getElementById("myOverlay");
console.log("mySidebar=", mySidebar);
if (mySidebar.style.display === 'block')
{
mySidebar.style.display = 'none';
overlayBg.style.display = "none";
}
else
{
mySidebar.style.display = 'block';
overlayBg.style.display = "block";
}
},
/**
* Open the sidebar on smaller screens.
*/
w3_close: function()
{
var mySidebar = document.getElementById("mySidebar");
var overlayBg = document.getElementById("myOverlay");
mySidebar.style.display = "none";
overlayBg.style.display = "none";
},
/**
* Show the full-page loading overlay.
*/
showFullPageOverlay: function()
{
document.getElementById("full-page-overlay").style.display = "block";
},
/**
* Hide the full-page loading overlay.
*/
hideFullPageOverlay: function()
{
document.getElementById("full-page-overlay").style.display = "none";
},
/**
* Find and mark the main navigation item for the selected "current" page/route
*/
selectMenuItemForCurrentUrl: function()
{
// Get domain root URL of the current page.
var domainUrl = window.location.origin;
// Get components of the URL for the current page.
var pageBasePathName = window.location.pathname;
var pageHash = window.location.hash;
var pagePathName = window.location.pathname;
var pageBaseUrl = domainUrl + pageBasePathName + pageHash;
// Get all main navigation links
var elements = document.querySelectorAll(".w3-bar-item");
for (let i = 0; i < elements.length; i++)
{
var element = elements[i];
//console.log("element[" + i + "]=", element);
// Get HREF from the element
var linkHref = element.getAttribute("href");
// Build a full URL the element's href (hash) so we can compare to the current URL.
var linkFullHref = domainUrl + pagePathName + linkHref;
// Remove the "current page" indicator from the element.
element.classList.remove("w3-blue");
// Ensure trailing slashes are added for comparison equivalence
var urlLast = linkFullHref[linkFullHref.length - 1];
if (urlLast != "/")
{
linkFullHref = linkFullHref + "/";
}
urlLast = pageBaseUrl[pageBaseUrl.length - 1];
if (urlLast != "/")
{
pageBaseUrl = pageBaseUrl + "/";
}
// Check if element is for the current page.
if (linkFullHref == pageBaseUrl)
{
// Add the "current page" indicator to the element.
element.classList.add("w3-blue");
}
}
},
/**
* Collapse or un-collapse a content element by setting its collapse state to opposite of current state.
* @param {string} id ID of the content element to collapse/un-collapse.
*/
invertCollapse: function(id)
{
var x = document.getElementById(id);
if (x.className.indexOf("w3-show") == -1)
{
x.className += " w3-show";
}
else
{
x.className = x.className.replace(" w3-show", "");
}
},
/**
* Move the position of an element in an array.
*
* @param array arr The array to move an element in.
* @param int old_index Current position of the element.
* @param int new_index New position of the element.
*
* @return array Updated array.
*/
moveArrayPosition: function(arr, old_index, new_index)
{
if (new_index == old_index)
{
// No change
return ;
}
if (new_index > old_index)
{
// Moving forward in array
if (old_index == this.$root.sections.work.length - 1) return; // Cannot move beyond the end of the array
}
if (new_index < old_index)
{
// Moving back in array
if (old_index == 0) return; // Cannot move beyond the start of the array
}
if (new_index >= arr.length)
{
var k = new_index - arr.length + 1;
while (k--)
{
arr.push(undefined);
}
}
arr.splice(new_index, 0, arr.splice(old_index, 1)[0]);
return arr; // for testing
}
},
watch: {
/**
* Detect when a route changes.
*
* @param object to Details of the previous route (navigating away from).
* @param object from Details of the new active route (navigating to).
*/
$route: function (to, from)
{
// Set the "current" main navigation item based on the current route.
this.selectMenuItemForCurrentUrl();
// Set the current page details based on the component mapped to the active route.
var component = pageComponents.getComponentByPath(to.fullPath);
this.setActivePageByComponent(component);
},
//TODO: Disbled
// $data: {
// handler: function(val, oldVal)
// {
// // Save the data to localStorage
// //NOTE: I'm initially not concerned about performance here.
// if (val.status == "loaded")
// {
// storage.setLocalStorage("sections", val.sections);
// }
// },
// deep: true
// }
}
});