CUAEPVXIKWH4OAPP7WHRQ6HOZWKADR2HI724ZQ2RIV4IPW3ZT35AC
export { Storage as default }
export { Storage, LocalStorage }
class Storage {
constructor() {
this.storage = {}
}
get(key) {
try {
return this.storage[key]
} catch (e) {
return null
}
}
set(key, value) {
try {
this.storage[key] = value;
} catch (e) {
return false
}
return true;
}
remove(key) {
try {
delete this.storage[key]
} catch (e) {
return false
}
return true
}
clear() {
this.storage = {}
return true
}
}
class LocalStorage extends Storage {
constructor() {
super()
this.storage = window.localStorage
}
get(key) {
try {
return JSON.parse(this.storage.getItem(key))
} catch (e) {
return null
}
}
set(key, value) {
try {
this.storage.setItem(key, JSON.stringify(value))
} catch (e) {
return false
}
return true
}
remove(key) {
try {
this.storage.removeItem(key)
} catch (e) {
return false
}
return true
}
clear() {
try {
this.storage.clear()
} catch (e) {
return false
}
return true
}
}
export { EttTask as default }
export { EttTask }
import { BubbleHour } from '/modules/BubbleHour.class.js';
class EttTask {
constructor(taskElement, onUpdate) {
let self = this
/* data */
const bubbleHourElements = taskElement.querySelectorAll('[role=bubble-hour]')
const taskTotal = taskElement.querySelector('.ett-task-total')
// var lineStart = {x:0,y:0}
var multiSelectFill = false
this.element = taskElement
this.bubbleHours = []
this.bubbles = []
this.bubbleStartIndex = null
/* actions */
const sumTime = ev => {
let total = 0
bubbleHourElements.forEach(bubbleHour => {
total += parseInt(bubbleHour.getAttribute('data-time'))
})
taskElement.setAttribute('data-time', total)
let hours = (total / 60)
taskTotal.innerHTML = hours.toFixed(2) + ' H'
onUpdate()
}
this.toPersist = () => {
let order = parseInt(self.element.getAttribute('id').replace(/[^0-9]/g,''))
let name = self.element.querySelector('.ett-task-name input').value
let persist = {
order: order,
name: name,
hours: {}
}
self.bubbleHours.forEach(bubbleHour => {
let hour = bubbleHour.element.getAttribute('data-hour')
bubbleHour.bubbles.forEach(bubble => {
let range = parseInt(bubble.element.getAttribute('role').replace(/[^0-9]/g,''))
let index = bubble.element.getAttribute('data-hour-index')*range
let minutes = bubble.element.getAttribute('data-time')
if ( !persist.hours.hasOwnProperty(hour) ) {
persist.hours[hour] = {}
}
persist.hours[hour][index] = minutes
})
})
return persist
}
/* init */
bubbleHourElements.forEach(bubbleHourElement => {
let bubbleHour = new BubbleHour(bubbleHourElement, sumTime, self)
self.bubbleHours.push(bubbleHour)
})
taskElement.ett = this
sumTime()
return this
}
}
export { EttDay as default }
export { EttDay }
import { EttTask } from '/modules/EttTask.class.js';
class EttDay {
constructor(date,storage) {
let self = this
this.data = {
date: date,
startHour: 7,
numHours: 12,
numTasks: 7,
numMajor: 3,
tasks: {}
}
this.render = () => {
/// pull ETT elements out of the DOM
const ettTemplate = document.getElementById('ett-task-template')
const ettDate = document.getElementById('ett-date')
const ettTaskContainer = document.getElementById('ett-tasks')
const taskTemplate = ettTemplate.content.firstElementChild.cloneNode(true)
const hourBreakTemplate = taskTemplate.querySelector('.bubble-hour-break').cloneNode(true)
const hourTemplate = taskTemplate.querySelector('.bubble-hour').cloneNode(true)
const bubbleTemplate = taskTemplate.querySelector('.bubble-15m').cloneNode(true)
const header = taskTemplate.cloneNode(true)
header.setAttribute('role','ett-header')
const ettTotal = header.querySelector('.ett-task-total')
const subHeader = taskTemplate.cloneNode(true)
subHeader.setAttribute('role','ett-subheader')
ettDate.value = self.data.date
// add tasks
for ( let t=0; t<self.data.numTasks; t++ ) {
// new header
if ( t == 0 ) {
// add top header - just a specially formatted task
header.classList.add('task-header')
// header title
let headerInput = header.querySelector('.ett-task-name input')
headerInput.value = 'THE MAJOR TASKS FOR TODAY'
headerInput.setAttribute('readonly','readonly')
// header hours
let hoursContainer = header.querySelector('.ett-task-time')
hoursContainer.innerHTML = ''
for ( let h=0; h<self.data.numHours; h++ ) {
let newHour = hourTemplate.cloneNode(true)
let hour = self.data.startHour+h;
if ( hour > 12 ) {
hour = hour - 12
hour += "PM"
} else if ( hour == 12 ) {
hour += "PM"
} else {
hour += "AM"
// deepcode ignore DuplicateIfBody: <please specify a reason of ignoring this>, deepcode ignore DuplicateIfBody: <please specify a reason of ignoring this>, deepcode ignore DuplicateIfBody: <please specify a reason of ignoring this>
}
newHour.innerHTML = hour
let newBreak = hourBreakTemplate.cloneNode(true)
hoursContainer.appendChild(newBreak)
hoursContainer.appendChild(newHour)
}
let newBreak = hourBreakTemplate.cloneNode(true)
hoursContainer.appendChild(newBreak)
header.setAttribute('id','task-header')
header.setAttribute('data-date',self.data.date)
ettTaskContainer.appendChild(header)
// new sub-header
} else if ( t == (self.data.numMajor) ) {
// add sub header - just a specially formatted task
subHeader.classList.add('task-header')
// header title
let headerInput = subHeader.querySelector('.ett-task-name input')
headerInput.value = 'STUFF THAT "JUST HAPPENED"'
headerInput.setAttribute('readonly','readonly')
// header hours
let hoursContainer = subHeader.querySelector('.ett-task-time')
hoursContainer.innerHTML = ''
for ( let h=0; h<self.data.numHours; h++ ) {
let newHour = hourTemplate.cloneNode(true)
let hour = self.data.startHour+h;
if ( hour > 12 ) {
hour = hour - 12
hour += "PM"
} else if ( hour == 12 ) {
hour += "PM"
} else {
hour += "AM"
// deepcode ignore DuplicateIfBody: <please specify a reason of ignoring this>, deepcode ignore DuplicateIfBody: <please specify a reason of ignoring this>
}
newHour.innerHTML = hour
let newBreak = hourBreakTemplate.cloneNode(true)
hoursContainer.appendChild(newBreak)
hoursContainer.appendChild(newHour)
}
let newBreak = hourBreakTemplate.cloneNode(true)
hoursContainer.appendChild(newBreak)
subHeader.setAttribute('id','task-subheader')
subHeader.setAttribute('data-date',self.data.date)
ettTaskContainer.appendChild(subHeader)
}
// new emergent task
let newTask = taskTemplate.cloneNode(true)
let hourContainer = newTask.querySelector('.ett-task-time')
if ( t in self.data.tasks && self.data.tasks[t].name )
{
let taskName = newTask.querySelector('.ett-task-name input')
if ( taskName ) {
taskName.value = self.data.tasks[t].name
}
}
hourContainer.innerHTML = ''
for ( let hh=0; hh<self.data.numHours; hh++ ) {
let newHour = hourTemplate.cloneNode(true)
let h = self.data.startHour+hh;
let hourId = 'task-'+t+'-hour-'+h
newHour.setAttribute('id',hourId)
newHour.setAttribute('data-hour',h)
newHour.innerHTML = '';
for ( let b=0; b<4; b++ ) {
let m = b*15;
let newBubble = bubbleTemplate.cloneNode(true)
newBubble.setAttribute('id',hourId+'-minute-'+m)
newBubble.setAttribute('data-hour-index',b)
newBubble.setAttribute('data-task-index',(4*hh)+b)
if ( t in self.data.tasks &&
h in self.data.tasks[t].hours &&
m in self.data.tasks[t].hours[h] &&
self.data.tasks[t].hours[h][m] >= 0 )
{
newBubble.setAttribute('data-time',self.data.tasks[t].hours[h][m])
}
newHour.appendChild(newBubble)
}
let newBreak = hourBreakTemplate.cloneNode(true)
hourContainer.appendChild(newBreak)
hourContainer.appendChild(newHour)
}
let newBreak = hourBreakTemplate.cloneNode(true)
hourContainer.appendChild(newBreak)
newTask.setAttribute('id','task-'+t)
let indexElement = newTask.querySelector('.ett-task-index')
if ( t < 10 ) {
indexElement.innerHTML = '0'+t
} else {
indexElement.innerHTML = t
}
newTask.setAttribute('data-date',self.data.date);
if ( t <= self.data.numMajor ) {
newTask.classList.add('ett-major-task')
}
ettTaskContainer.appendChild(newTask);
}
const sumTime = ev => {
let total = 0;
let ettTasks = ettTaskContainer.querySelectorAll('[role=ett-task]')
ettTasks.forEach(ettTask => {
total += parseInt(ettTask.getAttribute('data-time'))
});
let hours = (total/60)
ettTotal.innerHTML = hours.toFixed(2)+' H';
};
let ettTasks = ettTaskContainer.querySelectorAll('[role=ett-task]')
ettTasks.forEach( (ettTaskElement, t) => {
let ettTask = new EttTask(ettTaskElement,sumTime)
});
/// DATE PICKER
const calPopup = document.querySelector('#ett-date');
const datepicker = new Datepicker(calPopup, {
format: 'yyyy-mm-dd'
});
calPopup.addEventListener('focus',ev => {
let dp = ev.target.parentNode.querySelector('.datepicker')
dp.style.marginLeft = '-128px';
dp.style.left = '50%';
})
/// PERSISTENCE
document.addEventListener('persist',ev => {
self.data.tasks = {}
let ettTasks = ettTaskContainer.querySelectorAll('[role=ett-task]')
ettTasks.forEach( (ettTaskElement, t) => {
self.data.tasks[t] = ettTaskElement.ett.toPersist()
});
let date = self.data.date || new Date().toLocaleDateString('en-CA')
storage.set(date,self.data)
console.log('PERSIST')
})
}
return this
}
}
export { BubbleHour as default }
export { BubbleHour }
import { Bubble } from '/modules/Bubble.class.js'
class BubbleHour {
constructor(hourElement, onUpdate, task) {
let self = this
/* data */
this.element = hourElement
this.bubbleElements = hourElement.querySelectorAll('[role=bubble-15m]')
this.bubbles = []
/* actions */
const sumTime = ev => {
let total = 0
// let bubbles = ev.currentTarget.querySelectorAll('> [role=bubble-15m]')
self.bubbleElements.forEach(bubbleElement => {
total += parseInt(bubbleElement.getAttribute('data-time'))
})
hourElement.setAttribute('data-time', total)
onUpdate()
}
/* init */
this.bubbleElements.forEach(bubbleElement => {
let bubble = new Bubble(bubbleElement, sumTime, task, self)
self.bubbles.push(bubble)
task.bubbles.push(bubble)
})
hourElement.ett = this
sumTime()
return this
}
}
export { Bubble3 as default }
export { Bubble3 }
class Bubble3 {
constructor(bubbleElement, onUpdate, task) {
let self = this
/* data */
this.element = bubbleElement
this.bubbles5m = bubbleElement.querySelectorAll('.bubble-5m')
/* actions */
const fillBubble = (time) => {
bubbles5m.forEach(bubble => {
time = parseInt(time)
let minTrigger = parseInt(bubble.getAttribute('data-value')) - 4
if (time > 0 && time >= minTrigger) {
bubble.classList.add('fill')
} else {
bubble.classList.remove('fill')
}
})
}
const sumTime = ev => {
const currentTime = bubbleElement.getAttribute('data-time')
fillBubble(currentTime)
}
const cycleTime = ev => {
let currentTime = parseInt(bubbleElement.getAttribute('data-time'))
if (currentTime >= 15) {
currentTime = 0
} else {
currentTime += 5
}
bubbleElement.setAttribute('data-time', currentTime)
fillBubble(currentTime)
onUpdate()
}
/* init */
bubbleElement.addEventListener('click', cycleTime)
bubbleElement.classList.add('bubble3')
bubbleElement.ett = this
sumTime()
return this
}
}
export { Bubble as default }
export { Bubble }
class Bubble {
constructor(bubbleElement, onUpdate, task, hour) {
let self = this
/* data */
this.element = bubbleElement
/* actions */
this.fillBubble = (time) => {
bubbleElement.setAttribute('data-time', parseInt(time))
if (parseInt(time) > 0) {
bubbleElement.classList.add('fill')
} else {
bubbleElement.classList.remove('fill')
}
onUpdate()
}
const sumTime = ev => {
const currentTime = bubbleElement.getAttribute('data-time')
self.fillBubble(currentTime)
}
const cycleTime = ev => {
var currentTime = parseInt(bubbleElement.getAttribute('data-time'))
if (currentTime > 0) {
currentTime = 0
} else {
currentTime = 15
}
self.fillBubble(currentTime)
// document.dispatchEvent(new Event('persist'))
}
/* init */
const preMultiFill = ev => {
bubbleElement.addEventListener('mouseup', cycleTime)
bubbleElement.addEventListener('mouseout', multiSelectActivate)
document.addEventListener('mouseup', multiSelectCancel)
task.bubbleStartIndex = parseInt(bubbleElement.getAttribute('data-task-index'))
}
const multiSelectActivate = ev => {
bubbleElement.removeEventListener('mouseup', cycleTime)
bubbleElement.removeEventListener('mouseout', multiSelectActivate)
task.multiSelectActive = true
const currentTime = parseInt(bubbleElement.getAttribute('data-time'))
if (currentTime > 0) {
task.multiSelectFill = false
self.fillBubble(0)
document.body.style.cursor = 'not-allowed'
} else {
task.multiSelectFill = true
self.fillBubble(15)
document.body.style.cursor = 'copy'
}
}
const multiSelectCancel = ev => {
task.multiSelectActive = false
bubbleElement.removeEventListener('mouseout', multiSelectActivate)
document.removeEventListener('mouseup', multiSelectCancel)
task.bubbleStartIndex = null
document.body.style.cursor = 'default'
document.dispatchEvent(new Event('persist'))
}
const multiFill = ev => {
if (task.multiSelectActive) {
if (task.multiSelectFill) {
self.fillBubble(15)
} else {
self.fillBubble(0)
}
let bubbleIndex = parseInt(bubbleElement.getAttribute('data-task-index'))
let bubbleStartIndex = parseInt(task.bubbleStartIndex)
if (bubbleStartIndex !== null && bubbleStartIndex !== bubbleIndex) {
let startIndex = Math.min(bubbleIndex,task.bubbleStartIndex);
let endIndex = Math.max(bubbleIndex,task.bubbleStartIndex);
for (let i = startIndex; i <= endIndex; i++) {
let betweenBubble = task.element.querySelector('[data-task-index="' + i + '"]')
if ( betweenBubble ) {
if (task.multiSelectFill) {
betweenBubble.ett.fillBubble(15)
} else {
betweenBubble.ett.fillBubble(0)
}
}
}
}
}
}
bubbleElement.addEventListener('mousedown', preMultiFill)
bubbleElement.addEventListener('mouseenter', multiFill)
bubbleElement.ett = this
sumTime()
return this
}
}