Remove click counter and save

Add option to automatically save history
Create edit dialog
Reset to inital value
This commit is contained in:
CheddarCrisp 2020-02-16 09:02:59 -05:00
parent 956b524a8b
commit 76557c7428
4 changed files with 86 additions and 79 deletions

View file

@ -8,9 +8,9 @@
<div class="dialog">
<div class="dialog-content">
<label>Name: <input type="text" bind:value={newCounter.title} use:focus/></label>
<label>Initial Value: <input type="number" bind:value={newCounter.value} /></label>
<label>Initial Value: <input type="number" bind:value={newCounter.initialValue} /></label>
<label>Target: <input type="number" bind:value={newCounter.max} /></label>
<label>Click counter: <input type="checkbox" bind:value={newCounter.isClickCounter} /></label>
<label>Save history: <input type="checkbox" bind:checked={newCounter.saveHistory} /></label>
<button on:click={ () => { showAddDialog = false; } }>Cancel</button>
<button class="ok" on:click={ add }>OK</button>
</div>
@ -28,15 +28,11 @@ function focus(node){
node.focus();
}
function save(counter){
alert('Save ' + counter.title);
}
function showAdd(){
newCounter = {
title: '',
value: 0,
isClickCounter: false,
initialValue: 0,
saveHistory: false,
history: []
}
@ -44,7 +40,12 @@ function showAdd(){
}
function add(){
counters.add(newCounter);
const counter = {
...newCounter,
value: newCounter.initialValue
}
counters.add(counter);
showAddDialog = false;
}
@ -67,16 +68,6 @@ function add(){
color: white;
}
.dialog-content > label {
display: flex;
width: 100%;
margin-bottom: 5px;
}
.dialog-content > label > input {
margin-left: auto;
}
.ok {
margin-left: auto;
}

View file

@ -1,20 +1,17 @@
<div class="counter" on:click="{ clickCount }">
<div class="counter">
<header>{ counter.title }</header>
<span class="value">{ counter.value }</span>
{#if counter.max}
<MyProgress value={ counter.value } max={ counter.max }></MyProgress>
{/if}
<div class="controls">
{#if !counter.isClickCounter}
<button on:click={ () => { showIncrement = true; } }><i class="material-icons">add</i></button>
<button on:click={ () => { showSet = true; } }><i class="material-icons">create</i></button>
{/if}
<span class="message">{ message }</span>
<button on:click={ () => { showSet = true; } }><i class="material-icons">edit</i></button>
<button class="reset" on:click={ reset }><i class="material-icons">undo</i></button>
<button on:click={ save }><i class="material-icons">save</i></button>
<button on:click={ startEdit }><i class="material-icons">edit</i></button>
<button on:click={ remove }><i class="material-icons">delete</i></button>
</div>
{#if showDialog}
{#if showValueDialog}
<div class="dialog">
<div class="dialog-content">
<h1>{ showIncrement ? "Add" : "Set" }</h1>
@ -23,7 +20,19 @@
<button class="ok" on:click={ dialogDone }>OK</button>
</div>
</div>
{/if}
{/if}
{#if showEditDialog}
<div class="dialog">
<div class="dialog-content">
<label>Name: <input type="text" bind:value={editingCounter.title} use:focus/></label>
<label>Initial Value: <input type="number" bind:value={editingCounter.initialValue} /></label>
<label>Target: <input type="number" bind:value={editingCounter.max} /></label>
<label>Save history: <input type="checkbox" bind:checked={editingCounter.saveHistory} /></label>
<button on:click={ () => { showEditDialog = false; } }>Cancel</button>
<button class="ok" on:click={ finishEdit }>OK</button>
</div>
</div>
{/if}
</div>
<script>
import MyProgress from './MyProgress.svelte';
@ -40,18 +49,10 @@ $: counter = $counters.find(x => x.id == counterId);
let dialogValue;
let showIncrement;
let showSet;
let message = '';
let showEditDialog;
let editingCounter;
$: showDialog = showIncrement || showSet;
const formatter = new Intl.DateTimeFormat('en-US',
{
month: 'short',
day: 'numeric',
year: 'numeric',
hour: 'numeric',
minute: 'numeric'
});
$: showValueDialog = showIncrement || showSet;
function focus(node){
node.focus();
@ -61,6 +62,18 @@ function update(newCounter){
counters.update(newCounter);
}
function startEdit(e){
e.stopPropagation();
editingCounter = {...counter};
showEditDialog = true;
}
function finishEdit(){
update(editingCounter);
showEditDialog = false;
}
function dialogCancel(){
showIncrement = false;
showSet = false;
@ -88,50 +101,18 @@ function reset(e){
if(confirm(`Reset ${counter.title}?`)){
const newCounter = {
...counter,
value: 0
value: counter.initialValue
}
update(newCounter);
}
}
function save(e) {
e.stopPropagation();
const time = new Date();
const data = {
time,
value: counter.value
}
const newCounter = {
...counter,
history: [...counter.history, data]
}
message = `Saved ${data.value} at ${formatter.format(data.time)}`;
setTimeout(() => message = '', 5000);
update(newCounter);
}
function remove(){
if(confirm(`Remove ${counter.title}?`))
counters.remove(counter);
}
function clickCount() {
if(!counter.isClickCounter)
return;
const newCounter = {
...counter,
value: counter.value + 1
}
update(newCounter);
}
</script>
<style>
.counter{
@ -148,11 +129,6 @@ function clickCount() {
display: flex;
}
.message {
flex: 1;
text-align: center;
}
header {
font-size: 22px;
font-weight: 600;
@ -165,6 +141,10 @@ header {
margin-left: 0;
}
.reset {
margin-left: auto;
}
.dialog-value {
width: 100%;
margin: 5px 0;

View file

@ -6,13 +6,37 @@ function createCounters(){
const {subscribe,set,update:updateVal} = writable([]);
getDb('counters').then(counters => {
if(counters)
set(counters);
if(counters) {
const updatedCounters = counters.map(counter => {
return {
initialValue: 0,
showHistory: false,
...counter
}
});
set(updatedCounters);
}
});
function updateHistory(counter){
if(counter.saveHistory){
const time = new Date();
const data = {
time,
value: counter.value
};
counter.history = [...counter.history, data];
}
}
function add(counter){
const newCounter = { id: uuid(), ...counter };
updateHistory(newCounter);
updateVal(counters => {
const newCounters = [...counters, newCounter];
@ -23,6 +47,8 @@ function createCounters(){
}
function update(counter){
updateHistory(counter);
updateVal(counters => {
const counterIndex = counters.findIndex(x => x.id == counter.id);

View file

@ -50,7 +50,7 @@ button {
background-color: #E0E0E0;
pointer-events: all;
width: 250px;
width: 300px;
border-radius: 5px;
box-shadow: 0 1px 3px rgba(0,0,0,0.12), 0 1px 2px rgba(0,0,0,0.24);
@ -60,6 +60,16 @@ button {
flex-wrap: wrap;
}
.dialog-content > label {
display: flex;
width: 100%;
margin-bottom: 5px;
}
.dialog-content > label > input {
margin-left: auto;
}
input[type="text"],
input[type="number"] {
font-size: 16px;