- todo: design: flexbox, dragging, icons, priority.

This commit is contained in:
Paolo Arena
2019-01-16 02:26:43 +01:00
parent 2984f20b58
commit ce9f901b0a
23 changed files with 327 additions and 102 deletions

View File

@@ -118,11 +118,13 @@ module.exports = function (ctx) {
'QToolbar', 'QToolbar',
'QToolbarTitle', 'QToolbarTitle',
'QBtn', 'QBtn',
'QBtnDropdown',
'QIcon', 'QIcon',
'QList', 'QList',
'QListHeader', 'QListHeader',
'QItem', 'QItem',
'QItemMain', 'QItemMain',
'QItemTile',
'QItemSide', 'QItemSide',
'QCard', 'QCard',
'QCardTitle', 'QCardTitle',

View File

@@ -1,8 +1,6 @@
import Vue from 'vue' import Vue from 'vue'
import { Component, Prop } from 'vue-property-decorator' import { Component, Prop } from 'vue-property-decorator'
require('./SingleCat.scss')
import { ICategory } from '../../../model/index' import { ICategory } from '../../../model/index'
@Component({ @Component({

View File

@@ -17,3 +17,7 @@
<script lang="ts" src="./SingleCat.ts"> <script lang="ts" src="./SingleCat.ts">
</script> </script>
<style lang="scss" scoped>
@import './SingleCat.scss';
</style>

View File

@@ -4,8 +4,6 @@ import { Component, Watch } from 'vue-property-decorator'
import { SingleCat } from '@components' import { SingleCat } from '@components'
import { ICategory } from '@src/model' import { ICategory } from '@src/model'
require('./category.scss')
@Component({ @Component({
components: { SingleCat } components: { SingleCat }

View File

@@ -61,3 +61,7 @@
</template> </template>
<script lang="ts" src="./category.ts"> <script lang="ts" src="./category.ts">
</script> </script>
<style lang="scss" scoped>
@import './category.scss';
</style>

View File

@@ -3,9 +3,6 @@ import { Component, Watch } from 'vue-property-decorator'
import { ICategory } from '@src/model' import { ICategory } from '@src/model'
require('./tabledata.scss')
@Component({ @Component({
}) })
export default class Tabledata extends Vue { export default class Tabledata extends Vue {

View File

@@ -59,3 +59,7 @@
</template> </template>
<script lang="ts" src="./tabledata.ts"> <script lang="ts" src="./tabledata.ts">
</script> </script>
<style lang="scss" scoped>
@import './tabledata.scss';
</style>

View File

@@ -1,8 +1,6 @@
import Vue from 'vue' import Vue from 'vue'
import { Component } from 'vue-property-decorator' import { Component } from 'vue-property-decorator'
require('./logo.scss')
import { TimelineLite, Back } from 'gsap' import { TimelineLite, Back } from 'gsap'
import $ from 'jquery' import $ from 'jquery'

View File

@@ -5,3 +5,7 @@
</template> </template>
<script lang="ts" src="./logo.ts"> <script lang="ts" src="./logo.ts">
</script> </script>
<style lang="scss" scoped>
@import './logo.scss';
</style>

View File

@@ -1,37 +1,115 @@
.flex-container { .flex-item{
padding: 0; background-color: #d5e2eb;
margin: 0; padding: 1px;
list-style: none; margin: 1px;
color: #000;
font-size: 0.85rem;
flex: 1 1 auto;
}
-ms-box-orient: horizontal; .flex-container2 {
display: -webkit-box; flex-flow: row nowrap;
display: -moz-box; justify-content: space-between;
display: -ms-flexbox; }
display: -moz-flex;
display: -webkit-flex; .btn-item {
display: flex; max-width: 24px;
} }
#appsingletodo { .pos-item {
color: white; max-width: 24px;
font-size: 1.1rem; min-width: 24px;
display: flex; margin: 0 auto;
margin: 2px; height: 36px;
padding: 3px; line-height: 36px;
border: 2px; text-align: center;
background-color: #9db6ff; }
.priority-item-popover {
max-width: 24px;
min-width: 24px;
padding: 0px;
}
.priority-item {
max-width: 24px;
min-width: 24px;
}
.completed-item {
max-width: 24px;
min-width: 24px;
}
.myexpired {
padding-top: 0px;
padding-bottom: 0px;
font-size: 12px;
}
.data-item {
max-width: 100px;
min-width: 100px;
display: block;
visibility: initial;
}
@media screen and (max-width: 600px) {
.data-item {
display: none;
visibility: hidden;
content: "";
}
}
.div_descr {
// background-color: green;
flex: 2 1 auto;
}
.appsingletodo {
color: black;
font-size: 1.0rem;
// display: flex;
margin: 1px;
padding: 2px;
border: 1px;
background-color: #e1ebed;
} }
.mycols{ .mycols{
padding: 2px;
margin: 1px; margin: 1px;
border-color: #8a8484; padding: 2px;
border-style: outset; //width: 40px;
/* background-color: green; */ // border-color: #8a8484;
// border-style: outset;
margin: auto;
// flex-grow: 1;
}
.mycols:hover{
} }
.mybtn{ .mybtn{
width: 18px; width: 18px;
height: 18px; height: 18px;
} }
.icon_completed {
position: relative;
transform: translateY(0%);
}
.mydescr{
}
.icon_completed:hover {
color: darkgreen;
}

View File

@@ -1,8 +1,6 @@
import Vue from 'vue' import Vue from 'vue'
import { Component, Prop, Watch } from 'vue-property-decorator' import { Component, Prop, Watch } from 'vue-property-decorator'
require('./SingleTodo.scss')
import { rescodes } from '../../../store/Modules/rescodes' import { rescodes } from '../../../store/Modules/rescodes'
import { UserStore } from '@modules' import { UserStore } from '@modules'
@@ -12,7 +10,12 @@ import { ITodo } from '../../../model/index'
name: 'SingleTodo' name: 'SingleTodo'
}) })
export default class SingleTodo extends Vue { export default class SingleTodo extends Vue {
public selectPriority: [] public selectPriority: [] = []
public iconCompleted: string = ''
public iconPriority: string = ''
public popover: boolean = false
$q: any
@Prop({required: true}) itemtodo: ITodo @Prop({required: true}) itemtodo: ITodo
@Watch('itemtodo.completed') valueChanged() { @Watch('itemtodo.completed') valueChanged() {
@@ -25,12 +28,52 @@ export default class SingleTodo extends Vue {
this.$emit('eventupdate', this.itemtodo) this.$emit('eventupdate', this.itemtodo)
} }
setCompleted () {
// console.log('setCompleted')
this.itemtodo.completed = !this.itemtodo.completed
this.updateicon()
this.updatedata()
}
updatedata() {
this.$emit('eventupdate', this.itemtodo)
}
updateicon () {
if (this.itemtodo.completed)
this.iconCompleted = 'check_circle'
else
this.iconCompleted = 'check_circle_outline'
if (this.itemtodo.priority === rescodes.Todos.PRIORITY_HIGH)
this.iconPriority = 'expand_less' // expand_less
else if (this.itemtodo.priority === rescodes.Todos.PRIORITY_NORMAL)
this.iconPriority = 'remove'
else if (this.itemtodo.priority === rescodes.Todos.PRIORITY_LOW)
this.iconPriority = 'expand_more' // expand_more
}
created() { created() {
this.updateicon()
this.selectPriority = rescodes.selectPriority[UserStore.state.lang] this.selectPriority = rescodes.selectPriority[UserStore.state.lang]
} }
remove(id) { remove(id) {
this.$emit('event', id) this.$emit('event', id)
} }
setPriority (newpriority) {
this.itemtodo.priority = newpriority
this.updatedata()
// this.$q.notify('setPriority: ' + elem)
}
} }

View File

@@ -1,30 +1,55 @@
<template> <template>
<div id="appsingletodo" class="flex-container"> <div class="row flex-container2">
<div class="flex-item pos-item">{{ itemtodo.pos }}ª</div>
<div class="flex-item priority-item">
<q-btn push
class="priority-item-popover"
:icon="iconPriority">
<q-popover
v-model="popover"
self="top left"
<div class="doc-container"> >
<div class="row"> <q-list link>
<div class="flex-item mycols">P: {{ itemtodo.pos }}</div> <q-item v-for="field in selectPriority" :key="field.value"
<q-checkbox class="flex-item mycols" v-model="itemtodo.completed" :label="itemtodo.descr" /> @click.native="setPriority(field.value), popover = false">
<div class="flex-item mycols"> <q-item-side :icon="field.icon" inverted color="primary"/>
<q-select <q-item-main>
v-model="itemtodo.priority" <q-item-tile label>{{field.label}}</q-item-tile>
float-label="" </q-item-main>
radio </q-item>
:options="selectPriority" </q-list>
/> </q-popover>
</div> </q-btn>
</div>
<div class="flex-item mycols"><q-datetime <div class="flex-item completed-item">
v-model="itemtodo.expiring_at"/></div> <q-btn push
<div class="flex-item mycols"> class="priority-item-popover"
<q-btn class="mybtn" round color="" icon="delete" @click="remove(itemtodo.id)"></q-btn> :icon="iconCompleted"
</div> @click.native="setCompleted">
</q-btn>
</div> <!--<q-icon class=" mycols allleft icon_completed ScheduleStatus" :name="iconCompleted"
@click.native="setCompleted"/>-->
</div>
<div class="flex-item div_descr">
{{ itemtodo.descr }}
</div> </div>
<div class="flex-item data-item">
<q-datetime
v-model="itemtodo.expiring_at"
class="myexpired"/>
</div>
<div class="flex-item btn-item">
<q-btn class="mybtn" round color="" icon="delete" @click="remove(itemtodo.id)"></q-btn>
</div>
</div> </div>
</template> </template>
<script lang="ts" src="./SingleTodo.ts"> <script lang="ts" src="./SingleTodo.ts">
</script> </script>
<style lang="scss" scoped>
@import './SingleTodo.scss';
</style>

View File

@@ -1,3 +1,13 @@
.flex-container{
background-color: #ccc;
padding: 5px;
display: flex;
flex-flow: row nowrap;
justify-content: space-between;
}
.mycard { .mycard {
visibility: hidden; visibility: hidden;
} }

View File

@@ -4,16 +4,16 @@ import { Component, Watch } from 'vue-property-decorator'
import { SingleTodo } from '@components' import { SingleTodo } from '@components'
import { ITodo } from '@src/model' import { ITodo } from '@src/model'
require('./todo.scss')
import { rescodes } from '../../../store/Modules/rescodes' import { rescodes } from '../../../store/Modules/rescodes'
import { UserStore } from '@modules' import { UserStore } from '@modules'
import _ from 'lodash' import _ from 'lodash'
import draggable from 'vuedraggable'
@Component({ @Component({
components: { SingleTodo } components: { SingleTodo, draggable }
}) })
export default class Todo extends Vue { export default class Todo extends Vue {
$q: any $q: any
@@ -22,6 +22,50 @@ export default class Todo extends Vue {
title: string = '' title: string = ''
todo: string = '' todo: string = ''
todos_arr: any[] = [{}] todos_arr: any[] = [{}]
drag: boolean = true
startpos: number = 0
endpos: number = 0
@Watch('drag') changedrag() {
console.log('drag = ' + this.drag)
}
change(param) {
console.log('Change... ' + param)
}
onStart() {
this.startpos = 0
}
getpos(indelem) {
return this.todos_arr[indelem].pos
}
onEnd(myvar) {
let oldpos = this.getpos(myvar.oldIndex)
let newpos = this.getpos(myvar.newIndex)
console.log('onEnd old = ' + oldpos + ' new = ' + newpos)
if (myvar.oldIndex < myvar.newIndex) {
// c'è spazio
newpos = oldpos - 1
if (newpos <= 0)
newpos = 1
} else {
newpos = newpos + 1
}
console.log('newpos = ' + newpos)
if (newpos >= 0) {
let myobj = this.todos_arr[myvar.oldIndex]
console.log('posprec = ' + myobj.pos)
myobj.pos = newpos
this.modify(myobj)
}
}
created() { created() {
@@ -85,24 +129,25 @@ export default class Todo extends Vue {
console.log('Errore: ' + err.message) console.log('Errore: ' + err.message)
}) })
// objtodo.id = myid
// Add into the memory
// this.todos_loc.push(objtodo)
// empty the field // empty the field
this.todo = '' this.todo = ''
} }
deleteitem(id) { getobjbyid(id) {
// console.log('deleteitem: KEY = ', id)
let myobjtrov = null let myobjtrov = null
this.todos_arr.forEach(myobj => { this.todos_arr.forEach(myobj => {
if (myobj.id === id) if (myobj.id === id)
myobjtrov = myobj myobjtrov = myobj
}) })
return myobjtrov
}
deleteitem(id) {
// console.log('deleteitem: KEY = ', id)
let myobjtrov = this.getobjbyid(id)
if (myobjtrov !== null) { if (myobjtrov !== null) {
// Delete item // Delete item
this.$db.todos this.$db.todos
@@ -133,38 +178,22 @@ export default class Todo extends Vue {
}) })
} else { } else {
// this.$db.dispatch('todosSetSort', { sort: 'pos' } )
let coll = this.$db.todos
await this.$db.todos await this.$db.todos
.where('userId').equals(UserStore.state.userId) .where('userId').equals(UserStore.state.userId)
// .sortBy('descr')
.toArray().then(ristodos => { .toArray().then(ristodos => {
this.todos_arr = ristodos this.todos_arr = ristodos
}) })
let reverse = []
reverse['completed'] = true
reverse['priority'] = true
reverse['pos'] = true
console.log(reverse)
this.todos_arr = _.orderBy(this.todos_arr, ['completed', 'priority', 'pos'], ['asc', 'desc', 'asc']) this.todos_arr = _.orderBy(this.todos_arr, ['completed', 'priority', 'pos'], ['asc', 'desc', 'asc'])
} }
this.todos_arr.map((item, index) => {
item.pos = (index * 2) + 1
})
return [] return []
} }
/*
await db.transaction('rw', [db.friends], async () => {
const friend = await db.friends.get(1);
++friend.age;
await db.friends.put(friend);
});
*/
updateitem(myobj) { updateitem(myobj) {
console.log('updateitem') console.log('updateitem')
this.modify(myobj) this.modify(myobj)
@@ -179,6 +208,7 @@ export default class Todo extends Vue {
miorec.completed = myobj.completed miorec.completed = myobj.completed
miorec.expiring_at = myobj.expiring_at miorec.expiring_at = myobj.expiring_at
miorec.priority = myobj.priority miorec.priority = myobj.priority
miorec.pos = myobj.pos
await this.$db.todos.put(miorec) await this.$db.todos.put(miorec)

View File

@@ -7,9 +7,18 @@
:after="[{icon: 'arrow_forward', content: true, handler () {}}]" :after="[{icon: 'arrow_forward', content: true, handler () {}}]"
v-on:keyup.enter="insertTodo"/> v-on:keyup.enter="insertTodo"/>
<SingleTodo @event="deleteitem" @eventupdate="updateitem" :itemtodo='mytodo' v-for="mytodo of todos_arr" :key="mytodo.id">
</SingleTodo> <div class="flex-container">
<draggable v-model="todos_arr" :options="{draggable:'.myitemdrag'}" @start="onStart" @end="onEnd">
<transition-group>
<SingleTodo @event="deleteitem" @eventupdate="updateitem" :itemtodo='mytodo'
v-for="mytodo of todos_arr" :key="mytodo.id" class="myitemdrag">
</SingleTodo>
</transition-group>
</draggable>
</div>
<!--<div v-for="element in todos_arr" :key="element.id">{{element.descr}}</div>-->
</div> </div>
</q-page> </q-page>
@@ -18,3 +27,6 @@
</template> </template>
<script lang="ts" src="./todo.ts"> <script lang="ts" src="./todo.ts">
</script> </script>
<style lang="scss" scoped>
@import './todo.scss';
</style>

View File

@@ -4,8 +4,6 @@ import { GlobalStore } from '@store'
import { Logo } from '@components' import { Logo } from '@components'
require('./home.scss')
@Component({ @Component({
components: { Logo } components: { Logo }
}) })

View File

@@ -8,3 +8,6 @@
</template> </template>
<script lang="ts" src="./home.ts"> <script lang="ts" src="./home.ts">
</script> </script>
<style lang="scss" scoped>
@import './home.scss';
</style>

View File

@@ -17,37 +17,49 @@ export const rescodes = {
Todos: { Todos: {
PRIORITY_NORMAL: 0, PRIORITY_NORMAL: 0,
PRIORITY_HIGH: 10, PRIORITY_HIGH: 1,
PRIORITY_LOW: -10 PRIORITY_LOW: -1
}, },
selectPriority: { selectPriority: {
'it': [ 'it': [
{ {
id: 1,
label: 'Alta', label: 'Alta',
value: 1 value: 1,
icon: 'expand_less'
}, },
{ {
id: 2,
label: 'Normale', label: 'Normale',
value: 0 value: 0,
icon: 'remove'
}, },
{ {
id: 3,
label: 'Bassa', label: 'Bassa',
value: -1 value: -1,
icon: 'expand_more'
}], }],
'enUk': [ 'enUk': [
{ {
id: 1,
label: 'High', label: 'High',
value: 1 value: 1,
icon: 'expand_less'
}, },
{ {
id: 2,
label: 'Normal', label: 'Normal',
value: 0 value: 0,
icon: 'remove'
}, },
{ {
id: 3,
label: 'Low', label: 'Low',
value: -1 value: -1,
icon: 'expand_more'
}] }]
} }

1
src/typings/libs/ambient.d.ts vendored Normal file
View File

@@ -0,0 +1 @@
declare module 'vuedraggable'

View File

@@ -12,7 +12,6 @@ import { validationMixin } from 'vuelidate'
import { Logo } from '@components' import { Logo } from '@components'
import './signin.scss'
import router from '@router' import router from '@router'
// import {Loading, QSpinnerFacebook, QSpinnerGears} from 'quasar' // import {Loading, QSpinnerFacebook, QSpinnerGears} from 'quasar'

View File

@@ -60,3 +60,7 @@
<script lang="ts" src="./signin.ts"> <script lang="ts" src="./signin.ts">
</script> </script>
<style lang="scss" scoped>
@import './signin.scss';
</style>

View File

@@ -10,8 +10,6 @@ import { validationMixin } from 'vuelidate'
import { Logo } from '@components' import { Logo } from '@components'
import './signup.scss'
// import {Loading, QSpinnerFacebook, QSpinnerGears} from 'quasar' // import {Loading, QSpinnerFacebook, QSpinnerGears} from 'quasar'
@Component({ @Component({

View File

@@ -97,3 +97,6 @@
<script lang="ts" src="./signup.ts"> <script lang="ts" src="./signup.ts">
</script> </script>
<style lang="scss" scoped>
@import './signup.scss';
</style>