Some structure changes; added naviagation; added helpers
This commit is contained in:
3
.gitignore
vendored
3
.gitignore
vendored
@@ -86,7 +86,6 @@ out
|
|||||||
|
|
||||||
# Nuxt.js build / generate output
|
# Nuxt.js build / generate output
|
||||||
.nuxt
|
.nuxt
|
||||||
dist
|
|
||||||
|
|
||||||
# Gatsby files
|
# Gatsby files
|
||||||
.cache/
|
.cache/
|
||||||
@@ -204,7 +203,6 @@ out
|
|||||||
|
|
||||||
# Nuxt.js build / generate output
|
# Nuxt.js build / generate output
|
||||||
.nuxt
|
.nuxt
|
||||||
dist
|
|
||||||
|
|
||||||
# Gatsby files
|
# Gatsby files
|
||||||
.cache/
|
.cache/
|
||||||
@@ -237,3 +235,4 @@ dist
|
|||||||
.yarn/install-state.gz
|
.yarn/install-state.gz
|
||||||
.pnp.*
|
.pnp.*
|
||||||
|
|
||||||
|
/.trash/
|
||||||
|
|||||||
12
package.json
12
package.json
@@ -9,21 +9,29 @@
|
|||||||
"srv": "cross-env SOURCE_MAP_ENV=true webpack serve",
|
"srv": "cross-env SOURCE_MAP_ENV=true webpack serve",
|
||||||
"watch": "webpack --watch",
|
"watch": "webpack --watch",
|
||||||
"build": "cross-env NODE_ENV=production webpack",
|
"build": "cross-env NODE_ENV=production webpack",
|
||||||
"build-dev": "cross-env SOURCE_MAP_ENV=true webpack"
|
"build-dev": "cross-env SOURCE_MAP_ENV=true NODE_ENV=production webpack"
|
||||||
},
|
},
|
||||||
"keywords": [],
|
"keywords": [],
|
||||||
"author": "",
|
"author": "",
|
||||||
"license": "ISC",
|
"license": "ISC",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@babel/core": "^7.15.5",
|
"@babel/core": "^7.15.5",
|
||||||
|
"@babel/plugin-proposal-class-properties": "^7.14.5",
|
||||||
"@babel/preset-env": "^7.15.6",
|
"@babel/preset-env": "^7.15.6",
|
||||||
"babel-loader": "^8.2.2",
|
"babel-loader": "^8.2.2",
|
||||||
"clean-webpack-plugin": "^4.0.0",
|
"clean-webpack-plugin": "^4.0.0",
|
||||||
"cross-env": "^7.0.3",
|
"cross-env": "^7.0.3",
|
||||||
"css-loader": "^6.3.0",
|
"css-loader": "^6.3.0",
|
||||||
|
"css-minimizer-webpack-plugin": "^3.1.1",
|
||||||
|
"css-mqpacker-webpack-plugin": "^0.12.1",
|
||||||
|
"glob": "^7.2.0",
|
||||||
"html-webpack-plugin": "^5.3.2",
|
"html-webpack-plugin": "^5.3.2",
|
||||||
"mini-css-extract-plugin": "^2.3.0",
|
"mini-css-extract-plugin": "^2.3.0",
|
||||||
"terser-webpack-plugin": "^5.2.4",
|
"mini-svg-data-uri": "^1.3.3",
|
||||||
|
"postcss-loader": "^6.1.1",
|
||||||
|
"postcss-preset-env": "^6.7.0",
|
||||||
|
"purgecss-webpack-plugin": "^4.0.3",
|
||||||
|
"style-loader": "^3.3.0",
|
||||||
"webpack": "^5.56.1",
|
"webpack": "^5.56.1",
|
||||||
"webpack-cli": "^4.8.0",
|
"webpack-cli": "^4.8.0",
|
||||||
"webpack-dev-server": "^4.3.1"
|
"webpack-dev-server": "^4.3.1"
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
],
|
],
|
||||||
"querySelectors": {
|
"querySelectors": {
|
||||||
"console": "#appConsole",
|
"console": "#appConsole",
|
||||||
|
"navTabs": "#asSwitcher",
|
||||||
"modal": ".modal",
|
"modal": ".modal",
|
||||||
"notesGrid": "#notesGrid",
|
"notesGrid": "#notesGrid",
|
||||||
"noteEditForm": "#noteEditForm",
|
"noteEditForm": "#noteEditForm",
|
||||||
@@ -22,8 +23,8 @@
|
|||||||
},
|
},
|
||||||
"gridOrder": {
|
"gridOrder": {
|
||||||
"notes": [
|
"notes": [
|
||||||
"title",
|
|
||||||
"createdAt",
|
"createdAt",
|
||||||
|
"title",
|
||||||
"category",
|
"category",
|
||||||
"content",
|
"content",
|
||||||
"dates",
|
"dates",
|
||||||
|
|||||||
80
src/helpers.js
Normal file
80
src/helpers.js
Normal file
@@ -0,0 +1,80 @@
|
|||||||
|
export const env = require('./env.json')
|
||||||
|
export const msgBox = document.getElementById(env.querySelectors.console.slice(1))
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @type {{}}
|
||||||
|
*/
|
||||||
|
const monthsNamesFull = env.lists.monthsFull
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param string
|
||||||
|
* @returns {string}
|
||||||
|
*/
|
||||||
|
export const ucWords = string => {
|
||||||
|
return string.split('_').map(word => word.charAt(0).toUpperCase() + word.substr(1).toLowerCase()).join(' ')
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param date
|
||||||
|
* @returns {string}
|
||||||
|
*/
|
||||||
|
export const formatDate = date => {
|
||||||
|
const dt = new Date(date)
|
||||||
|
return [monthsNamesFull[dt.getMonth()], dt.getDate(), `, ${dt.getFullYear()}`].join(' ')
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param str
|
||||||
|
* @returns {*[]}
|
||||||
|
*/
|
||||||
|
export const findDates = str => {
|
||||||
|
const dates = []
|
||||||
|
const regex = new RegExp('[0-3]?[0-9].[0-3]?[0-9].(?:[0-9]{2})?[0-9]{2}', 'mg')
|
||||||
|
|
||||||
|
for (const match of (str || '').matchAll(regex)) {
|
||||||
|
dates.push(match[0])
|
||||||
|
}
|
||||||
|
|
||||||
|
return dates
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param args
|
||||||
|
* @returns {*}
|
||||||
|
*/
|
||||||
|
export const createNode = (...args) => {
|
||||||
|
const [tag, attrs, content, callback] = args
|
||||||
|
const node = document.createElement(tag)
|
||||||
|
|
||||||
|
for (const [key, value] of Object.entries(attrs || [])) {
|
||||||
|
node.setAttribute(key, value)
|
||||||
|
}
|
||||||
|
|
||||||
|
node.innerHTML = content || ''
|
||||||
|
|
||||||
|
return node
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param node
|
||||||
|
*/
|
||||||
|
export const destroyNode = (node) => {
|
||||||
|
|
||||||
|
if (!(node instanceof Node) && typeof node === 'string') {
|
||||||
|
node = document.querySelector(node)
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
node.remove()
|
||||||
|
} catch (e) {}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -8,6 +8,5 @@
|
|||||||
<body>
|
<body>
|
||||||
<div id="appConsole" class="uk-container"></div>
|
<div id="appConsole" class="uk-container"></div>
|
||||||
<div id="app" class="uk-container"></div>
|
<div id="app" class="uk-container"></div>
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
40
src/index.js
40
src/index.js
@@ -1,42 +1,13 @@
|
|||||||
import env from './env.json'
|
import { env } from './helpers'
|
||||||
import './styles/uikit.min.css'
|
import './styles/uikit.min.css'
|
||||||
import './styles/main.css'
|
import './styles/main.css'
|
||||||
import DOMController from './modules/DOMController'
|
import DOMController from './modules/DOMController'
|
||||||
|
|
||||||
//localStorage.clear()
|
|
||||||
|
|
||||||
window.env = env
|
|
||||||
const monthsNamesFull = window.env.lists.monthsFull
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @param str
|
|
||||||
* @returns {*[]}
|
|
||||||
* @private
|
|
||||||
*/
|
|
||||||
window.___findDates = str => {
|
|
||||||
const dates = []
|
|
||||||
const regex = new RegExp('[0-3]?[0-9].[0-3]?[0-9].(?:[0-9]{2})?[0-9]{2}', 'mg')
|
|
||||||
|
|
||||||
for (const match of (str || '').matchAll(regex)) {
|
|
||||||
dates.push(match[0])
|
|
||||||
}
|
|
||||||
|
|
||||||
return dates
|
|
||||||
}
|
|
||||||
|
|
||||||
window.___formatDate = date => {
|
|
||||||
const dt = new Date(date)
|
|
||||||
return [monthsNamesFull[dt.getMonth()], dt.getDate(), `, ${dt.getFullYear()}`].join(' ')
|
|
||||||
}
|
|
||||||
|
|
||||||
const app = document.getElementById('app')
|
const app = document.getElementById('app')
|
||||||
|
|
||||||
const view = new DOMController(app)
|
window.env = env
|
||||||
|
|
||||||
//console.log(dt, dt.match(/^(((2000|2400|2800|((19|2[0-9])(0[48]|[2468][048]|[13579][26])))-02-29)|(((19|2[0-9])[0-9]{2})-02-(0[1-9]|1[0-9]|2[0-8]))|(((19|2[0-9])[0-9]{2})-(0[13578]|10|12)-(0[1-9]|[12][0-9]|3[01]))|(((19|2[0-9])[0-9]{2})-(0[469]|11)-(0[1-9]|[12][0-9]|30)))T([01][0-9]|[2][0-3]):[0-5][0-9]:[0-5][0-9]\.[0-9]{3}Z$/) )
|
new DOMController(app)
|
||||||
|
|
||||||
//localStorage.clear()
|
|
||||||
|
|
||||||
/*NotesAPI.saveNote({
|
/*NotesAPI.saveNote({
|
||||||
//id: 441512,
|
//id: 441512,
|
||||||
@@ -47,4 +18,7 @@ const view = new DOMController(app)
|
|||||||
})*/
|
})*/
|
||||||
|
|
||||||
//NotesAPI.deleteNote(441512)
|
//NotesAPI.deleteNote(441512)
|
||||||
//console.log(NotesAPI.getNotes())
|
//console.log(NotesAPI.getNotes())
|
||||||
|
|
||||||
|
/*
|
||||||
|
1/1/11 or 1.1.11 or 1-1-11 01/01/11 or 01.01.11 or 01-01-11 01/01/2011 or 01.01.2011 or 01-01-2011 : true 01/1/2011 or 01.1.2011 or 01-1-2011 : true 1/11/2011 or 1.11.2011 or 1-11-2011 1/11/11 or 1.11.11 or 1-11-11 11/1/11 or 11.1.11 or 11-1-11*/
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import Templates from '../templates/Views'
|
import Templates from '../templates/Views'
|
||||||
|
import { msgBox, createNode, destroyNode, findDates, formatDate, ucWords } from '../helpers'
|
||||||
import NotesAPI from './NotesAPI'
|
import NotesAPI from './NotesAPI'
|
||||||
|
|
||||||
export default class DOMController {
|
export default class DOMController {
|
||||||
@@ -13,15 +14,29 @@ export default class DOMController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
this.btnCreateNote = this.root.querySelector(window.env.querySelectors.btnCreateNote)
|
this.btnCreateNote = this.root.querySelector(window.env.querySelectors.btnCreateNote)
|
||||||
|
|
||||||
this.createNotesGrid(window.env.prePopulateAmount || 0)
|
this.createNotesGrid(window.env.prePopulateAmount || 0)
|
||||||
|
|
||||||
this.listener([
|
this.listener([
|
||||||
[
|
[this.btnCreateNote, 'click', (this.btnCreateNote.dataset.action || 'showError'), { legend: 'Create Note' }],
|
||||||
this.btnCreateNote, 'click', (this.btnCreateNote.dataset.action || 'showError'), {
|
|
||||||
legend: 'Create Note',
|
|
||||||
}],
|
|
||||||
])
|
])
|
||||||
|
|
||||||
|
this.navTabs()
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
navTabs () {
|
||||||
|
const navTabs = document.querySelectorAll(window.env.querySelectors.navTabs + ' > li > a')
|
||||||
|
|
||||||
|
for (let i = 0; i < navTabs.length; ++i) {
|
||||||
|
this.listener([navTabs[i], 'click', 'createNotesGridByRoute', navTabs[i]])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
showError () {
|
||||||
|
DOMController.alert('Error occurred :(', 3000, 3)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -29,28 +44,68 @@ export default class DOMController {
|
|||||||
* @param msg
|
* @param msg
|
||||||
* @param fadeOut
|
* @param fadeOut
|
||||||
* @param type
|
* @param type
|
||||||
|
* @param womb
|
||||||
*/
|
*/
|
||||||
static alert (msg = '', fadeOut = 0, type = 0) {
|
static alert (msg = 'Alert without message', fadeOut = 0, type = 0, womb = null) {
|
||||||
const alertTypes = window.env.alertTypes
|
const alertTypes = window.env.alertTypes
|
||||||
const alert = this.createNode('div', { class: `uk-alert-${alertTypes[type]}`, 'uk-alert': null },
|
const alert = createNode('div', { class: `uk-alert-${alertTypes[type]} uk-padding-small`, 'uk-alert': null }, msg)
|
||||||
`<a class="uk-alert-close" uk-close></a>\n` + msg)
|
|
||||||
alert.style.display = 'block'
|
alert.style.display = 'block'
|
||||||
document.getElementById(window.env.querySelectors.console.slice(1)).appendChild(alert)
|
womb instanceof Element ? womb.appendChild(alert) : msgBox.appendChild(alert)
|
||||||
|
|
||||||
|
if (fadeOut > 0) {
|
||||||
|
setTimeout(() => {
|
||||||
|
alert.remove()
|
||||||
|
}, fadeOut)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
createNotesGrid (len, archived = false) {
|
/**
|
||||||
|
*
|
||||||
|
* @param node
|
||||||
|
*/
|
||||||
|
noteToTrash (node) {
|
||||||
|
const row = node.closest('tr')
|
||||||
|
NotesAPI.deleteNote(parseInt(row.dataset.id, 10))
|
||||||
|
row.classList.add('as-removing')
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
row.remove()
|
||||||
|
this.createNotesGrid(window.env.prePopulateAmount || 0)
|
||||||
|
}, 3000)
|
||||||
|
}
|
||||||
|
|
||||||
|
createNotesGridByRoute (navTab) {
|
||||||
|
const route = new URL( navTab.href ).pathname.slice(1).split('\/')[0]
|
||||||
|
document.querySelector('li.nav-tab.uk-active').classList.remove('uk-active')
|
||||||
|
navTab.closest('li').classList.add( 'uk-active' )
|
||||||
|
|
||||||
|
switch ( route ){
|
||||||
|
case 'all': this.createNotesGrid( 0, null ); break;
|
||||||
|
case '': this.createNotesGrid( window.env.prePopulateAmount || 0 ); break;
|
||||||
|
case 'archived': this.createNotesGrid( window.env.prePopulateAmount || 0, true ); break;
|
||||||
|
default: console.log(route)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param len
|
||||||
|
* @param archived
|
||||||
|
*/
|
||||||
|
createNotesGrid (len = window.env.prePopulateAmount || 0, archived = false) {
|
||||||
|
|
||||||
const notes = NotesAPI.getNotesSanitized(len, archived)
|
const notes = NotesAPI.getNotesSanitized(len, archived)
|
||||||
|
|
||||||
if (notes.length === 0) { return }
|
if (notes.length === 0) { return }
|
||||||
|
|
||||||
const nodeToListen = []
|
|
||||||
|
|
||||||
const notesGrid = document.querySelector(window.env.querySelectors.notesGrid + ' tbody')
|
const notesGrid = document.querySelector(window.env.querySelectors.notesGrid + ' tbody')
|
||||||
notesGrid.innerHTML = ''
|
notesGrid.innerHTML = ''
|
||||||
|
|
||||||
notes.forEach(el => {
|
notes.forEach(el => {
|
||||||
|
|
||||||
const row = DOMController.createNode('tr')
|
const row = createNode('tr')
|
||||||
row.dataset.id = el.id
|
row.dataset.id = el.id
|
||||||
|
|
||||||
window.env.gridOrder.notes.forEach(key => {
|
window.env.gridOrder.notes.forEach(key => {
|
||||||
@@ -59,14 +114,24 @@ export default class DOMController {
|
|||||||
|
|
||||||
switch (key) {
|
switch (key) {
|
||||||
case 'createdAt':
|
case 'createdAt':
|
||||||
value = ___formatDate(value)
|
value = formatDate(value)
|
||||||
|
break
|
||||||
|
case 'category':
|
||||||
|
value = ucWords( value )
|
||||||
|
break
|
||||||
|
case 'title':
|
||||||
|
//attrs.class = 'uk-text-truncate'
|
||||||
|
attrs.class = 'uk-text-bold'
|
||||||
break
|
break
|
||||||
case 'content':
|
case 'content':
|
||||||
attrs.class = 'uk-text-truncate'
|
|
||||||
|
//attrs.class = 'uk-text-truncate'
|
||||||
|
//attrs.title = value
|
||||||
break
|
break
|
||||||
case 'dates':
|
case 'dates':
|
||||||
attrs.class = 'uk-text-truncate'
|
value = findDates(el.content).join(', ')
|
||||||
value = ___findDates(el.content).join(', ')
|
//attrs.class = 'uk-text-truncate'
|
||||||
|
//attrs.title = value
|
||||||
break
|
break
|
||||||
case 'edit' :
|
case 'edit' :
|
||||||
attrs.class = 'icon icon-edit grid-control'
|
attrs.class = 'icon icon-edit grid-control'
|
||||||
@@ -78,15 +143,14 @@ export default class DOMController {
|
|||||||
break
|
break
|
||||||
case 'delete' :
|
case 'delete' :
|
||||||
attrs.class = 'icon icon-delete grid-control'
|
attrs.class = 'icon icon-delete grid-control'
|
||||||
attrs['data-action'] = 'toTrash'
|
attrs['data-action'] = 'noteToTrash'
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
const td = DOMController.createNode('td', attrs, value)
|
const td = createNode('td', attrs, value)
|
||||||
|
|
||||||
if (key.match(/^(edit|archive|delete)$/)) {
|
if (key.match(/^(edit|archive|delete)$/)) {
|
||||||
nodeToListen.push(td)
|
this.listener([td, 'click', td.dataset.action, td])
|
||||||
this.listener([td, 'click', td.dataset.action])
|
|
||||||
}
|
}
|
||||||
|
|
||||||
row.appendChild(td)
|
row.appendChild(td)
|
||||||
@@ -96,89 +160,6 @@ export default class DOMController {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
showError () {
|
|
||||||
console.error('Error occurred :(')
|
|
||||||
}
|
|
||||||
|
|
||||||
static createNode (...args) {
|
|
||||||
const [tag, attrs, content, callback] = args
|
|
||||||
const node = document.createElement(tag)
|
|
||||||
|
|
||||||
for (const [key, value] of Object.entries(attrs || [])) {
|
|
||||||
node.setAttribute(key, value)
|
|
||||||
}
|
|
||||||
|
|
||||||
node.innerHTML = content || ''
|
|
||||||
|
|
||||||
return node
|
|
||||||
}
|
|
||||||
|
|
||||||
destroyNode (selector) {
|
|
||||||
|
|
||||||
if (!(selector instanceof Node) && typeof selector === 'string') {
|
|
||||||
selector = document.querySelector(selector)
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
selector.remove()
|
|
||||||
} catch (e) {}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
getEditForm (args = {}) {
|
|
||||||
|
|
||||||
const node = DOMController.createNode('div', { class: window.env.querySelectors.modal.slice(1) },
|
|
||||||
Templates.templates.editForm)
|
|
||||||
|
|
||||||
if (args.legend) {
|
|
||||||
node.querySelector('legend').innerHTML = args.legend
|
|
||||||
}
|
|
||||||
|
|
||||||
this.root.appendChild(node)
|
|
||||||
node.style.display = 'block'
|
|
||||||
|
|
||||||
this.listener([
|
|
||||||
[node.querySelector(window.env.querySelectors.btnDestroyModal), 'click', 'destroyNode', node],
|
|
||||||
[node.querySelector('form'), 'submit', NotesAPI.saveNote],
|
|
||||||
])
|
|
||||||
}
|
|
||||||
|
|
||||||
listener (els) {
|
|
||||||
els[0] instanceof Element ? this.on(els) : els.forEach(el => this.on(el))
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
*
|
|
||||||
* @param args //selector, event, method, params
|
|
||||||
*/
|
|
||||||
on (args) {
|
|
||||||
|
|
||||||
const [selector, event, method] = args
|
|
||||||
|
|
||||||
if (!(selector instanceof Element)) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
try {
|
|
||||||
selector.addEventListener(event, evt => {
|
|
||||||
const params = args[3] || {}
|
|
||||||
|
|
||||||
if (evt.type === 'submit') {
|
|
||||||
evt.preventDefault()
|
|
||||||
}
|
|
||||||
|
|
||||||
if (typeof this[method] === 'function') {
|
|
||||||
this[method](params)
|
|
||||||
} else if (typeof method === 'function') {
|
|
||||||
method(params)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
} catch (err) {
|
|
||||||
console.error(err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @param selector
|
* @param selector
|
||||||
@@ -194,4 +175,69 @@ export default class DOMController {
|
|||||||
|
|
||||||
return data
|
return data
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param els
|
||||||
|
* @returns {void|*}
|
||||||
|
*/
|
||||||
|
listener (els) { return els[0] instanceof Element ? this.on(els) : els.forEach(el => this.on(el)) }
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param args //selector, event, method, params
|
||||||
|
*/
|
||||||
|
on (args) {
|
||||||
|
|
||||||
|
const [selector, event, method] = args
|
||||||
|
|
||||||
|
if (!(selector instanceof Element)) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
selector.addEventListener(event, evt => {
|
||||||
|
const params = args[3] || {}
|
||||||
|
|
||||||
|
if (selector.tagName === 'A') {
|
||||||
|
evt.preventDefault()
|
||||||
|
}
|
||||||
|
|
||||||
|
if (evt.type === 'submit') {
|
||||||
|
evt.preventDefault()
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
this.createNotesGrid(window.env.prePopulateAmount || 0)
|
||||||
|
}, 300)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof this[method] === 'function') {
|
||||||
|
this[method](params)
|
||||||
|
} else if (typeof method === 'function') {
|
||||||
|
method(params)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
} catch (err) {
|
||||||
|
console.error(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
getEditForm (args = {}) {
|
||||||
|
|
||||||
|
const node = createNode('div', { class: window.env.querySelectors.modal.slice(1) },
|
||||||
|
Templates.templates.editForm)
|
||||||
|
|
||||||
|
if (args.legend) {
|
||||||
|
node.querySelector('legend').innerHTML = args.legend
|
||||||
|
}
|
||||||
|
|
||||||
|
this.root.appendChild(node)
|
||||||
|
node.style.display = 'block'
|
||||||
|
|
||||||
|
this.listener([
|
||||||
|
[node.querySelector(window.env.querySelectors.btnDestroyModal), 'click', destroyNode, node], //Remove modal dialog
|
||||||
|
[node.querySelector('form'), 'submit', NotesAPI.saveNote],
|
||||||
|
])
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -11,12 +11,14 @@ export default class NotesAPI{
|
|||||||
* @returns {*}
|
* @returns {*}
|
||||||
*/
|
*/
|
||||||
static getNotes (n, archive = false, key = (window.env.localStorageKey || '') ) {
|
static getNotes (n, archive = false, key = (window.env.localStorageKey || '') ) {
|
||||||
|
|
||||||
let notes = JSON.parse(localStorage.getItem(key) || '[]')
|
let notes = JSON.parse(localStorage.getItem(key) || '[]')
|
||||||
|
|
||||||
if( archive === false ){
|
if( typeof archive === 'boolean' ){
|
||||||
notes = notes.filter( el => el.archive !== 'on' )
|
notes = notes.filter( el => ( archive ? el.archive === 'on' : el.archive !== 'on' ) )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
notes.sort((a, b) => {
|
notes.sort((a, b) => {
|
||||||
return new Date(a.createdAt) > new Date(b.createdAt) ? -1 : 1
|
return new Date(a.createdAt) > new Date(b.createdAt) ? -1 : 1
|
||||||
})
|
})
|
||||||
@@ -32,6 +34,7 @@ export default class NotesAPI{
|
|||||||
*/
|
*/
|
||||||
static getNotesSanitized( n = 0, archive = false){
|
static getNotesSanitized( n = 0, archive = false){
|
||||||
let notes = NotesAPI.getNotes(0, archive)
|
let notes = NotesAPI.getNotes(0, archive)
|
||||||
|
|
||||||
notes = Validation.allAgainstSchema(notes, window.env.schemas.note )
|
notes = Validation.allAgainstSchema(notes, window.env.schemas.note )
|
||||||
return n > 0 ? notes.slice(0, n) : notes
|
return n > 0 ? notes.slice(0, n) : notes
|
||||||
}
|
}
|
||||||
@@ -68,11 +71,13 @@ export default class NotesAPI{
|
|||||||
notes.push(noteToStore)
|
notes.push(noteToStore)
|
||||||
}
|
}
|
||||||
NotesAPI.saveNotesToStorage(notes)
|
NotesAPI.saveNotesToStorage(notes)
|
||||||
|
|
||||||
|
document.querySelector( window.env.querySelectors.noteEditForm ).closest('.modal').remove()
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
DOMController.alert( 'Could save the note! ' + isValid.errors.join(', '),0, 2 )
|
DOMController.alert( 'Could save the note! ' + isValid.errors.join(', '),6666, 2 ) //, document.getElementById('modalMsgBox')
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log(NotesAPI.getNotes())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -1,5 +1,26 @@
|
|||||||
body{
|
body{
|
||||||
background-color: aliceblue;
|
background-color: ghostwhite;
|
||||||
|
margin-top: 100px;
|
||||||
|
}
|
||||||
|
|
||||||
|
tbody td{
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#as-navbar{
|
||||||
|
overflow: hidden; position: fixed; left: 0; top: 0; width: 100%
|
||||||
|
}
|
||||||
|
|
||||||
|
.uk-text-truncate{
|
||||||
|
cursor: text;
|
||||||
|
}
|
||||||
|
|
||||||
|
#appConsole{
|
||||||
|
display: flex;
|
||||||
|
z-index: 2;
|
||||||
|
position: fixed;
|
||||||
|
bottom: 2rem;
|
||||||
|
right: 2rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.icon{
|
.icon{
|
||||||
@@ -12,12 +33,26 @@ body{
|
|||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
transition: transform 250ms;
|
transition: transform 250ms;
|
||||||
}
|
}
|
||||||
|
|
||||||
.icon.grid-control:hover{
|
.icon.grid-control:hover{
|
||||||
filter: brightness(0.1) sepia(1) hue-rotate(90deg) saturate(1);
|
filter: brightness(0.1) sepia(1) hue-rotate(90deg) saturate(1);
|
||||||
transform: translateY(5%);
|
transform: translateY(5%);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@keyframes fadeInAnimation {
|
||||||
|
0% {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
100% {
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.as-removing{
|
||||||
|
animation: fadeInAnimation ease 3s;
|
||||||
|
animation-iteration-count: 1;
|
||||||
|
animation-fill-mode: forwards;
|
||||||
|
}
|
||||||
|
|
||||||
.icon.as-transition:hover{
|
.icon.as-transition:hover{
|
||||||
transition: ease-in-out 100ms;
|
transition: ease-in-out 100ms;
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
import grid from './grid'
|
import grid from './grid'
|
||||||
import editForm from './editForm'
|
import editForm from './editForm'
|
||||||
import gridRow from './gridRow'
|
//import gridRow from '../../.trash/gridRow'
|
||||||
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
templates: {
|
templates: {
|
||||||
editForm: editForm,
|
editForm: editForm,
|
||||||
gridRow: gridRow
|
// gridRow: gridRow
|
||||||
},
|
},
|
||||||
grid: grid
|
grid: grid
|
||||||
}
|
}
|
||||||
@@ -1,6 +1,7 @@
|
|||||||
export default `<form id="noteEditForm" class="uk-form-horizontal uk-margin-large modal-content" style="background: ghostwhite">
|
export default `<form id="noteEditForm" class="uk-form-horizontal uk-margin-large modal-content" style="background: ghostwhite">
|
||||||
<fieldset class="uk-fieldset">
|
<fieldset class="uk-fieldset">
|
||||||
<legend class="uk-legend">Edit Note</legend>
|
<legend class="uk-legend">Edit Note</legend>
|
||||||
|
<div id="modalMsgBox"></div>
|
||||||
|
|
||||||
<div class="uk-margin">
|
<div class="uk-margin">
|
||||||
<label class="uk-form-label" for="formTitle">Title</label>
|
<label class="uk-form-label" for="formTitle">Title</label>
|
||||||
@@ -9,7 +10,7 @@ export default `<form id="noteEditForm" class="uk-form-horizontal uk-margin-larg
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="uk-margin" style="background: aquamarine">
|
<div class="uk-margin">
|
||||||
<label class="uk-form-label uk-float-right" for="formCategory">Category</label>
|
<label class="uk-form-label uk-float-right" for="formCategory">Category</label>
|
||||||
<div class="uk-form-controls">
|
<div class="uk-form-controls">
|
||||||
<select id="formCategory" name="category" class="uk-select">
|
<select id="formCategory" name="category" class="uk-select">
|
||||||
|
|||||||
@@ -1,8 +1,31 @@
|
|||||||
export default `<table id="notesGrid" class="uk-table uk-table-small uk-table-responsive1 uk-table-striped uk-table-hover uk-table-divider">
|
export default `
|
||||||
|
<div id="as-navbar" class="uk-background-secondary">
|
||||||
|
<div class="uk-container">
|
||||||
|
<div class="uk-float-right uk-margin-top uk-margin-right">
|
||||||
|
<button id="btnCreateNote" class="uk-button uk-button-primary" data-action="getEditForm">Create Note</button>
|
||||||
|
</div>
|
||||||
|
<ul id="asSwitcher" class="uk-subnav uk-subnav-pill uk-margin-small-top uk-margin-small-bottom uk-padding-small">
|
||||||
|
<li class="nav-tab"><a href="/all">All Notes</a></li>
|
||||||
|
<li class="nav-tab uk-active"><a href="/">Recent Notes</a></li>
|
||||||
|
<li class="nav-tab"><a href="/archived">Archived Notes</a></li>
|
||||||
|
<li class="nav-tab"><a href="/analytics">Analytics</a></li>
|
||||||
|
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<table id="notesGrid" class="uk-table uk-table-small uk-table-responsive1 uk-table-striped uk-table-hover uk-table-divider">
|
||||||
|
<col width="150">
|
||||||
|
<col width="250">
|
||||||
|
<col width="150">
|
||||||
|
<col>
|
||||||
|
<col width="180">
|
||||||
|
<col width="32">
|
||||||
|
<col width="32">
|
||||||
|
<col width="32">
|
||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th>Title</th>
|
|
||||||
<th>Created</th>
|
<th>Created</th>
|
||||||
|
<th>Title</th>
|
||||||
<th>Category</th>
|
<th>Category</th>
|
||||||
<th>Content</th>
|
<th>Content</th>
|
||||||
<th>Dates</th>
|
<th>Dates</th>
|
||||||
@@ -13,9 +36,9 @@ export default `<table id="notesGrid" class="uk-table uk-table-small uk-table-re
|
|||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
</tbody>
|
</tbody>
|
||||||
<tr>
|
<!--<tr>
|
||||||
<td colspan="8" class="uk-margin uk-text-right">
|
<td colspan="8" class="uk-margin uk-text-right">
|
||||||
<button id="btnCreateNote" class="uk-button uk-button-primary" data-action="getEditForm">Create Note</button>
|
<button id="btnCreateNote" class="uk-button uk-button-primary" data-action="getEditForm">Create Note</button>
|
||||||
</td>
|
</td>
|
||||||
</tr>
|
</tr>-->
|
||||||
</table>`
|
</table>`
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
export default `
|
|
||||||
<td></td>
|
|
||||||
<td></td>
|
|
||||||
<td></td>
|
|
||||||
<td></td>
|
|
||||||
<td></td>
|
|
||||||
<td class="uk-text-right">
|
|
||||||
<div class="uk-button-group">
|
|
||||||
<button class="uk-button uk-button-default icon icon-archive"></button>
|
|
||||||
<button class="uk-button uk-button-default"></button>
|
|
||||||
</div>
|
|
||||||
</td>
|
|
||||||
`
|
|
||||||
@@ -1,56 +1,103 @@
|
|||||||
|
const os = require('os')
|
||||||
const path = require('path')
|
const path = require('path')
|
||||||
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
|
const glob = require('glob')
|
||||||
const HtmlWebpackPlugin = require('html-webpack-plugin')
|
|
||||||
const {CleanWebpackPlugin} = require('clean-webpack-plugin')
|
|
||||||
const TerserPlugin = require("terser-webpack-plugin")
|
|
||||||
|
|
||||||
let mode = 'development', target = 'web'
|
const { CleanWebpackPlugin } = require('clean-webpack-plugin')
|
||||||
|
const HtmlWebpackPlugin = require('html-webpack-plugin')
|
||||||
|
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
|
||||||
|
const PurgeCSSPlugin = require('purgecss-webpack-plugin')
|
||||||
|
const svgToMiniDataURI = require('mini-svg-data-uri')
|
||||||
|
const CssMinimizerPlugin = require('css-minimizer-webpack-plugin')
|
||||||
|
const CSSMQPackerPlugin = require('css-mqpacker-webpack-plugin')
|
||||||
|
|
||||||
|
let mode = 'development', target = 'web', isProd = false
|
||||||
|
const babelExclude = /(node_modules|bower_components)/
|
||||||
|
|
||||||
if (process.env.NODE_ENV === 'production') {
|
if (process.env.NODE_ENV === 'production') {
|
||||||
mode = 'development'
|
mode = 'development'
|
||||||
target = 'browserslist'
|
target = 'browserslist'
|
||||||
|
isProd = true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const isDev = process.env.NODE_ENV !== 'production'
|
||||||
|
|
||||||
const plugins = [
|
const plugins = [
|
||||||
new CleanWebpackPlugin(),
|
new CleanWebpackPlugin(),
|
||||||
new MiniCssExtractPlugin(),
|
new MiniCssExtractPlugin(),
|
||||||
|
new PurgeCSSPlugin({
|
||||||
|
paths: glob.sync(`${path.join(__dirname, 'src')}/**/*`, { nodir: true }),
|
||||||
|
//only: ['bundle', 'vendor']
|
||||||
|
}),
|
||||||
new HtmlWebpackPlugin({
|
new HtmlWebpackPlugin({
|
||||||
template: './src/index.html',
|
template: './src/index.html',
|
||||||
inject: 'body'
|
inject: 'body',
|
||||||
}),
|
}),
|
||||||
]
|
]
|
||||||
|
|
||||||
console.log( process.env.SOURCE_MAP_ENV )
|
const stylesLoaders = loader => {
|
||||||
|
const loaders = [
|
||||||
|
isDev ? 'style-loader' : MiniCssExtractPlugin.loader,
|
||||||
|
'css-loader',
|
||||||
|
{
|
||||||
|
loader: 'postcss-loader',
|
||||||
|
options: {
|
||||||
|
postcssOptions: {
|
||||||
|
ident: 'postcss',
|
||||||
|
plugins: [
|
||||||
|
require('postcss-preset-env'),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
]
|
||||||
|
|
||||||
|
if (loader) {
|
||||||
|
loaders.push(loader)
|
||||||
|
}
|
||||||
|
|
||||||
|
return loaders
|
||||||
|
}
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
mode: mode,
|
mode: mode,
|
||||||
target: target,
|
target: target,
|
||||||
module: {
|
module: {
|
||||||
rules: [
|
rules: [
|
||||||
{
|
|
||||||
test: /\.(jpe?g|png|gif|svg)$/i,
|
|
||||||
type: "asset",
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
test: /\.css$/i,
|
test: /\.css$/i,
|
||||||
use: [
|
use: stylesLoaders(),
|
||||||
{
|
|
||||||
loader: MiniCssExtractPlugin.loader,
|
|
||||||
// This is required for asset imports in CSS, such as url()
|
|
||||||
options: { publicPath: '' },
|
|
||||||
},
|
|
||||||
'css-loader',
|
|
||||||
///"postcss-loader",
|
|
||||||
// according to the docs, sass-loader should be at the bottom, which
|
|
||||||
// loads it first to avoid prefixes in your sourcemaps and other issues.
|
|
||||||
//"sass-loader",
|
|
||||||
],
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
test: /\.js$/,
|
test: /\.s[ac]ss$/i,
|
||||||
exclude: /node_modules/,
|
use: stylesLoaders('sass-loader'),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
test: /\.m?js$/i,
|
||||||
|
exclude: babelExclude,
|
||||||
use: {
|
use: {
|
||||||
loader: 'babel-loader',
|
loader: 'babel-loader',
|
||||||
|
options: {
|
||||||
|
presets: [
|
||||||
|
'@babel/preset-env',
|
||||||
|
],
|
||||||
|
plugins: [
|
||||||
|
'@babel/plugin-proposal-class-properties',
|
||||||
|
],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
test: /\.(jpe?g|webp|png|gif|svg)$/i,
|
||||||
|
type: 'asset/resource',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
test: /\.(svg)$/i,
|
||||||
|
type: 'asset/inline',
|
||||||
|
generator: {
|
||||||
|
dataUrl: content => {
|
||||||
|
content = content.toString()
|
||||||
|
return svgToMiniDataURI(content)
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
@@ -61,20 +108,29 @@ module.exports = {
|
|||||||
filename: '[name].[hash].js',
|
filename: '[name].[hash].js',
|
||||||
},
|
},
|
||||||
plugins: plugins,
|
plugins: plugins,
|
||||||
devtool: mode === 'production' ? 'source-map' : ( process.env.SOURCE_MAP_ENV ? 'source-map' : false ),
|
devtool: mode === 'production' ? 'source-map' : (process.env.SOURCE_MAP_ENV ? 'eval-cheap-module-source-map' : false),
|
||||||
optimization: {
|
optimization: {
|
||||||
minimize: true,
|
minimize: isProd,
|
||||||
|
splitChunks: {
|
||||||
|
chunks: 'all',
|
||||||
|
},
|
||||||
minimizer: [
|
minimizer: [
|
||||||
new TerserPlugin({
|
`...`,
|
||||||
extractComments: true,
|
new CssMinimizerPlugin({
|
||||||
terserOptions: {
|
parallel: os.cpus().length,
|
||||||
ecma: 5,
|
minimizerOptions: {
|
||||||
compress: {
|
preset: [
|
||||||
drop_console: mode === 'production',
|
'default', // for advanced need to run `npm i -D cssnano-preset-advanced`
|
||||||
},
|
{
|
||||||
|
discardComments: { removeAll: true },
|
||||||
|
},
|
||||||
|
],
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
|
new CSSMQPackerPlugin({
|
||||||
|
test: /\.css$/i,
|
||||||
|
sort: true,
|
||||||
|
}),
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
devServer: {
|
devServer: {
|
||||||
@@ -82,10 +138,5 @@ module.exports = {
|
|||||||
compress: true,
|
compress: true,
|
||||||
port: 1976,
|
port: 1976,
|
||||||
liveReload: true,
|
liveReload: true,
|
||||||
/*overlay: {
|
|
||||||
warnings: true,
|
|
||||||
errors: true,
|
|
||||||
}*/
|
|
||||||
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user