Remove click counter and save
Add option to automatically save history Create edit dialog Reset to inital value
This commit is contained in:
parent
956b524a8b
commit
76557c7428
4 changed files with 86 additions and 79 deletions
|
@ -8,9 +8,9 @@
|
||||||
<div class="dialog">
|
<div class="dialog">
|
||||||
<div class="dialog-content">
|
<div class="dialog-content">
|
||||||
<label>Name: <input type="text" bind:value={newCounter.title} use:focus/></label>
|
<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>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 on:click={ () => { showAddDialog = false; } }>Cancel</button>
|
||||||
<button class="ok" on:click={ add }>OK</button>
|
<button class="ok" on:click={ add }>OK</button>
|
||||||
</div>
|
</div>
|
||||||
|
@ -28,15 +28,11 @@ function focus(node){
|
||||||
node.focus();
|
node.focus();
|
||||||
}
|
}
|
||||||
|
|
||||||
function save(counter){
|
|
||||||
alert('Save ' + counter.title);
|
|
||||||
}
|
|
||||||
|
|
||||||
function showAdd(){
|
function showAdd(){
|
||||||
newCounter = {
|
newCounter = {
|
||||||
title: '',
|
title: '',
|
||||||
value: 0,
|
initialValue: 0,
|
||||||
isClickCounter: false,
|
saveHistory: false,
|
||||||
history: []
|
history: []
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -44,7 +40,12 @@ function showAdd(){
|
||||||
}
|
}
|
||||||
|
|
||||||
function add(){
|
function add(){
|
||||||
counters.add(newCounter);
|
const counter = {
|
||||||
|
...newCounter,
|
||||||
|
value: newCounter.initialValue
|
||||||
|
}
|
||||||
|
|
||||||
|
counters.add(counter);
|
||||||
|
|
||||||
showAddDialog = false;
|
showAddDialog = false;
|
||||||
}
|
}
|
||||||
|
@ -67,16 +68,6 @@ function add(){
|
||||||
color: white;
|
color: white;
|
||||||
}
|
}
|
||||||
|
|
||||||
.dialog-content > label {
|
|
||||||
display: flex;
|
|
||||||
width: 100%;
|
|
||||||
margin-bottom: 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.dialog-content > label > input {
|
|
||||||
margin-left: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
.ok {
|
.ok {
|
||||||
margin-left: auto;
|
margin-left: auto;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,20 +1,17 @@
|
||||||
<div class="counter" on:click="{ clickCount }">
|
<div class="counter">
|
||||||
<header>{ counter.title }</header>
|
<header>{ counter.title }</header>
|
||||||
<span class="value">{ counter.value }</span>
|
<span class="value">{ counter.value }</span>
|
||||||
{#if counter.max}
|
{#if counter.max}
|
||||||
<MyProgress value={ counter.value } max={ counter.max }></MyProgress>
|
<MyProgress value={ counter.value } max={ counter.max }></MyProgress>
|
||||||
{/if}
|
{/if}
|
||||||
<div class="controls">
|
<div class="controls">
|
||||||
{#if !counter.isClickCounter}
|
|
||||||
<button on:click={ () => { showIncrement = true; } }><i class="material-icons">add</i></button>
|
<button on:click={ () => { showIncrement = true; } }><i class="material-icons">add</i></button>
|
||||||
<button on:click={ () => { showSet = true; } }><i class="material-icons">create</i></button>
|
<button on:click={ () => { showSet = true; } }><i class="material-icons">edit</i></button>
|
||||||
{/if}
|
|
||||||
<span class="message">{ message }</span>
|
|
||||||
<button class="reset" on:click={ reset }><i class="material-icons">undo</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>
|
<button on:click={ remove }><i class="material-icons">delete</i></button>
|
||||||
</div>
|
</div>
|
||||||
{#if showDialog}
|
{#if showValueDialog}
|
||||||
<div class="dialog">
|
<div class="dialog">
|
||||||
<div class="dialog-content">
|
<div class="dialog-content">
|
||||||
<h1>{ showIncrement ? "Add" : "Set" }</h1>
|
<h1>{ showIncrement ? "Add" : "Set" }</h1>
|
||||||
|
@ -23,7 +20,19 @@
|
||||||
<button class="ok" on:click={ dialogDone }>OK</button>
|
<button class="ok" on:click={ dialogDone }>OK</button>
|
||||||
</div>
|
</div>
|
||||||
</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>
|
</div>
|
||||||
<script>
|
<script>
|
||||||
import MyProgress from './MyProgress.svelte';
|
import MyProgress from './MyProgress.svelte';
|
||||||
|
@ -40,18 +49,10 @@ $: counter = $counters.find(x => x.id == counterId);
|
||||||
let dialogValue;
|
let dialogValue;
|
||||||
let showIncrement;
|
let showIncrement;
|
||||||
let showSet;
|
let showSet;
|
||||||
let message = '';
|
let showEditDialog;
|
||||||
|
let editingCounter;
|
||||||
|
|
||||||
$: showDialog = showIncrement || showSet;
|
$: showValueDialog = showIncrement || showSet;
|
||||||
|
|
||||||
const formatter = new Intl.DateTimeFormat('en-US',
|
|
||||||
{
|
|
||||||
month: 'short',
|
|
||||||
day: 'numeric',
|
|
||||||
year: 'numeric',
|
|
||||||
hour: 'numeric',
|
|
||||||
minute: 'numeric'
|
|
||||||
});
|
|
||||||
|
|
||||||
function focus(node){
|
function focus(node){
|
||||||
node.focus();
|
node.focus();
|
||||||
|
@ -61,6 +62,18 @@ function update(newCounter){
|
||||||
counters.update(newCounter);
|
counters.update(newCounter);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function startEdit(e){
|
||||||
|
e.stopPropagation();
|
||||||
|
|
||||||
|
editingCounter = {...counter};
|
||||||
|
showEditDialog = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function finishEdit(){
|
||||||
|
update(editingCounter);
|
||||||
|
showEditDialog = false;
|
||||||
|
}
|
||||||
|
|
||||||
function dialogCancel(){
|
function dialogCancel(){
|
||||||
showIncrement = false;
|
showIncrement = false;
|
||||||
showSet = false;
|
showSet = false;
|
||||||
|
@ -88,50 +101,18 @@ function reset(e){
|
||||||
if(confirm(`Reset ${counter.title}?`)){
|
if(confirm(`Reset ${counter.title}?`)){
|
||||||
const newCounter = {
|
const newCounter = {
|
||||||
...counter,
|
...counter,
|
||||||
value: 0
|
value: counter.initialValue
|
||||||
}
|
}
|
||||||
|
|
||||||
update(newCounter);
|
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(){
|
function remove(){
|
||||||
if(confirm(`Remove ${counter.title}?`))
|
if(confirm(`Remove ${counter.title}?`))
|
||||||
counters.remove(counter);
|
counters.remove(counter);
|
||||||
}
|
}
|
||||||
|
|
||||||
function clickCount() {
|
|
||||||
if(!counter.isClickCounter)
|
|
||||||
return;
|
|
||||||
|
|
||||||
const newCounter = {
|
|
||||||
...counter,
|
|
||||||
value: counter.value + 1
|
|
||||||
}
|
|
||||||
|
|
||||||
update(newCounter);
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
<style>
|
<style>
|
||||||
.counter{
|
.counter{
|
||||||
|
@ -148,11 +129,6 @@ function clickCount() {
|
||||||
display: flex;
|
display: flex;
|
||||||
}
|
}
|
||||||
|
|
||||||
.message {
|
|
||||||
flex: 1;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
header {
|
header {
|
||||||
font-size: 22px;
|
font-size: 22px;
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
|
@ -165,6 +141,10 @@ header {
|
||||||
margin-left: 0;
|
margin-left: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.reset {
|
||||||
|
margin-left: auto;
|
||||||
|
}
|
||||||
|
|
||||||
.dialog-value {
|
.dialog-value {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
margin: 5px 0;
|
margin: 5px 0;
|
||||||
|
|
|
@ -6,13 +6,37 @@ function createCounters(){
|
||||||
const {subscribe,set,update:updateVal} = writable([]);
|
const {subscribe,set,update:updateVal} = writable([]);
|
||||||
|
|
||||||
getDb('counters').then(counters => {
|
getDb('counters').then(counters => {
|
||||||
if(counters)
|
if(counters) {
|
||||||
set(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){
|
function add(counter){
|
||||||
const newCounter = { id: uuid(), ...counter };
|
const newCounter = { id: uuid(), ...counter };
|
||||||
|
|
||||||
|
updateHistory(newCounter);
|
||||||
|
|
||||||
updateVal(counters => {
|
updateVal(counters => {
|
||||||
const newCounters = [...counters, newCounter];
|
const newCounters = [...counters, newCounter];
|
||||||
|
|
||||||
|
@ -23,6 +47,8 @@ function createCounters(){
|
||||||
}
|
}
|
||||||
|
|
||||||
function update(counter){
|
function update(counter){
|
||||||
|
updateHistory(counter);
|
||||||
|
|
||||||
updateVal(counters => {
|
updateVal(counters => {
|
||||||
const counterIndex = counters.findIndex(x => x.id == counter.id);
|
const counterIndex = counters.findIndex(x => x.id == counter.id);
|
||||||
|
|
||||||
|
|
|
@ -50,7 +50,7 @@ button {
|
||||||
background-color: #E0E0E0;
|
background-color: #E0E0E0;
|
||||||
pointer-events: all;
|
pointer-events: all;
|
||||||
|
|
||||||
width: 250px;
|
width: 300px;
|
||||||
|
|
||||||
border-radius: 5px;
|
border-radius: 5px;
|
||||||
box-shadow: 0 1px 3px rgba(0,0,0,0.12), 0 1px 2px rgba(0,0,0,0.24);
|
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;
|
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="text"],
|
||||||
input[type="number"] {
|
input[type="number"] {
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue