- added Categories to the Task List.

- Drawer added SubMenu : Personal / Work Todo list categories.
This commit is contained in:
Paolo Arena
2019-01-29 03:12:18 +01:00
parent 0225f27535
commit e029f6165e
13 changed files with 132 additions and 1301 deletions

File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 375 KiB

42
src/classes/debounce.ts Normal file
View File

@@ -0,0 +1,42 @@
/**
* A function that emits a side effect and does not return anything.
*/
export type Procedure = (...args: any[]) => void
export type Options = {
isImmediate: boolean
}
export function debounce<F extends Procedure>(
func: F,
waitMilliseconds: number = 50,
options: Options = {
isImmediate: false
}
): F {
let timeoutId: NodeJS.Timeout | undefined
return function(this: any, ...args: any[]) {
const context = this
const doLater = function() {
timeoutId = undefined
if (!options.isImmediate) {
func.apply(context, args)
}
}
const shouldCallNow = options.isImmediate && timeoutId === undefined
if (timeoutId !== undefined) {
clearTimeout(timeoutId)
}
timeoutId = <any>setTimeout(doLater, waitMilliseconds)
if (shouldCallNow) {
func.apply(context, args)
}
} as any
}

View File

@@ -1,4 +1,8 @@
$colcompleted: #a2a2a2;
$heightitem: 19px;
.flex-item{ .flex-item{
// background-color: #d5e2eb; // background-color: #d5e2eb;
padding: 0px; padding: 0px;
@@ -10,7 +14,7 @@
.flex-container2 { .flex-container2 {
flex-flow: row nowrap; flex-flow: row wrap;
justify-content: space-between; justify-content: space-between;
margin: 2px 5px 2px 5px; // top right bottom left margin: 2px 5px 2px 5px; // top right bottom left
} }
@@ -46,8 +50,8 @@
margin-right: 1px; margin-right: 1px;
padding-left: 1px; padding-left: 1px;
padding-right: 1px; padding-right: 1px;
height: 36px; height: $heightitem;
line-height: 36px; line-height: $heightitem;
text-align: center; text-align: center;
// background-color: #ff4081; // background-color: #ff4081;
font-size: 0.75rem; font-size: 0.75rem;
@@ -67,8 +71,8 @@
max-width: 92px; max-width: 92px;
min-width: 92px; min-width: 92px;
margin: 0 auto; margin: 0 auto;
height: 36px; height: $heightitem;
line-height: 36px; line-height: $heightitem;
text-align: center; text-align: center;
// background-color: #ff4081; // background-color: #ff4081;
font-size: 1rem; font-size: 1rem;
@@ -135,8 +139,8 @@
.percProgress { .percProgress {
height: 24px; height: $heightitem;
line-height: 24px; line-height: $heightitem;
color: #888; color: #888;
} }
@@ -157,6 +161,10 @@
color: green; color: green;
} }
.percompleted {
color: $colcompleted
}
.myexpired { .myexpired {
padding-top: 0px; padding-top: 0px;
padding-bottom: 0px; padding-bottom: 0px;
@@ -164,10 +172,11 @@
} }
.data-item { .data-item {
//max-width: 100px; max-width: 100px;
//min-width: 100px; //min-width: 100px;
//display: flex; //display: flex;
//visibility: initial; //visibility: initial;
margin-right: 3px;
color: #ccc; color: #ccc;
order: 1; order: 1;
flex: 1; flex: 1;
@@ -264,7 +273,7 @@
} }
.status_completed { .status_completed {
color:rgba(49, 68, 240, 0.7); color: $colcompleted
} }
.menuTitlePriority { .menuTitlePriority {

View File

@@ -8,6 +8,8 @@ import { ITodo } from '../../../model/index'
import $ from 'jquery' import $ from 'jquery'
import { debounce } from '../../../classes/debounce'
@Component({ @Component({
name: 'SingleTodo' name: 'SingleTodo'
}) })
@@ -22,7 +24,7 @@ export default class SingleTodo extends Vue {
public classExpiringEx: string = '' public classExpiringEx: string = ''
public iconPriority: string = '' public iconPriority: string = ''
public popover: boolean = false public popover: boolean = false
public popover_menu: boolean = false public popover_menu: boolean = false // Serve
public classRow: string = '' public classRow: string = ''
public sel: boolean = false public sel: boolean = false
public inEdit: boolean = false public inEdit: boolean = false
@@ -102,6 +104,9 @@ export default class SingleTodo extends Vue {
mycolcl = ' highperc' mycolcl = ' highperc'
} }
if (this.itemtodo.completed)
mycolcl = ' percompleted'
this.colProgress = mycolcl this.colProgress = mycolcl
this.menuProgress += mycolcl this.menuProgress += mycolcl
@@ -124,7 +129,7 @@ export default class SingleTodo extends Vue {
this.menuPopupTodo = rescodes.menuPopupTodo[UserStore.state.lang] this.menuPopupTodo = rescodes.menuPopupTodo[UserStore.state.lang]
else { else {
this.menuPopupTodo = [] this.menuPopupTodo = []
this.menuPopupTodo.push(rescodes.menuPopupTodo[UserStore.state.lang][0]) this.menuPopupTodo.push(rescodes.menuPopupTodo[UserStore.state.lang][rescodes.INDEX_MENU_DELETE])
} }
} }
@@ -304,6 +309,8 @@ export default class SingleTodo extends Vue {
this.enableExpiring() this.enableExpiring()
} else if (action === rescodes.MenuAction.COMPLETED) { } else if (action === rescodes.MenuAction.COMPLETED) {
this.setCompleted() this.setCompleted()
} else if (action === rescodes.MenuAction.PROGRESS_BAR) {
this.updatedata()
} }
} }

