This commit is contained in:
Jason Snelders 2019-11-12 17:28:56 +11:00
parent ff7eff653c
commit 85bd67acc3
4 changed files with 196 additions and 178 deletions

View File

@ -52,7 +52,98 @@ var app = new Vue({
data:
{
sections: {
status: "laading",
sections: {},
/**
* Details of the current page/route.
*/
activePage: {
id: "",
title: "",
fontAwesomeIconCss: ""
}
},
created()
{
this.sections = this.getDefaultSections();
//-- Register all components
components.registerComponents();
//-- Get the component for the initial route path
var initialRoute = this.$route.path;
var component = components.getComponentByPath(initialRoute);
this.setActivePageByComponent(component);
},
destroyed()
{
},
mounted()
{
this.loadFromStorage();
// Set the "current" main navigation item based on the current route.
helpers.selectMenuItemForCurrentUrl();
// Once the app is fully displayed, hide the overlay.
helpers.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 = "";
},
getDefaultSections: function()
{
return {
basics: {
name: "",
label: "",
@ -134,158 +225,56 @@ var app = new Vue({
name: "",
reference: ""
}]
},
/**
* Details of the current page/route.
*/
activePage: {
id: "",
title: "",
fontAwesomeIconCss: ""
}
};
},
created()
loadFromStorage: function()
{
//-- Register all components
components.registerComponents();
//-- Get the component for the initial route path
var initialRoute = this.$route.path;
var component = components.getComponentByPath(initialRoute);
this.setActivePageByComponent(component);
},
destroyed()
{
},
mounted()
{
// var savedData = helpers.getLocalStorage("sections.basics");
// console.log("savedData=", savedData);
// if (savedData)
// {
// // Data previously saved.
// //this.sections = savedData;
// for (var key in savedData)
// {
// if (savedData.hasOwnProperty(key))
// {
// console.log(key + " > " + savedData[key]);
// this.sections.basics[key] = savedData[key];
// }
// }
// }
//var savedData = helpers.getLocalStorage("sections").sections;
var savedData = helpers.getLocalStorage("sections");
console.log("get saved data[sections]=", savedData);
this.populateSections(savedData);
},
if (savedData)
populateSections: function(data)
{
if (data)
{
// Data previously saved.
//this.sections = savedData;
for (var key in savedData)
for (var key in data)
{
if (savedData.hasOwnProperty(key))
if (data.hasOwnProperty(key))
{
console.log(key + " > ", savedData[key]);
this.sections[key] = savedData[key];
this.sections[key] = data[key];
}
}
}
// Set the "current" main navigation item based on the current route.
helpers.selectMenuItemForCurrentUrl();
// Once the app is fully displayed, hide the overlay.
helpers.hideFullPageOverlay();
},
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.
* Clear save data and reset the sections structure.
*/
clearActivePage: function()
resetResume: function()
{
this.activePage.id = "";
this.activePage.title = "";
this.activePage.fontAwesomeIconCss = "";
var response = confirm("Are you sure you want to clear your saved resume?");
if (response == true)
{
this.sections = this.getDefaultSections();
alert("Your resume has been cleared.");
}
return false;
}
},
// /**
// * When a component is activated (loaded) it will pass data back to this app (ID, title, icons, etc).
// *
// * @param object eventValue
// */
// componentActivated: function(eventValue)
// {
// //alert("Hello was clicked" + "\n" + "Who=" + eventValue.whoWasIt + "\n" + "What=" + eventValue.whatWasIt);
// console.log("componentActivated(): eventValue.component=", eventValue.component);
// }
},
// watch: {
// /**
// * Watch all data for changes
// */
// 'sections.basics': function(val)
// {
// // Save the data to localStorage
// //NOTE: I'm initially not concerned about performance here/
// console.log("watch section", val);
// }
// }
watch: {
@ -311,10 +300,12 @@ var app = new Vue({
$data: {
handler: function(val, oldVal)
{
console.log("val=", val.sections);
// Save the data to localStorage
//NOTE: I'm initially not concerned about performance here.
if (val.status == "loaded")
{
helpers.setLocalStorage("sections", val.sections);
}
},
deep: true
}

View File

@ -139,7 +139,7 @@ var components = {
id: "skills",
path: "#/section/skills",
type: "page",
title: "Publications",
title: "Skills",
description: "",
fontAwesomeIcon: "fas fa-tools"
});

View File

@ -27,6 +27,19 @@ var importComponent = {
methods: {
importJson: function()
{
console.log("import JSON: " + this.json);
var data = JSON.parse(this.json);
this.$root.populateSections(data);
},
validateJson: function(value)
{
}
}
};

View File

@ -10,10 +10,13 @@
<body class="w3-light-grey">
<!-- VueJS App -->
<div id="app">
<!-- Top container -->
<div class="w3-bar w3-top w3-black w3-large" style="z-index:4">
<button class="w3-bar-item w3-button w3-hide-large w3-hover-none w3-hover-text-light-grey" onclick="helpers.w3_open();"><i
class="fa fa-bars"></i> &nbsp;Menu</button>
<button class="w3-bar-item w3-button w3-hide-large w3-hover-none w3-hover-text-light-grey" onclick="helpers.w3_open();"><i class="fa fa-bars"></i> &nbsp;Menu</button>
<span class="w3-bar-item w3-right">JSON Resume Editor</span>
</div>
@ -43,7 +46,7 @@
<a href="#/section/work" class="w3-bar-item w3-button w3-padding"><i class="fas fa-building"></i>&nbsp; Work</a>
<a href="#/section/volunteer" class="w3-bar-item w3-button w3-padding"><i class="fas fa-hands-helping"></i>&nbsp; Volunteer</a>
<a href="#/section/education" class="w3-bar-item w3-button w3-padding"><i class="fas fa-graduation-cap"></i>&nbsp; Education</a>
<a href="#/section/awards" class="w3-bar-item w3-button w3-padding"><i class="fas fa-award""></i>&nbsp; Awards</a>
<a href="#/section/awards" class="w3-bar-item w3-button w3-padding"><i class="fas fa-award"></i>&nbsp; Awards</a>
<a href="#/section/publications" class="w3-bar-item w3-button w3-padding"><i class="fas fa-book"></i>&nbsp; Publications</a>
<a href="#/section/skills" class="w3-bar-item w3-button w3-padding"><i class="fas fa-tools"></i>&nbsp; Skills</a>
<a href="#/section/languages" class="w3-bar-item w3-button w3-padding"><i class="fas fa-heart"></i>&nbsp; Languages</a>
@ -55,6 +58,7 @@
<a href="#/preview" class="w3-bar-item w3-button w3-padding"><i class="fas fa-print"></i>&nbsp; Preview</a>
<a href="#/import" class="w3-bar-item w3-button w3-padding"><i class="fas fa-file-upload"></i>&nbsp; Import</a>
<a href="#/export" class="w3-bar-item w3-button w3-padding"><i class="fas fa-file-download"></i>&nbsp; Export</a>
<span class="w3-bar-item w3-button w3-padding" v-on:click="resetResume"><i class="fas fa-sync-alt"></i>&nbsp; Reset Resume</span>
</div>
<hr>
<div class="w3-bar-block">
@ -71,8 +75,7 @@
<!-- End Page Content -->
<div class="w3-main w3-padding-16">
<!-- VueJS App -->
<div id="app">
<div id="full-page-overlay">
<div id="full-page-overlay-text">Please wait while we load the goodness.</div>
</div>
@ -85,8 +88,7 @@
<div class="w3-container">
<router-view>Loading...</router-view>
</div>
</div>
<!-- /VueJS App -->
@ -101,7 +103,8 @@
<!-- /End Page Content -->
</div>
<!-- /VueJS App -->
<!-- Component Templates -->
<template type="text/x-template" id="home-template" lang="html">
@ -371,7 +374,7 @@
<small id="highlightsHelp" class="form-help text-muted">Short sentences and highlights of the position.</small>
<ol>
<li>
<input id="highlights[0]" class="w3-input w3-border" type="text" v-model="$root.sections.work[0].highlights[0]">
<input id="highlights[0]" class="w3-input w3-border" type="text" v-model="$root.sections.volunteer[0].highlights[0]">
</li>
</ol>
</div>
@ -388,7 +391,11 @@
<preview-field label="Summary" v-bind:value="$root.sections.volunteer[0].summary" format="multi-line"></preview-field>
<h5 class="margin-top-32">Highlights</h5>
<ol>
<li>
<preview-field label="" v-bind:value="$root.sections.volunteer[0].highlights[0]" format="list-item"></preview-field>
</li>
</ol>
</div>
</div>
</div>
@ -504,7 +511,7 @@
<div>
<preview-field label="Title" v-bind:value="$root.sections.awards[0].title"></preview-field>
<preview-field label="Date" v-bind:value="$root.sections.awards[0].date"></preview-field>
<preview-field label="Awarder" v-bind:value="$root.sections.awards[0].awarder" format="url"></preview-field>
<preview-field label="Awarder" v-bind:value="$root.sections.awards[0].awarder"></preview-field>
<preview-field label="Summary" v-bind:value="$root.sections.awards[0].summary" format="multi-line"></preview-field>
</div>
</div>
@ -543,7 +550,7 @@
</p>
<p>
<label for="summary" class="w3-text-blue"><b>Summary</b></label>
<textarea id="summary" rows="8" class="w3-input w3-border" type="text" v-model="$root.sections.work[0].summary"></textarea>
<textarea id="summary" rows="8" class="w3-input w3-border" type="text" v-model="$root.sections.publications[0].summary"></textarea>
<small id="summaryHelp" class="form-help text-muted">Details of the article.</small>
</p>
</div>
@ -556,7 +563,7 @@
<preview-field label="Publisher" v-bind:value="$root.sections.publications[0].publisher"></preview-field>
<preview-field label="Release Date" v-bind:value="$root.sections.publications[0].releaseDate"></preview-field>
<preview-field label="Website" v-bind:value="$root.sections.publications[0].website" format="url"></preview-field>
<preview-field label="Summary" v-bind:value="$root.sections.work[0].summary" format="multi-line"></preview-field>
<preview-field label="Summary" v-bind:value="$root.sections.publications[0].summary" format="multi-line"></preview-field>
</div>
</div>
</div>
@ -584,7 +591,7 @@
</p>
<h5 class="margin-top-32">Keywords</h5>
<small id="keywordsHelp" class="form-help text-muted">Sub-skills.</small>
<small id="keywordsHelp" class="form-help text-muted">Keywords.</small>
<ol>
<li>
<input id="keywords[0]" class="w3-input w3-border" type="text" v-model="$root.sections.skills[0].keywords[0]">
@ -703,7 +710,7 @@
</p>
<p>
<label for="reference" class="w3-text-blue required-field"><b>Reference</b></label>
<input id="reference" class="w3-input w3-border" type="text" v-model="$root.sections.references[0].reference" required>
<textarea id="reference" rows="8" class="w3-input w3-border" type="text" v-model="$root.sections.references[0].reference"></textarea>
<small id="referenceHelp" class="form-help text-muted">The reference given by the person.</small>
</p>
</div>
@ -713,7 +720,7 @@
<div class="preview w3-container w3-card-4 w3-padding-16 w3-margin-left">
<div>
<preview-field label="Name" v-bind:value="$root.sections.references[0].name"></preview-field>
<preview-field label="Reference" v-bind:value="$root.sections.references[0].reference"></preview-field>
<preview-field label="Reference" v-bind:value="$root.sections.references[0].reference" format="multi-line"></preview-field>
</div>
</div>
</div>
@ -859,7 +866,8 @@
<template type="text/x-template" id="preview-single-field-template" lang="html">
<div class="w3-row w3-margin-bottom">
<div id="preview-single-field-root">
<div class="w3-row w3-margin-bottom" v-if="format != 'list-item'">
<div class="w3-col m3">
<span>{{label}}</span>
</div>
@ -867,6 +875,11 @@
<span v-html="getValue()"></span>
</div>
</div>
<span v-if="format == 'list-item'">
<span v-html="getValue()"></span>
</span>
</div>
</template>
@ -874,9 +887,10 @@
<template type="text/x-template" id="import-template" lang="html">
<div id="import-root">
<p>
Past existing resume JSON to continue editing.
Past existing resume JSON and import to continue editing.
</p>
<textarea rows="20" class="w3-input w3-border" type="text" v-model="json"></textarea>
<button class="w3-btn w3-white w3-border w3-border-blue w3-round" v-on:click="importJson">Import</button>
</div>
</template>