Added and linked todo list to the project list

This commit is contained in:
Paolo Arena
2019-04-03 02:48:05 +02:00
parent 7cacf5c6ea
commit fe600f40a6
34 changed files with 493 additions and 153 deletions

View File

@@ -2,23 +2,21 @@ import Vue from 'vue'
import { Component, Watch } from 'vue-property-decorator'
import { ICategory } from '../../../model/index'
import globalroutines from "../../../globalroutines/index"
import { tools } from "../../../store/Modules/tools"
import { tools } from '../../../store/Modules/tools'
@Component({
})
export default class Tabledata extends Vue {
$q: any
export default class TableData extends Vue {
public $q: any
public filter: boolean = false
public title: string = ''
public category: string = ''
public categories_loc: any[] = [{}]
public categories_arr: any[] = [{}]
public selected: any [] = []
public selectedSecond: any [] = []
filter: boolean = false
title: string = ''
category: string = ''
categories_loc: any[] = [{}]
categories_arr: any[] = [{}]
selected: any [] = []
selectedSecond: any [] = []
data: any [] = [{
public data: any [] = [{
id: 0,
descr_it: 'Frozen Yogurt',
descr_en: '',
@@ -31,7 +29,7 @@ export default class Tabledata extends Vue {
descr_es: ''
}]
columns: any [] = [
public columns: any [] = [
{
name: 'descr_it',
required: true,
@@ -39,7 +37,7 @@ export default class Tabledata extends Vue {
align: 'left',
field: 'descr_it',
sortable: true,
classes: 'my-class',
classes: 'my-class'
},
{
name: 'descr_en',
@@ -47,7 +45,7 @@ export default class Tabledata extends Vue {
align: 'left',
field: 'descr_en',
sortable: true,
classes: 'my-class',
classes: 'my-class'
},
{
name: 'descr_es',
@@ -55,7 +53,7 @@ export default class Tabledata extends Vue {
align: 'left',
field: 'descr_es',
sortable: true,
classes: 'my-class',
classes: 'my-class'
},
{
name: 'campo2bool',
@@ -63,26 +61,25 @@ export default class Tabledata extends Vue {
align: 'left',
field: 'campo2bool',
sortable: true,
classes: 'my-class',
classes: 'my-class'
}
]
@Watch('categories_loc') valueChanged() {
@Watch('categories_loc') public valueChanged() {
this.updatetable()
}
created() {
public created() {
this.loadCat()
}
async loadCat() {
await this.$db.categories.toArray().then(ris => this.categories_loc = ris)
public async loadCat() {
await this.$db.categories.toArray().then((ris) => this.categories_loc = ris)
this.updatetable()
}
initcat() {
public initcat() {
const objcat: ICategory = {
descr_it: '',
@@ -94,7 +91,7 @@ export default class Tabledata extends Vue {
}
async insertCategory() {
public async insertCategory() {
const objcat = this.initcat()
@@ -116,7 +113,7 @@ export default class Tabledata extends Vue {
this.category = ''
}
async deleteCategory(myarrobj) {
public async deleteCategory(myarrobj) {
for (const myobj of myarrobj) {
@@ -142,14 +139,14 @@ export default class Tabledata extends Vue {
}
updatetable() {
public updatetable() {
this.filterCategories()
this.categories_arr = [...this.categories_loc]
}
async filterCategories() {
public async filterCategories() {
if (this.filter) {
// #Todo If need to filter the output database ...
@@ -168,7 +165,7 @@ export default class Tabledata extends Vue {
}
}
deleteRow() {
public deleteRow() {
console.log('SEL = ', this.selectedSecond)
const seldel = [...this.selectedSecond]
@@ -191,7 +188,7 @@ export default class Tabledata extends Vue {
});
*/
async modify() {
public async modify() {
// esempio da sistemare
await this.$db.transaction('rw', [this.$db.categories], async () => {
const friend = await this.$db.get(1)

View File

@@ -57,9 +57,9 @@
</template>
<script lang="ts" src="tabledata.ts">
<script lang="ts" src="./TableData.ts">
</script>
<style lang="scss" scoped>
@import 'tabledata';
@import './TableData.scss';
</style>

View File

@@ -0,0 +1 @@
export {default as TableData} from './TableData.vue'

View File

@@ -1,3 +1,3 @@
export * from './SingleCat/index'
export * from './category/index'
export * from './tabledata/index'
export * from './SingleCat'
export * from './category'
export * from './TableData'

View File

@@ -1 +0,0 @@
export {default as TableData} from './tabledata.vue'

View File

@@ -2,9 +2,9 @@
min-width: 350px;
}
.flex-container{
.flex-container, .flex-container_col{
background-color: rgb(250, 250, 250);
padding: 4px;
padding: 2px 4px 2px 4px;
margin: 2px;
display: flex;
align-items: center;
@@ -12,6 +12,9 @@
justify-content: space-between;
}
.flex-container_col {
flex-direction: column;
}
.mycard {
@@ -113,6 +116,7 @@
.flex-icon{
padding: 3px;
font-size: 1.5rem;
}
.titleSubMenu {

View File

@@ -1,25 +1,26 @@
import Vue from 'vue'
import { Component, Watch } from 'vue-property-decorator'
import { IDrag, IProject, IProjectsState } from '../../../model/index'
import { IDrag, IProject, IProjectsState, ITodo } from '../../../model/index'
import { SingleProject } from '../../../components/projects/SingleProject/index'
import { CTodo } from '../../../components/todos/CTodo'
import { tools } from '../../../store/Modules/tools'
import * as ApiTables from '../../../store/Modules/ApiTables'
import { GlobalStore, Projects } from '@store'
import { GlobalStore, Projects, Todos } from '@store'
import { UserStore } from '@store'
import { Getter } from 'vuex-class'
import { Screen } from 'quasar'
import { CProgress } from '@src/components/CProgress'
import { CProgress } from '@components'
const namespace: string = 'Projects'
@Component({
components: { SingleProject, CProgress },
components: { SingleProject, CProgress, CTodo },
filters: {
capitalize(value) {
if (!value) {
@@ -44,11 +45,14 @@ export default class ProjList extends Vue {
public itemproj: IProject = null
public idsel: string = ''
public itemsel: IProject = Projects.getters.getRecordEmpty()
public itemtodosel: ITodo = Todos.getters.getRecordEmpty()
public whatisSel: number = 0
public colProgress: string = 'blue'
public percProgress: string = 'percProgress'
public $refs: {
singleproject: SingleProject[]
singleproject: SingleProject[],
ctodo: CTodo
}
get getrouteup() {
@@ -210,8 +214,9 @@ export default class ProjList extends Vue {
console.log('this.$refs.singleproject', this.$refs.singleproject)
for (const elem of this.$refs.singleproject) {
// @ts-ignore
if (elem.itemproject._id === id)
if (elem.itemproject._id === id) {
return elem
}
}
}
@@ -232,8 +237,13 @@ export default class ProjList extends Vue {
public setidsel(id: string) {
this.idsel = id
this.whatisSel = tools.WHAT_PROJECT
this.itemsel = Projects.getters.getRecordById(this.idsel)
}
public setitemsel(item: ITodo) {
this.whatisSel = tools.WHAT_TODO
this.itemtodosel = item
}
public async updateitemproj({ myitem, field }) {
console.log('calling MODIFY updateitemproj', myitem, field)
@@ -251,10 +261,25 @@ export default class ProjList extends Vue {
}
public deselectAllRowsproj(item: IProject, check, onlythis: boolean = false) {
// console.log('deselectAllRowsproj : ', item)
public deselectAllRowstodo(item: ITodo, check, onlythis: boolean = false) {
console.log('PROJ-LIST deselectAllRowstodo : ', item)
for (let i = 0; i < this.$refs.singleproject.length; i++) {
// @ts-ignore
for (const i in this.$refs.ctodo.$refs.single) {
// @ts-ignore
const contr = this.$refs.ctodo.$refs.single[i] as SingleTodo
const des = !check
if (des) {
// @ts-ignore
contr.deselectAndExitEdit()
}
}
}
public deselectAllRowsproj(item: IProject, check, onlythis: boolean = false) {
console.log('deselectAllRowsproj: ', item)
for (const i in this.$refs.singleproject) {
const contr = this.$refs.singleproject[i] as SingleProject
// @ts-ignore
@@ -264,7 +289,11 @@ export default class ProjList extends Vue {
if (onlythis) {
des = item._id === id
} else {
des = ((check && (item._id !== id)) || (!check))
if (!!item) {
des = ((check && (item._id !== id)) || (!check))
} else {
des = !check
}
}
if (des) {
// @ts-ignore
@@ -290,9 +319,10 @@ export default class ProjList extends Vue {
}
get getCalcHoursWorked() {
if (this.itemsel.hoursplanned <= 0)
if (this.itemsel.hoursplanned <= 0) {
return 0
let myperc = Math.round(this.itemsel.hoursworked / this.itemsel.hoursplanned * 100)
}
const myperc = Math.round(this.itemsel.hoursworked / this.itemsel.hoursplanned * 100)
return myperc

View File

@@ -84,30 +84,23 @@
<SingleProject ref="singleproject" @deleteItemproj="mydeleteitemproj(myproj._id)"
@eventupdateproj="updateitemproj"
@idsel="setidsel"
@deselectAllRowsproj="deselectAllRowsproj" @onEnd="onEndproj"
@deselectAllRowsproj="deselectAllRowsproj" @deselectAllRowstodo="deselectAllRowstodo" @onEnd="onEndproj"
:itemproject='myproj'>
</SingleProject>
</div>
</div>
<!--</q-infinite-scroll>-->
<q-input ref="insertProjectBottom" v-model="projbottom"
style="margin-left: 6px;"
color="blue-12"
:label="$t('todo.insertbottom')"
:after="[{icon: 'arrow_forward', content: true, handler () {}}]"
v-on:keyup.enter="dbInsert()">
</q-input>
<br>
</div>
<q-separator></q-separator>
<CTodo ref="ctodo" @setitemsel="setitemsel" :categoryAtt="idProjAtt" title="" backcolor="white" forecolor="black" :viewtaskTop="false" @deselectAllRowsproj="deselectAllRowsproj" @deselectAllRowstodo="deselectAllRowstodo"
>
</CTodo>
</div>
</template>
<template v-if="!!itemsel.descr" v-slot:after>
<template v-if="(whatisSel === tools.WHAT_PROJECT) && (!!itemsel.descr)" v-slot:after>
<div class="q-pa-xs clMain">
<div class="flex-container clMain">
<q-icon class="flex-item flex-icon" name="format_align_center"/>
@@ -142,7 +135,6 @@
debounce="500"
/>
<CProgress descr="" :progressval="getCalcHoursWorked"></CProgress>
</div>
<q-icon class="flex-item flex-icon" name="watch_later"/>
<div class="flex-item itemdata content-center">
@@ -159,11 +151,11 @@
</div>
</div>
<div class="flex-container clMain">
<div style="margin: 10px;"></div>
<q-icon class="flex-item flex-icon" name="developer_mode"/>
<div class="flex-item itemdata">
<q-input v-model="itemsel.begin_development" mask="date" :hint="$t('proj.begin_development')">
<q-input dense v-model="itemsel.begin_development" mask="date" :hint="$t('proj.begin_development')">
<!--<span class="data_string">{{tools.getstrDate(itemsel.begin_development)}}</span>-->
<q-icon name="event" class="cursor-pointer">
<q-icon name="event" class="cursor-pointer" style="font-size: 1.5rem;">
<q-popup-proxy>
<q-date v-model="itemsel.begin_development" today-btn/>
</q-popup-proxy>
@@ -172,9 +164,9 @@
</div>
<div style="margin: 10px;"></div>
<div class="flex-item itemdata">
<q-input v-model="itemsel.begin_test" mask="date" :hint="$t('proj.begin_test')">
<q-input dense v-model="itemsel.begin_test" mask="date" :hint="$t('proj.begin_test')">
<!--<span class="data_string">{{tools.getstrDate(itemsel.begin_development)}}</span>-->
<q-icon name="event" class="cursor-pointer">
<q-icon name="event" class="cursor-pointer" style="font-size: 1.5rem;">
<q-popup-proxy>
<q-date v-model="itemsel.begin_test" today-btn/>
</q-popup-proxy>
@@ -184,6 +176,24 @@
</div>
</div>
</template>
<template v-else-if="(whatisSel === tools.WHAT_TODO) && (!!itemtodosel.descr)" v-slot:after>
<div class="q-pa-xs clMain">
<div class="flex-container clMain">
<q-icon class="flex-item flex-icon" name="border_color"/>
<div class="flex-item itemdescr">
<q-input
ref="input"
v-model="itemtodosel.descr"
:label="$t('proj.longdescr')"
outlined
debounce="500"
autogrow
/>
</div>
</div>
</div>
</template>
</q-splitter>
</div>
</q-page>

View File

@@ -0,0 +1 @@
export {default as TodoList} from './todo-list.vue'

View File

@@ -0,0 +1,29 @@
import Vue from 'vue'
import { Component, Watch } from 'vue-property-decorator'
import { CTodo } from '@src/components/todos/CTodo'
import { tools } from '@src/store/Modules/tools'
@Component({
components: { CTodo },
filters: {
capitalize(value) {
return tools.capitalize(value)
}
}
})
export default class TodoList extends Vue {
public categoryAtt: string = ''
@Watch('$route.params.category')
public changecat() {
this.categoryAtt = this.$route.params.category
console.log('this.categoryAtt', this.categoryAtt)
}
public created() {
console.log('LOAD TODO-LIST....')
this.changecat()
}
}

View File

@@ -0,0 +1,12 @@
<template>
<div>
<CTodo :categoryAtt="categoryAtt" :title="categoryAtt">
</CTodo>
</div>
</template>
<script lang="ts" src="./todo-list.ts">
</script>
<style lang="scss" scoped>
@import './todo-list.scss';
</style>

View File

@@ -1 +0,0 @@
export {default as Todo} from './todo.vue'

View File

@@ -1,230 +0,0 @@
import Vue from 'vue'
import { Component, Watch } from 'vue-property-decorator'
import { IDrag, ITodo, ITodosState } from '../../model/index'
import { SingleTodo } from '../../components/todos/SingleTodo/index'
import { tools } from '../../store/Modules/tools'
import * as ApiTables from '../../store/Modules/ApiTables'
import { GlobalStore, Todos } from '@store'
import { UserStore } from '@store'
import { Getter } from 'vuex-class'
const namespace: string = 'Todos'
@Component({
components: { SingleTodo },
filters: {
capitalize(value) {
if (!value) {
return ''
}
value = value.toString()
return value.charAt(0).toUpperCase() + value.slice(1)
}
}
})
export default class Todo extends Vue {
public $q: any
public todotop: string = ''
public todobottom: string = ''
public polling = null
public service: any
public scrollable = true
public categoryAtt: string = ''
public dragname: string = 'first'
public $refs: {
single: SingleTodo[]
}
get tools() {
return tools
}
get showtype() {
return Todos.state.showtype
}
set showtype(value) {
console.log('showtype', value)
GlobalStore.mutations.setShowType(value)
}
get doneTodosCount() {
return Todos.getters.doneTodosCount(this.categoryAtt)
}
get menuPopupConfigTodo() {
return tools.menuPopupConfigTodo[UserStore.state.lang]
}
get listOptionShowTask() {
return tools.listOptionShowTask[UserStore.state.lang]
}
get TodosCount() {
return Todos.getters.TodosCount(this.categoryAtt)
}
@Getter('items_dacompletare', { namespace })
public items_dacompletare: (state: ITodosState, category: string) => ITodo[]
@Getter('todos_completati', { namespace })
public todos_completati: (state: ITodosState, category: string) => ITodo[]
@Watch('$route.params.category')
public changecat() {
this.categoryAtt = this.$route.params.category
}
public showTask(field_value) {
return field_value === tools.MenuAction.SHOW_TASK
}
public async onEndtodo(itemdragend) {
await Todos.actions.swapElems(itemdragend)
}
public created() {
const $service = this.$dragula.$service
tools.dragula_option($service, this.dragname)
$service.eventBus.$on('dragend', (args) => {
const itemdragend: IDrag = {
category: this.categoryAtt,
newIndex: this.getElementIndex(args.el),
oldIndex: this.getElementOldIndex(args.el)
}
this.onEndtodo(itemdragend)
})
$service.eventBus.$on('drag', (el, source) => {
this.scrollable = false
})
$service.eventBus.$on('drop', (el, source) => {
this.scrollable = true
})
this.load()
}
public mounted() {
this.categoryAtt = this.$route.params.category
tools.touchmove(this.scrollable)
}
public async load() {
console.log('LOAD TODO....')
this.categoryAtt = this.$route.params.category
// Set last category selected
localStorage.setItem(tools.localStorage.categorySel, this.categoryAtt)
this.checkUpdate_everytime()
}
// Call to check if need to refresh
public checkUpdate_everytime() {
this.polling = setInterval(() => {
this.checkUpdate()
}, tools.NUMSEC_CHECKUPDATE)
}
public beforeDestroy() {
clearInterval(this.polling)
}
public mydeleteitemtodo(idobj: string) {
// console.log('mydeleteitemtodo', idobj)
return Todos.actions.deleteItemtodo({ cat: this.categoryAtt, idobj })
}
public async dbInsert(atfirst: boolean = false) {
let descr = this.todobottom.trim()
if (atfirst) {
descr = this.todotop.trim()
}
if (descr === '') {
return
}
if (!tools.checkIfUserExist(this)) {
return
}
const myobj: ITodo = {
descr,
category: this.categoryAtt
}
// empty the field
if (atfirst) {
this.todotop = ''
}
else {
this.todobottom = ''
}
return await Todos.actions.dbInsert({ myobj, atfirst })
}
public async updateitemtodo({ myitem, field }) {
console.log('calling MODIFY updateitemtodo', myitem, field)
const itemdragend: IDrag = {
category: this.categoryAtt,
field,
idelemtochange: myitem._id,
prioritychosen: myitem.priority,
atfirst: false
}
await Todos.actions.swapElems(itemdragend)
await Todos.actions.modify({ myitem, field })
}
public deselectAllRowstodo(item: ITodo, check, onlythis: boolean = false) {
// console.log('deselectAllRowstodo : ', item)
for (let i = 0; i < this.$refs.single.length; i++) {
const contr = this.$refs.single[i] as SingleTodo
// @ts-ignore
const id = contr.itemtodo._id
// Don't deselect the actual clicked!
let des = false
if (onlythis) {
des = item._id === id
} else {
des = ((check && (item._id !== id)) || (!check))
}
if (des) {
// @ts-ignore
contr.deselectAndExitEdit()
}
}
}
public checkUpdate() {
ApiTables.waitAndcheckPendingMsg()
}
private getElementIndex(el: any) {
return [].slice.call(el.parentElement.children).indexOf(el)
}
private getElementOldIndex(el: any) {
return parseInt(el.attributes.index.value, 10)
}
}

View File

@@ -1,155 +0,0 @@
<template>
<q-page>
<div class="panel">
<div class="divtitlecat">
<div class="flex-container">
<div class="flex-item categorytitle">{{categoryAtt | capitalize}}</div>
<div class="flex-item">
<q-btn push
size="sm"
icon="settings">
<q-menu id="popconfig" self="top right">
<q-list link separator no-border class="todo-menu">
<q-item clickable v-for="field in menuPopupConfigTodo" :key="field.value">
<q-item-section avatar>
<q-icon :name="field.icon"/>
</q-item-section>
<q-item-section>{{field.label}}</q-item-section>
<q-item-section side v-if="showTask(field.value)">
<q-item-section side>
<q-icon name="keyboard_arrow_right"/>
</q-item-section>
<q-menu auto-close anchor="bottom middle" self="top middle">
<q-list dense>
<q-item side :icon="field.icon">
<q-item-section>
<q-list dense>
<q-item clickable v-ripple v-for="opt in listOptionShowTask"
:key="opt.value"
@click="showtype = opt.value">
<q-item-section avatar>
<q-icon :name="opt.icon" inverted color="primary"/>
</q-item-section>
<q-item-section>
{{opt.label}}
</q-item-section>
</q-item>
</q-list>
</q-item-section>
</q-item>
</q-list>
</q-menu>
</q-item-section>
</q-item>
</q-list>
</q-menu>
</q-btn>
</div>
</div>
</div>
<q-input ref="insertTask" color="blue-12" v-model="todotop" :label="$t('todo.inserttop')"
style="margin-left: 6px;"
:after="[{icon: 'arrow_forward', content: true, handler () {}}]"
v-on:keyup.enter="dbInsert(true)">
<template v-slot:prepend>
<q-icon name="add"/>
</template>
</q-input>
<div style="display: none">{{ prior = 0, priorcomplet = false }}</div>
<div>
<!--<q-infinite-scroll :handler="loadMoreTodo" :offset="7">-->
<div class="container" v-dragula="items_dacompletare(categoryAtt)" :drake="dragname">
<div :id="tools.getmyid(mytodo._id)" :index="index"
v-for="(mytodo, index) in items_dacompletare(categoryAtt)"
:key="mytodo._id" class="myitemdrag">
<div v-if="(prior !== mytodo.priority) && mytodo.status !== tools.Status.COMPLETED"
:class="tools.getTitlePriority(mytodo.priority)">
<label>{{tools.getPriorityByInd(mytodo.priority)}}</label>
</div>
<SingleTodo ref="single" @deleteItemtodo="mydeleteitemtodo(mytodo._id)" @eventupdate="updateitemtodo"
@deselectAllRowstodo="deselectAllRowstodo" @onEnd="onEndtodo"
:itemtodo='mytodo'/>
<!--<div :nametranslate="`REF${index}`" class="divdrag non-draggato"></div>-->
<div style="display: none">{{ prior = mytodo.priority, priorcomplet = (mytodo.status === tools.Status.COMPLETED) }}
</div>
</div>
</div>
<!--</q-infinite-scroll>-->
<div v-if="doneTodosCount > 0" class="titleCompleted">
<label>{{$t('todo.completed')}}</label>
</div>
<!--<q-infinite-scroll :handler="loadMoreTodo" :offset="7">-->
<div class="container">
<div :id="tools.getmyid(mytodo._id)" :index="index"
v-for="(mytodo, index) in todos_completati(categoryAtt)"
:key="mytodo._id" class="myitemdrag">
<SingleTodo ref="single" @deleteItemtodo="mydeleteItemtodo(mytodo._id)" @eventupdate="updateitemtodo"
@deselectAllRows="deselectAllRowstodo" @onEndtodo="onEndtodo"
:itemtodo='mytodo'/>
<!--<div :nametranslate="`REF${index}`" class="divdrag non-draggato"></div>-->
<div style="display: none">{{ prior = mytodo.priority, priorcomplet = (mytodo.status === tools.Status.COMPLETED) }}
</div>
</div>
</div>
<!--</q-infinite-scroll>-->
</div>
<q-input v-if="TodosCount > 0" ref="insertTaskBottom" v-model="todobottom"
style="margin-left: 6px;"
color="blue-12"
:label="$t('todo.insertbottom')"
:after="[{icon: 'arrow_forward', content: true, handler () {}}]"
v-on:keyup.enter="dbInsert(false)"/>
<br>
<!--{{ tmpstrTodos }}-->
<!--<div class="flex-item btn-item">-->
<!--<q-btn class="mybtn" round color="" icon="lock" @click="getArrTodos">Get Todo</q-btn>-->
<!--&lt;!&ndash;<q-btn class="mybtn" round color="" icon="person" @click="setArrTodos">Set Todo</q-btn>&ndash;&gt;-->
<!--&lt;!&ndash;<q-btn class="mybtn" round color="" icon="list" @click="reload_fromServer++">Reload</q-btn>&ndash;&gt;-->
<!--</div>-->
<!--
<!--&lt;!&ndash;<q-input v-model="testPao" float-label="testPao"/>&ndash;&gt;-->
<!--<q-input v-model="todos_changed" float-label="todos_changed"/>-->
<!--<q-input v-model="reload_fromServer" float-label="reload_fromServer"/>-->
<!--<div class="flex-item btn-item">-->
<!--<q-btn class="mybtn" round color="" icon="lock" @click="clicktest()"></q-btn>-->
<!--<q-btn class="mybtn" round color="" icon="person" @click="clicktest2()"></q-btn>-->
<!--<q-btn class="mybtn" round color="" icon="list" @click="checkUpdate()"></q-btn>-->
<!--</div>-->
<!--&ndash;&gt;-->
<!--<q-btn class="mybtn" round color="" icon="lock" @click="clickaggshowtype()"></q-btn>-->
<!--<span style="white-space: pre;">{{ todos_vista }}</span>-->
</div>
</q-page>
</template>
<script lang="ts" src="./todo.ts">
</script>
<style lang="scss" scoped>
@import './todo';
</style>