View File

@@ -59,3 +59,12 @@
min-height: 10px; min-height: 10px;
} }
.categorytitle{
font-size: 1.25rem;
font-weight: bold;
}
.titleSubMenu {
font-size: 0.7rem;
font-weight: 350;
}

View File

@@ -15,6 +15,7 @@ import draggable from 'vuedraggable'
import $ from 'jquery' import $ from 'jquery'
@Component({ @Component({
components: { SingleTodo, draggable } components: { SingleTodo, draggable }
}) })
export default class Todo extends Vue { export default class Todo extends Vue {
@@ -41,6 +42,15 @@ export default class Todo extends Vue {
console.log('drag = ' + this.drag) console.log('drag = ' + this.drag)
} }
@Watch('$route.params.category') changecat() {
console.log('changecat')
this.load()
}
getCategory() {
return this.$route.params.category
}
change(param) { change(param) {
console.log('Change... ' + param) console.log('Change... ' + param)
} }
@@ -257,6 +267,7 @@ export default class Todo extends Vue {
priority: rescodes.Todos.PRIORITY_NORMAL, priority: rescodes.Todos.PRIORITY_NORMAL,
completed: false, completed: false,
created_at: new Date(), created_at: new Date(),
category: '',
modify_at: new Date(), modify_at: new Date(),
expiring_at: mydateexp, expiring_at: mydateexp,
enableExpiring: false, enableExpiring: false,
@@ -286,6 +297,7 @@ export default class Todo extends Vue {
const objtodo = this.initcat() const objtodo = this.initcat()
objtodo.descr = this.todo objtodo.descr = this.todo
objtodo.category = this.getCategory()
const lastelem = this.getLastList() const lastelem = this.getLastList()
objtodo.id_prev = (lastelem !== null) ? lastelem.id : rescodes.LIST_START objtodo.id_prev = (lastelem !== null) ? lastelem.id : rescodes.LIST_START
objtodo.id_next = rescodes.LIST_END objtodo.id_next = rescodes.LIST_END
@@ -432,6 +444,7 @@ export default class Todo extends Vue {
// #Todo If need to filter the output database ... // #Todo If need to filter the output database ...
await this.$db.todos await this.$db.todos
.where('userId').equals(UserStore.state.userId) .where('userId').equals(UserStore.state.userId)
.and(todo => todo.category === this.getCategory())
.toArray() .toArray()
.then((response) => { .then((response) => {
Promise.all(response.map(key => key)) Promise.all(response.map(key => key))
@@ -442,6 +455,7 @@ export default class Todo extends Vue {
} else { } else {
await this.$db.todos await this.$db.todos
.where('userId').equals(UserStore.state.userId) .where('userId').equals(UserStore.state.userId)
.and(todo => todo.category === this.getCategory())
.toArray().then(ristodos => { .toArray().then(ristodos => {
arrtemp = ristodos arrtemp = ristodos
}) })
@@ -541,6 +555,7 @@ export default class Todo extends Vue {
this.modifyField(miorec, myobj, 'descr') this.modifyField(miorec, myobj, 'descr')
this.modifyField(miorec, myobj, 'completed') this.modifyField(miorec, myobj, 'completed')
this.modifyField(miorec, myobj, 'category')
this.modifyField(miorec, myobj, 'expiring_at') this.modifyField(miorec, myobj, 'expiring_at')
this.modifyField(miorec, myobj, 'priority') this.modifyField(miorec, myobj, 'priority')
this.modifyField(miorec, myobj, 'id_prev') this.modifyField(miorec, myobj, 'id_prev')

View File

@@ -3,6 +3,8 @@
<div class="panel"> <div class="panel">
<p class="caption"></p> <p class="caption"></p>
<div class="categorytitle">{{ getCategory() }}</div>
<div style="display: none">{{ prior = 0, priorcomplet = false }}</div> <div style="display: none">{{ prior = 0, priorcomplet = false }}</div>
<div class="drag"> <div class="drag">

View File

@@ -53,19 +53,27 @@
console.log('Drawer created...') console.log('Drawer created...')
} }
Glo
photo = '' photo = ''
user = null user = null
links = { links = {
Dashboard: { Dashboard: {
routes: [ routes: [
{ route: '/', faIcon: 'fa fa-home', materialIcon: 'home', name: 'pages.home' }, { route: '/', faIcon: 'fa fa-home', materialIcon: 'home', name: 'pages.home' },
{ route: '/todo', faIcon: 'fa fa-list-alt', materialIcon: 'todo', name: 'pages.Todo' }, {
route: '/todo', faIcon: 'fa fa-list-alt', materialIcon: 'todo', name: 'pages.Todo',
routes2: [
{ route: '/todo/personal', faIcon: 'fa fa-list-alt', materialIcon: 'todo', name: 'Personal' },
{ route: '/todo/work', faIcon: 'fa fa-list-alt', materialIcon: 'todo', name: 'Work' }
]
},
{ route: '/category', faIcon: 'fa fa-list-alt', materialIcon: 'category', name: 'pages.Category' }, { route: '/category', faIcon: 'fa fa-list-alt', materialIcon: 'category', name: 'pages.Category' },
{ route: '/signup', faIcon: 'fa fa-registered', materialIcon: 'home', name: 'pages.SignUp' }, { route: '/signup', faIcon: 'fa fa-registered', materialIcon: 'home', name: 'pages.SignUp' },
{ route: '/signin', faIcon: 'fa fa-anchor', materialIcon: 'home', name: 'pages.SignIn' }, { route: '/signin', faIcon: 'fa fa-anchor', materialIcon: 'home', name: 'pages.SignIn' },
/* {route: '/vreg?idlink=aaa', faIcon: 'fa fa-login', materialIcon: 'login', name: 'pages.vreg'},*/ /* {route: '/vreg?idlink=aaa', faIcon: 'fa fa-login', materialIcon: 'login', name: 'pages.vreg'},*/
], ],
show: true show: true,
}, },
Forms: { Forms: {
routes: [ routes: [
@@ -140,7 +148,7 @@
margin-top: 5%; margin-top: 5%;
} }
.fixed-left:hover{ .fixed-left:hover {
cursor: ew-resize; cursor: ew-resize;
} }

View File

@@ -1,15 +1,26 @@
<template> <template>
<div class="list no-border platform-delimiter light-paragraph"> <div class="list no-border platform-delimiter light-paragraph">
<q-icon name="action"/> <q-icon name="action"/>
<template v-for="(parent, index) in links"> <template v-for="(parent, index) in links">
<!-- <!--
<div class="list-label cursor-pointer" @click="parent.show = !parent.show"> <div class="list-label cursor-pointer" @click="parent.show = !parent.show">
{{replaceUnderlineToSpace(index)}} <div class="menu_freccina"><i aria-hidden="true" class="v-icon material-icons theme--light">keyboard_arrow_down</i></div> {{replaceUnderlineToSpace(index)}} <div class="menu_freccina"><i aria-hidden="true" class="v-icon material-icons theme--light">keyboard_arrow_down</i></div>
</div>
-->
<div class="q-list-header">{{replaceUnderlineToSpace(index)}}</div>
<template v-for="child in parent.routes">
<div v-if="child.routes2">
<q-collapsible menu :label="$t(child.name)" icon="format_list_bulleted" class="titleSubMenu">
<div v-for="child2 in child.routes2">
<q-item link :to="child2.route" exact
class="item item-link drawer-closer cursor-pointer">
<i :class="child2.faIcon" class="item-primary"></i>
<div class="item-content">{{$t(child2.name)}}</div>
</q-item>
</div>
</q-collapsible>
</div> </div>
--> <div v-else>
<div class="q-list-header">{{replaceUnderlineToSpace(index)}}</div>
<template v-for="child in parent.routes">
<q-slide-transition :duration=200> <q-slide-transition :duration=200>
<div v-show="true"> <div v-show="true">
<q-item link :to="child.route" exact <q-item link :to="child.route" exact
@@ -19,7 +30,8 @@
</q-item> </q-item>
</div> </div>
</q-slide-transition> </q-slide-transition>
</template> </div>
</template>
</template> </template>
</div> </div>
</template> </template>
@@ -67,7 +79,7 @@
padding: 5px 8px; padding: 5px 8px;
} }
.menu-hr{ .menu-hr {
border-color: #dedede; border-color: #dedede;
height: 0.5px; height: 0.5px;
} }

View File

@@ -1,6 +1,7 @@
export interface ITodo { export interface ITodo {
id?: number, id?: number,
userId: string userId: string
category?: string
descr?: string, descr?: string,
priority: number, priority: number,
completed: boolean, completed: boolean,

View File

@@ -9,7 +9,7 @@ export default ({ Vue }) => {
database: 'test', database: 'test',
schemas: [ schemas: [
{ categories: '++id, sub_categ_id, descr_it, campo2bool, campo3bool' }, { categories: '++id, sub_categ_id, descr_it, campo2bool, campo3bool' },
{ todos: '++id, userId, pos, descr, priority, completed, created_at, modify_at, expiring_at, progress, enableExpiring' } { todos: '++id, userId, category, pos, descr, priority, completed, created_at, modify_at, expiring_at, progress, enableExpiring' }
], ],
options: { options: {
todos: { type: 'list', primary: 'pos', label: 'label', updated_at: 'updated_at' }, todos: { type: 'list', primary: 'pos', label: 'label', updated_at: 'updated_at' },

View File

@@ -25,7 +25,7 @@ export const RouteConfig: VueRouteConfig[] = [
meta: { name: 'Verify Reg' } meta: { name: 'Verify Reg' }
}, },
{ {
path: '/todo', path: '/todo/:category',
component: () => import('@/components/todos/todo/todo.vue'), component: () => import('@/components/todos/todo/todo.vue'),
meta: { name: 'Todos' } meta: { name: 'Todos' }
}, },

View File

@@ -74,6 +74,8 @@ export const rescodes = {
}, },
INDEX_MENU_DELETE: 3,
menuPopupTodo: { menuPopupTodo: {
'it': [ 'it': [
{ {