Calcolo Hours

This commit is contained in:
Paolo Arena
2021-02-11 02:21:36 +01:00
parent 7d0b3fb26f
commit 5568547784
37 changed files with 1372 additions and 574 deletions

View File

@@ -36,6 +36,8 @@ export const shared_consts = {
FILTER_NAVI_NON_PRESENTI: 8192, FILTER_NAVI_NON_PRESENTI: 8192,
FILTER_QUALIFIED: 16384, FILTER_QUALIFIED: 16384,
FILTER_ASK_ZOOM_VISTO: 32768, FILTER_ASK_ZOOM_VISTO: 32768,
FILTER_HOURS_MYLIST: 65536,
FILTER_HOURS_ALL: 131072,
Permissions: { Permissions: {
Admin: { Admin: {

View File

@@ -24,6 +24,7 @@ export default class CDateTime extends Vue {
@Prop({ required: false, default: '' }) public bgcolor!: string @Prop({ required: false, default: '' }) public bgcolor!: string
@Prop({ required: false, default: false }) public dense: boolean @Prop({ required: false, default: false }) public dense: boolean
@Prop({ required: false, default: '5' }) public minuteinterval: boolean @Prop({ required: false, default: '5' }) public minuteinterval: boolean
@Prop({ required: false, default: 'date-time' }) public view: string
public mystyleicon: string = 'font-size: 1.5rem;' public mystyleicon: string = 'font-size: 1.5rem;'
public showDateTimeScroller: boolean = false public showDateTimeScroller: boolean = false
@@ -118,4 +119,12 @@ export default class CDateTime extends Vue {
else else
return '' return ''
} }
public getstrDate(mydate) {
if (this.view === 'date-time') {
return tools.getstrDateTime(mydate)
} else {
return tools.getstrDate(mydate)
}
}
} }

View File

@@ -31,7 +31,7 @@
<template v-slot:control> <template v-slot:control>
<div style=""> <div style="">
<div class="self-center full-width no-outline" :style="mystyle" tabindex="0"> <div class="self-center full-width no-outline" :style="mystyle" tabindex="0">
{{ tools.getstrDateTime(myvalue) }} {{ getstrDate(myvalue) }}
</div> </div>
</div> </div>
</template> </template>
@@ -41,7 +41,7 @@
<q-scroller <q-scroller
v-model="myvalue" v-model="myvalue"
view="date-time" :view="view"
:locale="toolsext.getLocale()" :locale="toolsext.getLocale()"
:rounded-borders="true" :rounded-borders="true"
border-color="#2196f3" border-color="#2196f3"

View File

@@ -12,5 +12,8 @@
} }
.q-table td { .q-table td {
padding: 0; padding-left: 1px;
padding-right: 2px;
padding-top: 0;
padding-bottom: 0;
} }

View File

@@ -23,10 +23,18 @@ export default class CGridTableRec extends Vue {
@Prop({ required: false }) public prop_mytable: string @Prop({ required: false }) public prop_mytable: string
@Prop({ required: false, default: null }) public prop_mycolumns: any[] @Prop({ required: false, default: null }) public prop_mycolumns: any[]
@Prop({ required: false, default: '' }) public prop_colkey: string @Prop({ required: false, default: '' }) public prop_colkey: string
@Prop({ required: false, default: '' }) public prop_codeId: string
@Prop({ required: false, default: '' }) public nodataLabel: string @Prop({ required: false, default: '' }) public nodataLabel: string
@Prop({ required: false, default: '' }) public noresultLabel: string @Prop({ required: false, default: '' }) public noresultLabel: string
@Prop({ required: false, default: {} }) public defaultnewrec: any
@Prop({ required: false, default: null }) public tablesList: ITableRec[] @Prop({ required: false, default: null }) public tablesList: ITableRec[]
@Prop({ required: false, default: null }) public arrfilters: IFilter[] @Prop({ required: false, default: null }) public arrfilters: IFilter[]
@Prop({ required: false, default: [] }) public filterdef: number[]
@Prop({ required: false, default: {} }) public extraparams: any
public newRecordBool: boolean = false
public newRecord: any = {}
public savenewRec: boolean = false
public mytable: string public mytable: string
public mytitle: string public mytitle: string
@@ -57,7 +65,7 @@ export default class CGridTableRec extends Vue {
public separator: 'horizontal' public separator: 'horizontal'
public myfilter = undefined public myfilter = undefined
public myfilterand = [] public myfilterand = []
public rowsel: any public rowsel: any = {}
public dark: boolean = true public dark: boolean = true
public canEdit: boolean = false public canEdit: boolean = false
@@ -71,6 +79,11 @@ export default class CGridTableRec extends Vue {
public selected = [] public selected = []
@Watch('prop_codeId')
public changeprop_codeId() {
this.refresh()
}
get isAdmin() { get isAdmin() {
return UserStore.state.isAdmin return UserStore.state.isAdmin
} }
@@ -158,7 +171,11 @@ export default class CGridTableRec extends Vue {
} }
public annulla(val) { public annulla(val) {
// this.rowclicksel = null console.log('annulla')
GlobalStore.actions.DeleteRec({ table: this.mytable, id: this.newRecord._id })
.then((ris) => {
return true
})
} }
public SaveValue(newVal, valinitial) { public SaveValue(newVal, valinitial) {
@@ -296,16 +313,20 @@ export default class CGridTableRec extends Vue {
myobj[sortBy] = 1 myobj[sortBy] = 1
} }
const params: IParamsQuery = { let params: IParamsQuery = {
table: this.mytable, table: this.mytable,
startRow, startRow,
endRow, endRow,
filter: myfilter, filter: myfilter,
filterand: myfilterand, filterand: myfilterand,
sortBy: myobj, sortBy: myobj,
descending descending,
userId: UserStore.state.my._id,
codeId: this.prop_codeId
} }
params = { ...params, ...this.extraparams }
const data = await GlobalStore.actions.loadTable(params) const data = await GlobalStore.actions.loadTable(params)
if (data) { if (data) {
@@ -372,6 +393,26 @@ export default class CGridTableRec extends Vue {
return this.returnedCount return this.returnedCount
} }
public async createNewRecordDialog() {
const mydata = {
table: this.mytable,
data: {}
}
mydata.data = this.defaultnewrec
// const mykey = fieldsTable.getKeyByTable(this.mytable)
// mydata.data[mykey] = ''
const data = await GlobalStore.actions.saveTable(mydata)
this.newRecord = data
this.newRecordBool = true
}
public async createNewRecord() { public async createNewRecord() {
this.loading = true this.loading = true
@@ -380,6 +421,8 @@ export default class CGridTableRec extends Vue {
data: {} data: {}
} }
mydata.data = this.defaultnewrec
// const mykey = fieldsTable.getKeyByTable(this.mytable) // const mykey = fieldsTable.getKeyByTable(this.mytable)
// mydata.data[mykey] = '' // mydata.data[mykey] = ''
@@ -412,6 +455,7 @@ export default class CGridTableRec extends Vue {
this.canEdit = tools.getCookie(tools.CAN_EDIT, this.canEdit) === 'true' this.canEdit = tools.getCookie(tools.CAN_EDIT, this.canEdit) === 'true'
this.tablesel = tools.getCookie('tablesel', this.tablesel) this.tablesel = tools.getCookie('tablesel', this.tablesel)
} }
this.myfilterand = this.filterdef
console.log('this.tablesel', this.tablesel) console.log('this.tablesel', this.tablesel)
if (this.tablesel === '') { if (this.tablesel === '') {
@@ -592,9 +636,11 @@ export default class CGridTableRec extends Vue {
else else
return '' return ''
} }
public getSelectedString() { public getSelectedString() {
return this.selected.length === 0 ? '' : `${this.selected.length} record${this.selected.length > 1 ? 's' : ''} selected of ${this.serverData.length}` return this.selected.length === 0 ? '' : `${this.selected.length} record${this.selected.length > 1 ? 's' : ''} selected of ${this.serverData.length}`
} }
public selectionclick(details) { public selectionclick(details) {
// console.log('selectionclick this.selected', this.selected, 'details', details) // console.log('selectionclick this.selected', this.selected, 'details', details)
if (details.added) { if (details.added) {
@@ -622,4 +668,30 @@ export default class CGridTableRec extends Vue {
public changemyfilterand() { public changemyfilterand() {
this.refresh() this.refresh()
} }
public async saveNewRecord() {
console.log('saveNewRecord')
this.savenewRec = true
const mydata = {
table: this.mytable,
data: {}
}
mydata.data = this.newRecord
const data = await GlobalStore.actions.saveTable(mydata)
.then((ris) => {
if (ris) {
// console.log('ris', ris)
this.newRecordBool = false
}
})
}
public hidewindow() {
console.log('hidewindow')
if (!this.savenewRec) {
this.annulla(0)
}
}
} }

View File

@@ -1,5 +1,8 @@
<template> <template>
<div class="q-pa-xs"> <div class="q-pa-xs">
<q-btn v-if="mytable" flat dense color="primary"
:label="$t('grid.addrecord')"
@click="createNewRecordDialog"></q-btn>
<q-table <q-table
@@ -54,16 +57,17 @@
</q-input> </q-input>
<q-toggle v-if="mytable" v-model="canEdit" :disable="disabilita" :val="lists.MenuAction.CAN_EDIT_TABLE" <q-toggle v-if="mytable" v-model="canEdit" :disable="disabilita" :val="lists.MenuAction.CAN_EDIT_TABLE"
class="q-mx-sm" class="q-mx-sm"
:label="$t('grid.editvalues')" @input="changefuncAct" :label="$t('grid.editvalues')" @input="changefuncAct">
></q-toggle> </q-toggle>
<q-btn v-if="mytable" flat dense color="primary" :disable="loading || !canEdit" <q-btn v-if="mytable" flat dense color="primary" :disable="loading || !canEdit"
:label="$t('grid.addrecord')" :label="$t('grid.addrecord')"
@click="createNewRecord"></q-btn> @click="createNewRecord">
</q-btn>
<q-space/> <q-space/>
<!--<q-toggle v-for="(mycol, index) in mycolumns" v-model="colVisib" :val="rec.field" :label="mycol.label"></q-toggle>--> <!--<q-toggle v-for="(mycol, index) in mycolumns" v-model="colVisib" :val="rec.field" :label="mycol.label"></q-toggle>-->
<q-select <q-select
@@ -102,11 +106,14 @@
</q-inner-loading> </q-inner-loading>
<div class="row"> <div class="row">
<q-toggle v-for="(filter, index) of arrfilters" :key="index" v-model="myfilterand" :val="filter.value" <q-toggle v-for="(filter, index) of arrfilters"
:label="filter.label"></q-toggle> :key="index"
v-model="myfilterand" :disable="filter.hide"
:val="filter.value"
:label="filter.label">
</q-toggle>
</div> </div>
</template> </template>
<template v-slot:body="props"> <template v-slot:body="props">
@@ -141,6 +148,7 @@
</q-td> </q-td>
</q-tr> </q-tr>
</template> </template>
<!-- <!--
<q-btn <q-btn
flat round dense flat round dense
@@ -169,7 +177,7 @@
<div class="q-ma-xs"> <div class="q-ma-xs">
<q-field rounded outlined bg-color="orange-3" dense> <q-field rounded outlined bg-color="orange-3" dense>
<template v-slot:control> <template v-slot:control>
<div class="self-center full-width no-outline" tabindex="0">{{mycol.label}}</div> <div class="self-center full-width no-outline" tabindex="0">{{ mycol.label }}</div>
</template> </template>
</q-field> </q-field>
</div> </div>
@@ -193,11 +201,45 @@
</div> </div>
</div> </div>
</div> </div>
<q-dialog v-model="newRecordBool" @hide="hidewindow">
<q-card :style="`min-width: `+ tools.myheight_dialog() + `px;`">
<q-toolbar class="bg-primary text-white">
<q-toolbar-title>
{{ mytitle }}
</q-toolbar-title>
<q-btn flat round color="white" icon="close" v-close-popup></q-btn>
</q-toolbar>
<q-card-section class="inset-shadow">
<div v-for="col in mycolumns" :key="col.name"
v-if="colVisib.includes(col.field + col.subfield)">
<div>
<CMyPopupEdit :canEdit="true"
:col="col"
:row.sync="newRecord"
:field="col.field"
:subfield="col.subfield"
minuteinterval="1"
:visulabel="true"
@save="SaveValue"
@show="selItem(newRecord, col)"
@showandsave="showandsel">
</CMyPopupEdit>
</div>
</div>
</q-card-section>
<q-card-actions align="center">
<q-btn flat :label="$t('dialog.ok')" color="primary" @click="saveNewRecord"></q-btn>
<q-btn flat :label="$t('dialog.cancel')" color="primary" v-close-popup @click="annulla"></q-btn>
</q-card-actions>
</q-card>
</q-dialog>
</div> </div>
</template> </template>
<script lang="ts" src="./CGridTableRec.ts"> <script lang="ts" src="./CGridTableRec.ts">
</script> </script>
<style lang="scss"> <style lang="scss">
@import './CGridTableRec.scss'; @import './CGridTableRec.scss';
</style> </style>

View File

87
src/components/CHours/CHours.ts Executable file
View File

@@ -0,0 +1,87 @@
import Vue from 'vue'
import { Component, Prop, Watch } from 'vue-property-decorator'
import { colTableHours } from '@src/store/Modules/fieldsTable'
import { CCard, CGridTableRec, CMyPage, CTitleBanner, CImgText } from '@components'
import MixinBase from '@src/mixins/mixin-base'
import { shared_consts } from '@src/common/shared_vuejs'
import { UserStore } from '@store'
@Component({
name: 'CHours',
mixins: [MixinBase],
components: { CImgText, CCard, CMyPage, CTitleBanner, CGridTableRec }
})
export default class CHours extends MixinBase {
@Prop({ required: true }) public todoId: string
public pagination = {
sortBy: 'descr',
descending: false,
page: 2,
rowsPerPage: 5
// rowsNumber: xx if getting data from a server
}
get extraparams() {
return {
lk_tab: 'users',
lk_LF: 'userId',
lk_FF: '_id',
lk_as: 'user',
lk_proj: {
todoId: 1, userId: 1, descr: 1, date: 1, time_start: 1, time_end: 1, hours: 1,
username: 1, name: 1, surname: 1
}
}
}
public arrfilterand = [
{
label: 'Tutte le ore',
value: shared_consts.FILTER_HOURS_ALL
}
]
get myfilterdef() {
return [shared_consts.FILTER_HOURS_MYLIST]
}
get myarrfilterand() {
const myfiltrodef = {
label: 'Mie Ore',
value: shared_consts.FILTER_HOURS_MYLIST,
hide: true,
default: true
}
let myarr = []
myarr.push(myfiltrodef)
if (this.arrfilterand)
myarr = [...myarr, ...this.arrfilterand]
console.log('myarr', myarr)
return myarr
}
public selected = []
public dataPages = []
get getcolHours() {
return colTableHours
}
get defaultnewrec() {
const myrec = {
todoId: this.todoId,
userId: UserStore.state.my._id,
descr: ''
}
return myrec
}
}

View File

@@ -0,0 +1,33 @@
<template>
<div>
<span>{{ setmeta({
title: 'Lista Ore',
description: "",
keywords: '' } ) }}
</span>
<div class="q-ma-sm q-gutter-sm q-pa-xs">
<CTitleBanner title="Lista Ore"></CTitleBanner>
<CGridTableRec prop_mytable="hours"
prop_mytitle="Lista Ore"
:prop_mycolumns="getcolHours"
prop_colkey="descr"
nodataLabel="Nessuna Lista Ore"
noresultLabel="Il filtro selezionato non ha trovato nessun risultato"
:arrfilters="myarrfilterand"
:filterdef="myfilterdef"
:prop_codeId="todoId"
:defaultnewrec="defaultnewrec"
:extraparams="extraparams"
>
</CGridTableRec>
</div>
</div>
</template>
<script lang="ts" src="./CHours.ts">
</script>
<style lang="scss" scoped>
@import 'CHours.scss';
</style>

1
src/components/CHours/index.ts Executable file
View File

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

View File

34
src/components/CInput/CInput.ts Executable file
View File

@@ -0,0 +1,34 @@
import Vue from 'vue'
import { Component, Prop } from 'vue-property-decorator'
import { GlobalStore, UserStore } from '@store'
import VueScrollReveal from 'vue-scroll-reveal'
import { tools } from '@src/store/Modules/tools'
import { toolsext } from '@src/store/Modules/toolsext'
import { Screen } from 'quasar'
@Component({
name: 'CInput'
})
export default class CInput extends Vue {
@Prop({ required: false, default: '' }) public src: string
@Prop({ required: false, default: '' }) public src2: string
@Prop({ required: false, default: 'myclimg' }) public class1: string
@Prop({ required: false, default: '' }) public style1: string
@Prop({ required: false, default: 'image' }) public alt1: string
@Prop({ required: false, default: 'image' }) public alt2: string
get clrowcol() {
let mycl = 'row'
if (tools.isMobile())
mycl = 'column'
return mycl
}
get myclass() {
return this.clrowcol + ' items-start q-col-gutter-xs imgtext '
}
}

View File

@@ -0,0 +1,11 @@
<template>
<div>
<q-field
</div>
</template>
<script lang="ts" src="./CInput.ts">
</script>
<style lang="scss" scoped>
@import './CInput.scss';
</style>

1
src/components/CInput/index.ts Executable file
View File

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

View File

@@ -13,10 +13,11 @@ import { GlobalStore, UserStore } from '../../store/Modules'
import { CMyChipList } from '../CMyChipList' import { CMyChipList } from '../CMyChipList'
import { CMyToggleList } from '../CMyToggleList' import { CMyToggleList } from '../CMyToggleList'
import translate from '@src/globalroutines/util' import translate from '@src/globalroutines/util'
import { CDateTime } from '../CDateTime'
@Component({ @Component({
name: 'CMyFieldDb', name: 'CMyFieldDb',
components: { CMyEditor, CMySelect, CMyChipList, CMyToggleList } components: { CMyEditor, CMySelect, CMyChipList, CMyToggleList, CDateTime }
}) })
export default class CMyFieldDb extends MixinBase { export default class CMyFieldDb extends MixinBase {
@@ -29,6 +30,8 @@ export default class CMyFieldDb extends MixinBase {
@Prop({ required: false, default: '' }) public jointable: string @Prop({ required: false, default: '' }) public jointable: string
@Prop({ required: false, default: 'settings' }) public table: string @Prop({ required: false, default: 'settings' }) public table: string
@Prop({ required: false, default: '' }) public myimg: string @Prop({ required: false, default: '' }) public myimg: string
@Prop({ required: false, default: '' }) public id: string
@Prop({ required: false, default: '' }) public idmain: string
public $t public $t
public myvalue = '' public myvalue = ''
@@ -37,18 +40,28 @@ export default class CMyFieldDb extends MixinBase {
public countryname = '' public countryname = ''
public created() { public created() {
this.myvalue = this.getValDb(this.mykey, this.serv, '', this.table, this.mysubkey) this.crea()
}
public crea() {
this.myvalue = this.getValDb(this.mykey, this.serv, '', this.table, this.mysubkey, this.id, this.idmain)
this.col.jointable = this.jointable this.col.jointable = this.jointable
this.col.fieldtype = this.type this.col.fieldtype = this.type
this.col.label = this.title this.col.label = this.title
// console.log('created', this.myvalue) // console.log('CMyFieldDb crea', this.myvalue)
}
@Watch('id')
public idchanged(value) {
this.crea()
} }
public getclassCol(col) { public getclassCol(col) {
if (col) { if (col) {
let mycl = (this.disable || col.disable) ? '' : 'colmodif ' let mycl = (this.disable || col.disable) ? '' : 'colmodif '
mycl += (col.fieldtype === tools.FieldType.date) ? ' coldate flex flex-container ' : '' mycl += ((col.fieldtype === tools.FieldType.date) || (col.fieldtype === tools.FieldType.onlydate)) ? ' coldate flex flex-container ' : ''
return mycl return mycl
} else { } else {
@@ -63,6 +76,12 @@ export default class CMyFieldDb extends MixinBase {
} else { } else {
return tools.getstrDateTime(val) return tools.getstrDateTime(val)
} }
} else if (this.col.fieldtype === tools.FieldType.onlydate) {
if (val === undefined) {
return '[]'
} else {
return tools.getstrDate(val)
}
} else if (this.col.fieldtype === tools.FieldType.boolean) { } else if (this.col.fieldtype === tools.FieldType.boolean) {
return (val) ? this.$t('dialog.yes') : this.$t('dialog.no') return (val) ? this.$t('dialog.yes') : this.$t('dialog.no')
} else if (this.col.fieldtype === tools.FieldType.binary) { } else if (this.col.fieldtype === tools.FieldType.binary) {
@@ -120,7 +139,7 @@ export default class CMyFieldDb extends MixinBase {
public savefield(value, initialval) { public savefield(value, initialval) {
this.myvalue = value this.myvalue = value
this.setValDb(this.mykey, this.myvalue, this.type, this.serv, this.table, this.mysubkey) this.setValDb(this.mykey, this.myvalue, this.type, this.serv, this.table, this.mysubkey, this.id)
} }
public savefieldboolean(value) { public savefieldboolean(value) {
@@ -129,10 +148,10 @@ export default class CMyFieldDb extends MixinBase {
else else
this.myvalue = value this.myvalue = value
this.setValDb(this.mykey, this.myvalue, this.type, this.serv, this.table, this.mysubkey) this.setValDb(this.mykey, this.myvalue, this.type, this.serv, this.table, this.mysubkey, this.id)
} }
public selectcountry({name, iso2, dialCode}) { public selectcountry({ name, iso2, dialCode }) {
// console.log(name, iso2, dialCode) // console.log(name, iso2, dialCode)
this.myvalue = iso2 this.myvalue = iso2
this.countryname = name this.countryname = name

View File

@@ -31,6 +31,18 @@
> >
</CDateTime> </CDateTime>
</div> </div>
<div v-else-if="type === tools.FieldType.onlydate">
<CDateTime
:label="col.label"
class="cursor-pointer"
:value.sync="myvalue"
:readonly="false"
:dense="true"
:canEdit="canEdit"
view="date"
>
</CDateTime>
</div>
<div v-else :class="mycl"> <div v-else :class="mycl">
<div v-if="type === tools.FieldType.binary"> <div v-if="type === tools.FieldType.binary">
<CMyChipList <CMyChipList

View File

@@ -6,6 +6,7 @@ import { toolsext } from '@src/store/Modules/toolsext'
import { IColGridTable } from '../../model' import { IColGridTable } from '../../model'
import { fieldsTable } from '../../store/Modules/fieldsTable' import { fieldsTable } from '../../store/Modules/fieldsTable'
import { CMyChipList } from '../CMyChipList' import { CMyChipList } from '../CMyChipList'
import { CDate } from '../CDate'
import { CDateTime } from '../CDateTime' import { CDateTime } from '../CDateTime'
import { CMyToggleList } from '../CMyToggleList' import { CMyToggleList } from '../CMyToggleList'
import { CMySelect } from '../CMySelect' import { CMySelect } from '../CMySelect'
@@ -14,7 +15,7 @@ import { CGallery } from '../CGallery'
@Component({ @Component({
name: 'CMyPopupEdit', name: 'CMyPopupEdit',
components: { CMyChipList, CDateTime, CMyToggleList, CMySelect, CMyEditor, CGallery } components: { CMyChipList, CDateTime, CDate, CMyToggleList, CMySelect, CMyEditor, CGallery }
}) })
export default class CMyPopupEdit extends Vue { export default class CMyPopupEdit extends Vue {
@@ -27,11 +28,12 @@ export default class CMyPopupEdit extends Vue {
@Prop({ required: false, default: 'row' }) public view @Prop({ required: false, default: 'row' }) public view
@Prop({ required: false, default: '5' }) public minuteinterval @Prop({ required: false, default: '5' }) public minuteinterval
@Prop({ required: false, default: false }) public disable @Prop({ required: false, default: false }) public disable
@Prop({ required: false, default: false }) public visulabel
public myvalue = '' public myvalue = ''
public myvalueprec = 'false' public myvalueprec = 'false'
public countryname = '' public countryname = ''
public visueditor : boolean = false public visueditor: boolean = false
get tools() { get tools() {
return tools return tools
@@ -50,6 +52,14 @@ export default class CMyPopupEdit extends Vue {
this.$emit('update:row', newval) this.$emit('update:row', newval)
} }
public changevalRec(newval) {
console.log('this.row', this.row, 'this.col', this.col, 'newval', newval)
console.log('this.row[this.col.name]', this.row[this.col.name])
this.row[this.col.name] = newval
console.log('changevalRec update:row', newval)
this.$emit('update:row', this.row)
}
public updatedata() { public updatedata() {
this.mounted() this.mounted()
} }
@@ -161,6 +171,12 @@ export default class CMyPopupEdit extends Vue {
} else { } else {
return tools.getstrDateTime(val) return tools.getstrDateTime(val)
} }
} else if (col.fieldtype === tools.FieldType.onlydate) {
if (val === undefined) {
return '[]'
} else {
return tools.getstrDate(val)
}
} else if (col.fieldtype === tools.FieldType.boolean) { } else if (col.fieldtype === tools.FieldType.boolean) {
return (val) ? this.$t('dialog.yes') : this.$t('dialog.no') return (val) ? this.$t('dialog.yes') : this.$t('dialog.no')
} else if (col.fieldtype === tools.FieldType.binary) { } else if (col.fieldtype === tools.FieldType.binary) {
@@ -201,10 +217,14 @@ export default class CMyPopupEdit extends Vue {
} }
} }
public visInNewRec(col) {
return !col.notShowInNewRec
}
public getclassCol(col) { public getclassCol(col) {
if (col) { if (col) {
let mycl = (col.disable || this.isviewfield) ? '' : 'colmodif' let mycl = (col.disable || this.isviewfield) ? '' : 'colmodif'
mycl += (col.fieldtype === tools.FieldType.date) ? ' coldate flex flex-container' : '' mycl += ((col.fieldtype === tools.FieldType.date) || (col.fieldtype === tools.FieldType.onlydate)) ? ' coldate flex flex-container' : ''
return mycl return mycl
} else { } else {

View File

@@ -1,30 +1,67 @@
<template> <template>
<div :class="getclassCol(col)"> <div :class="getclassCol(col)">
<div v-if="col.fieldtype === tools.FieldType.listimages"> <div v-if="visulabel" class="flex">
<CGallery :gall="row" :listimages="myvalue" :edit="isviewfield" <div v-if="visInNewRec(col)" style="flex-grow: 1;">
@showandsave="Savedb"> <div v-if="col.fieldtype === tools.FieldType.string">
<q-input v-model="myvalue"
autogrow
@keyup.enter.stop
@input="changevalRec"
autofocus
:label="col.label">
</q-input>
</div>
<div v-if="col.fieldtype === tools.FieldType.date">
<CDateTime
:label="col.label"
class="cursor-pointer"
:valueDate="myvalue"
:readonly="false"
:minuteinterval="minuteinterval"
:dense="true"
@input="changevalRec"
canEdit="true"
@savetoclose="SaveValueInt"
@show="OpenEdit">
</CDateTime>
</div>
<div v-else-if="col.fieldtype === tools.FieldType.number">
<q-input v-model="myvalue" type="number"
autofocus
@input="changevalRec"
:label="col.label"
>
</CGallery> </q-input>
</div> </div>
<div v-else-if="col.fieldtype === tools.FieldType.image">
<CGallery :gall="row" :listimages="myvalue" :edit="isviewfield"
@showandsave="Savedb">
</CGallery>
</div>
<div v-else-if="col.fieldtype === tools.FieldType.nationality">
<div>
{{myvalue}}
</div>
</div>
<div v-else-if="col.fieldtype === tools.FieldType.intcode">
<div>
{{myvalue}}
</div> </div>
</div> </div>
<div v-else> <div v-else>
<!-- Edit Value --> <div v-if="col.fieldtype === tools.FieldType.listimages">
<span v-if="col.fieldtype === tools.FieldType.date"> <CGallery :gall="row" :listimages="myvalue" :edit="isviewfield"
@showandsave="Savedb">
</CGallery>
</div>
<div v-else-if="col.fieldtype === tools.FieldType.image">
<CGallery :gall="row" :listimages="myvalue" :edit="isviewfield"
@showandsave="Savedb">
</CGallery>
</div>
<div v-else-if="col.fieldtype === tools.FieldType.nationality">
<div>
{{ myvalue }}
</div>
</div>
<div v-else-if="col.fieldtype === tools.FieldType.intcode">
<div>
{{ myvalue }}
</div>
</div>
<div v-else>
<!-- Edit Value -->
<span v-if="col.fieldtype === tools.FieldType.date">
<CDateTime <CDateTime
:label="col.label" :label="col.label"
class="cursor-pointer" class="cursor-pointer"
@@ -37,174 +74,188 @@
@show="OpenEdit"> @show="OpenEdit">
</CDateTime> </CDateTime>
</span> </span>
<div v-if="col.fieldtype !== tools.FieldType.date"> <span v-else-if="col.fieldtype === tools.FieldType.onlydate">
<div> <CDateTime
<div v-if="col.fieldtype === tools.FieldType.binary"> :label="col.label"
<CMyChipList class="cursor-pointer"
:type="tools.FieldType.binary" :valueDate="myvalue"
:value="myvalue" :readonly="false"
:options="db_fieldsTable.getTableJoinByName(col.jointable)" :minuteinterval="minuteinterval"
:optval="db_fieldsTable.getKeyByTable(col.jointable)" :dense="true"
:optlab="db_fieldsTable.getLabelByTable(col.jointable)" :canEdit="canEdit"
:opticon="db_fieldsTable.getIconByTable(col.jointable)"></CMyChipList> @savetoclose="SaveValueInt"
</div> @show="OpenEdit"
<!-- Show Value --> view="date">
<div v-else-if="col.fieldtype === tools.FieldType.multiselect"> </CDateTime>
<CMyChipList </span>
:type="tools.FieldType.multiselect" <div v-else>
:value="myvalue" <div>
:options="db_fieldsTable.getTableJoinByName(col.jointable)" <div v-if="col.fieldtype === tools.FieldType.binary">
:optval="db_fieldsTable.getKeyByTable(col.jointable)" <CMyChipList
:optlab="db_fieldsTable.getLabelByTable(col.jointable)" :type="tools.FieldType.binary"
:opticon="db_fieldsTable.getIconByTable(col.jointable)"></CMyChipList> :value="myvalue"
</div> :options="db_fieldsTable.getTableJoinByName(col.jointable)"
<div v-else-if="col.fieldtype === tools.FieldType.select"> :optval="db_fieldsTable.getKeyByTable(col.jointable)"
<CMyChipList :optlab="db_fieldsTable.getLabelByTable(col.jointable)"
myclass="text-center" :opticon="db_fieldsTable.getIconByTable(col.jointable)"></CMyChipList>
:type="tools.FieldType.select"
:value="myvalue"
:options="db_fieldsTable.getTableJoinByName(col.jointable)"
:optval="db_fieldsTable.getKeyByTable(col.jointable)"
:optlab="db_fieldsTable.getLabelByTable(col.jointable)"
:opticon="db_fieldsTable.getIconByTable(col.jointable)"></CMyChipList>
</div>
<div v-else-if="col.fieldtype === tools.FieldType.boolean">
<q-toggle dark color="green" v-model="myvalue" :label="col.title"
:disable="disable && col.name !== 'profile.saw_zoom_presentation'"
@input="Savedb"></q-toggle>
</div>
<div v-else-if="col.fieldtype === tools.FieldType.html">
<div v-html="visuValByType(myvalue, col, row)" @click="visueditor = true">
</div> </div>
</div> <!-- Show Value -->
<div v-else> <div v-else-if="col.fieldtype === tools.FieldType.multiselect">
{{ visuValByType(myvalue, col, row) }} <CMyChipList
</div> :type="tools.FieldType.multiselect"
:value="myvalue"
<div v-if="col.fieldtype === tools.FieldType.html"> :options="db_fieldsTable.getTableJoinByName(col.jointable)"
:optval="db_fieldsTable.getKeyByTable(col.jointable)"
<CMyEditor v-if="visueditor" :value.sync="myvalue" :title="col.title" @keyup.enter.stop :optlab="db_fieldsTable.getLabelByTable(col.jointable)"
@showandsave="Savedb" @annulla="visueditor=false"> :opticon="db_fieldsTable.getIconByTable(col.jointable)"></CMyChipList>
</CMyEditor>
</div>
<q-popup-edit
v-if="canEdit && col.fieldtype !== tools.FieldType.html"
v-model="myvalue"
:disable="col.disable"
:title="col.title"
buttons
persistent
@save="SaveValueInt"
@show="OpenEdit">
<div v-if="col.fieldtype === tools.FieldType.boolean">
<q-checkbox v-model="myvalue" :label="col.title">
</q-checkbox>
{{ visuValByType(myvalue, col, row) }}
</div>
<div v-else-if="col.fieldtype === tools.FieldType.string">
<q-input v-model="myvalue"
autogrow
@keyup.enter.stop
autofocus>
</q-input>
</div>
<div v-else-if="col.fieldtype === tools.FieldType.password">
<q-input v-model="myvalue"
type="password"
@keyup.enter.stop
autofocus>
</q-input>
</div>
<div v-else-if="col.fieldtype === tools.FieldType.number">
<q-input v-model="myvalue" type="number"
autofocus>
</q-input>
</div>
<div v-else-if="col.fieldtype === tools.FieldType.binary">
<CMyToggleList :label="col.title"
:options="db_fieldsTable.getTableJoinByName(col.jointable)"
:value.sync="myvalue"
:optval="db_fieldsTable.getKeyByTable(col.jointable)"
:optlab="db_fieldsTable.getLabelByTable(col.jointable)">
</CMyToggleList>
</div> </div>
<div v-else-if="col.fieldtype === tools.FieldType.select"> <div v-else-if="col.fieldtype === tools.FieldType.select">
<CMySelect :label="col.title" <CMyChipList
:value.sync="myvalue" myclass="text-center"
:optval="db_fieldsTable.getKeyByTable(col.jointable)" :type="tools.FieldType.select"
:optlab="db_fieldsTable.getLabelByTable(col.jointable)" :value="myvalue"
:options="db_fieldsTable.getTableJoinByName(col.jointable)" :options="db_fieldsTable.getTableJoinByName(col.jointable)"
:useinput="false"> :optval="db_fieldsTable.getKeyByTable(col.jointable)"
</CMySelect> :optlab="db_fieldsTable.getLabelByTable(col.jointable)"
:opticon="db_fieldsTable.getIconByTable(col.jointable)"></CMyChipList>
</div> </div>
<div v-else-if="col.fieldtype === tools.FieldType.nationality"> <div v-else-if="col.fieldtype === tools.FieldType.boolean">
<div class="justify-center q-gutter-sm clgutter q-mt-sm"> <q-toggle dark color="green" v-model="myvalue" :label="col.title"
<q-input :disable="disable && col.name !== 'profile.saw_zoom_presentation'"
v-model="countryname" @input="Savedb"></q-toggle>
:readonly="true" </div>
rounded dense <div v-else-if="col.fieldtype === tools.FieldType.html">
debounce="1000" <div v-html="visuValByType(myvalue, col, row)" @click="visueditor = true">
>
<template v-slot:prepend>
<div style="font-size: 1rem;">
<vue-country-code
:defaultCountry="myvalue"
:disabledFetchingCountry="true"
@onSelect="selectcountry"
:preferredCountries="tools.getprefCountries"
:dropdownOptions="{ disabledDialCode: true }">
</vue-country-code>
</div>
</template>
</q-input>
<div style="height: 180px;">
</div>
</div> </div>
</div> </div>
<div v-else-if="col.fieldtype === tools.FieldType.intcode"> <div v-else>
{{ visuValByType(myvalue, col, row) }}
<vue-tel-input
@country-changed="intcode_change"
v-model="myvalue"
:placeholder="$t('reg.cell')"
:enabledCountryCode="true"
inputClasses="clCell"
wrapperClasses="clCellCode">
</vue-tel-input>
</div>
<div v-else-if="col.fieldtype === tools.FieldType.multiselect">
<div>join: {{col.jointable}}</div>
<q-select
v-model="myvalue"
rounded
outlined
multiple
dense
options-dense
:display-value="db_fieldsTable.getTitleByTable(col.jointable)"
emit-value
map-options
:options="db_fieldsTable.getTableJoinByName(col.jointable)"
:option-label="db_fieldsTable.getLabelByTable(col.jointable)"
:option-value="db_fieldsTable.getKeyByTable(col.jointable)"
style="min-width: 150px"
@input="changeCol">
</q-select>
</div> </div>
</q-popup-edit> <div v-if="col.fieldtype === tools.FieldType.html">
<CMyEditor v-if="visueditor" :value.sync="myvalue" :title="col.title" @keyup.enter.stop
@showandsave="Savedb" @annulla="visueditor=false">
</CMyEditor>
</div>
<q-popup-edit
v-if="canEdit && col.fieldtype !== tools.FieldType.html"
v-model="myvalue"
:disable="col.disable"
:title="col.title"
buttons
persistent
@save="SaveValueInt"
@show="OpenEdit">
<div v-if="col.fieldtype === tools.FieldType.boolean">
<q-checkbox v-model="myvalue" :label="col.title">
</q-checkbox>
{{ visuValByType(myvalue, col, row) }}
</div>
<div v-else-if="col.fieldtype === tools.FieldType.string">
<q-input v-model="myvalue"
autogrow
@keyup.enter.stop
autofocus>
</q-input>
</div>
<div v-else-if="col.fieldtype === tools.FieldType.password">
<q-input v-model="myvalue"
type="password"
@keyup.enter.stop
autofocus>
</q-input>
</div>
<div v-else-if="col.fieldtype === tools.FieldType.number">
<q-input v-model="myvalue" type="number"
autofocus>
</q-input>
</div>
<div v-else-if="col.fieldtype === tools.FieldType.binary">
<CMyToggleList :label="col.title"
:options="db_fieldsTable.getTableJoinByName(col.jointable)"
:value.sync="myvalue"
:optval="db_fieldsTable.getKeyByTable(col.jointable)"
:optlab="db_fieldsTable.getLabelByTable(col.jointable)">
</CMyToggleList>
</div>
<div v-else-if="col.fieldtype === tools.FieldType.select">
<CMySelect :label="col.title"
:value.sync="myvalue"
:optval="db_fieldsTable.getKeyByTable(col.jointable)"
:optlab="db_fieldsTable.getLabelByTable(col.jointable)"
:options="db_fieldsTable.getTableJoinByName(col.jointable)"
:useinput="false">
</CMySelect>
</div>
<div v-else-if="col.fieldtype === tools.FieldType.nationality">
<div class="justify-center q-gutter-sm clgutter q-mt-sm">
<q-input
v-model="countryname"
:readonly="true"
rounded dense
debounce="1000"
>
<template v-slot:prepend>
<div style="font-size: 1rem;">
<vue-country-code
:defaultCountry="myvalue"
:disabledFetchingCountry="true"
@onSelect="selectcountry"
:preferredCountries="tools.getprefCountries"
:dropdownOptions="{ disabledDialCode: true }">
</vue-country-code>
</div>
</template>
</q-input>
<div style="height: 180px;">
</div>
</div>
</div>
<div v-else-if="col.fieldtype === tools.FieldType.intcode">
<vue-tel-input
@country-changed="intcode_change"
v-model="myvalue"
:placeholder="$t('reg.cell')"
:enabledCountryCode="true"
inputClasses="clCell"
wrapperClasses="clCellCode">
</vue-tel-input>
</div>
<div v-else-if="col.fieldtype === tools.FieldType.multiselect">
<div>join: {{ col.jointable }}</div>
<q-select
v-model="myvalue"
rounded
outlined
multiple
dense
options-dense
:display-value="db_fieldsTable.getTitleByTable(col.jointable)"
emit-value
map-options
:options="db_fieldsTable.getTableJoinByName(col.jointable)"
:option-label="db_fieldsTable.getLabelByTable(col.jointable)"
:option-value="db_fieldsTable.getKeyByTable(col.jointable)"
style="min-width: 150px"
@input="changeCol">
</q-select>
</div>
</q-popup-edit>
</div>
</div> </div>
</div> </div>
</div> </div>
@@ -215,5 +266,5 @@
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
@import './CMyPopupEdit.scss'; @import './CMyPopupEdit.scss';
</style> </style>

View File

@@ -41,6 +41,7 @@ export default class CMyToggleList extends Vue {
} }
public mounted() { public mounted() {
console.log('mounted')
this.myarrvalues = [] this.myarrvalues = []
// console.log('value', this.value) // console.log('value', this.value)
@@ -50,11 +51,28 @@ export default class CMyToggleList extends Vue {
if (this.isarray) { if (this.isarray) {
// console.table(this.options) // console.table(this.options)
this.options.forEach((rec) => { this.options.forEach((rec) => {
console.log('rec: ', rec) console.log('rec: ', rec, 'optval', this.optval, 'optlab', this.optlab)
const mydata = { const mydata = {
label: this.$t(rec[this.optlab]), label: '',
value: rec[this.optval], value: rec[this.optval],
valbool: this.value.includes(rec[this.optval]) valbool: false
}
const lab = rec[`${this.optlab}`]
console.log('lab', lab)
if (tools.isObject(this.optlab)) {
const arr = this.options.filter((myrec) => myrec[this.optval] === mydata.value).map(this.optlab)
if (arr) {
// @ts-ignore
mydata.label = arr[0]
}
} else {
mydata.label = this.$t(rec[this.optlab])
}
if (this.value) {
mydata.valbool = this.value.includes(rec[this.optval])
} }
console.log('mydata ', mydata) console.log('mydata ', mydata)
this.myarrvalues.push(mydata) this.myarrvalues.push(mydata)

View File

@@ -12,9 +12,23 @@ $heightBtn: 100%;
.cpr-progrbar-item { .cpr-progrbar-item {
//height: 10px //height: 10px
margin-top: 11px; margin-top: 8px;
margin-bottom: 11px; margin-bottom: 8px;
height:15px; height:10px;
}
@media (max-width: 600px) {
.cpr-progrbar-item {
//height: 10px
margin-top: 6px;
margin-bottom: 6px;
height: 8px;
}
.progress-item {
padding-top: 2px;
padding-bottom: 2px;
}
} }
.cpr-slider-item { .cpr-slider-item {

View File

@@ -40,7 +40,7 @@ export default class CProgress extends Vue {
get getdescr() { get getdescr() {
if (!!this.descr) { if (!!this.descr) {
return this.descr + ' : ' return this.descr + ': '
} }
} }

View File

@@ -48,7 +48,8 @@ export default class CShareWithUs extends MixinBase {
filter: '', filter: '',
filterand: '', filterand: '',
sortBy: myobj, sortBy: myobj,
descending descending,
userId: UserStore.state.my._id
} }
console.log('myload', params) console.log('myload', params)

View File

@@ -16,6 +16,7 @@ export * from './CMyPopupEdit'
export * from './CMyToggleList' export * from './CMyToggleList'
export * from './CMyChipList' export * from './CMyChipList'
export * from './CMyEditor' export * from './CMyEditor'
export * from './CInput'
export * from './CMyFieldDb' export * from './CMyFieldDb'
export * from './CMyTeacher' export * from './CMyTeacher'
export * from './CImgText' export * from './CImgText'
@@ -64,4 +65,5 @@ export * from './CECommerce'
export * from './CSingleCart' export * from './CSingleCart'
export * from './CMyCart' export * from './CMyCart'
export * from './CShareWithUs' export * from './CShareWithUs'
export * from './CHours'
export * from '../views/ecommerce/' export * from '../views/ecommerce/'

View File

@@ -260,12 +260,12 @@ export default class SingleProject extends Vue {
this.$emit('deselectAllRowstodo', null, false) this.$emit('deselectAllRowstodo', null, false)
this.$emit('deselectAllRowsproj', this.itemproject, true) this.$emit('deselectAllRowsproj', this.itemproject, true)
if (!this.sel) { // if (!this.sel) {
this.selectRiga() this.selectRiga()
} else { // } else {
this.$emit('deselectAllRowsproj', null, false, false, true) // this.$emit('deselectAllRowsproj', null, false, false, true)
this.deselectRiga() // this.deselectRiga()
} // }
} }
} }

View File

@@ -229,12 +229,12 @@ export default class SingleTodo extends Vue {
this.$emit('deselectAllRowsproj', null, false, false) this.$emit('deselectAllRowsproj', null, false, false)
this.$emit('deselectAllRowstodo', this.itemtodo, true) this.$emit('deselectAllRowstodo', this.itemtodo, true)
if (!this.sel) { // if (!this.sel) {
this.selectRiga() this.selectRiga()
} else { // } else {
this.$emit('deselectAllRowsproj', null, false, false, true) // this.$emit('deselectAllRowsproj', null, false, false, true)
this.deselectRiga() // this.deselectRiga()
} // }
} }
} }

View File

@@ -42,9 +42,9 @@ export default class MixinBase extends MixinMetaTags {
return shared_consts return shared_consts
} }
public getValDb(keystr, serv, def?, table?, subkey?, id?) { public getValDb(keystr, serv, def?, table?, subkey?, id?, idmain?) {
return tools.getValDb(keystr, serv, def, table, subkey, id) return tools.getValDb(keystr, serv, def, table, subkey, id, idmain)
} }
public getValDbLang(keystr, serv, def?, table?, subkey?) { public getValDbLang(keystr, serv, def?, table?, subkey?) {
@@ -61,7 +61,7 @@ export default class MixinBase extends MixinMetaTags {
if (table === 'users') { if (table === 'users') {
const myid = UserStore.state.my._id const myid = UserStore.state.my._id
let myfield = {} const myfield = {}
if (key === 'profile') { if (key === 'profile') {
UserStore.state.my.profile[subkey] = value UserStore.state.my.profile[subkey] = value
@@ -84,6 +84,25 @@ export default class MixinBase extends MixinMetaTags {
fieldsvalue: myfield fieldsvalue: myfield
} }
} else if (table === 'todos') {
const myfield = {}
// Save to the DB:
if (subkey) {
myfield[key + '.' + subkey] = value
} else {
myfield[key] = value
}
// console.log('myfield', myfield)
mydatatosave = {
id,
table,
fieldsvalue: myfield
}
} else if (table === 'settings') { } else if (table === 'settings') {
GlobalStore.mutations.setValueSettingsByKey({ key, value, serv }) GlobalStore.mutations.setValueSettingsByKey({ key, value, serv })
@@ -95,7 +114,7 @@ export default class MixinBase extends MixinMetaTags {
type type
} }
myrec.serv = serv myrec.serv = serv
if (myrec.type === tools.FieldType.date) if ((myrec.type === tools.FieldType.date) || (myrec.type === tools.FieldType.onlydate))
myrec.value_date = value myrec.value_date = value
else if (myrec.type === tools.FieldType.number) else if (myrec.type === tools.FieldType.number)
myrec.value_num = value myrec.value_num = value

View File

@@ -52,6 +52,13 @@ export interface ITeachUname {
username?: string username?: string
} }
export interface IResp {
_id?: string
username?: string
name?: string
surname?: string
}
export interface IMyPage { export interface IMyPage {
_id?: string _id?: string
author_username?: string author_username?: string
@@ -183,6 +190,8 @@ export interface IGlobalState {
departments: IDepartment[], departments: IDepartment[],
sharewithus: IShareWithUs[], sharewithus: IShareWithUs[],
groups: IGroup[], groups: IGroup[],
resps: IResp[],
workers: IResp[],
autoplaydisc: number autoplaydisc: number
} }
@@ -366,6 +375,14 @@ export interface IParamsQuery {
filterand: string filterand: string
sortBy: any sortBy: any
descending: number descending: number
userId: string
codeId?: string
lk_tab?: string,
lk_LF?: string,
lk_FF?: string,
lk_as?: string,
lk_proj?: string,
lk_col2?: string,
} }
export interface IColGridTable { export interface IColGridTable {
@@ -388,6 +405,7 @@ export interface IColGridTable {
jointable?: string jointable?: string
resultjoin?: string[] resultjoin?: string[]
visuonlyEditVal?: boolean visuonlyEditVal?: boolean
notShowInNewRec?: boolean
} }
export interface ITableRec { export interface ITableRec {
@@ -404,6 +422,8 @@ export interface ITableRec {
export interface IFilter { export interface IFilter {
label: string label: string
value: string value: string
hide?: boolean
default?: boolean
} }
export interface IDataPass { export interface IDataPass {

View File

@@ -57,3 +57,14 @@ export interface ITodosState {
insidePending: boolean insidePending: boolean
visuLastCompleted: number visuLastCompleted: number
} }
export interface IHours {
_id?: any,
userId?: string
descr?: string,
todoId?: string,
date?: Date,
time_start: number
time_end: number
hours: number
}

View File

@@ -417,6 +417,8 @@ const msg_it = {
non_verificato: "Non Verificato", non_verificato: "Non Verificato",
forgetpassword: "Password dimenticata?", forgetpassword: "Password dimenticata?",
modificapassword: "Modifica Password", modificapassword: "Modifica Password",
resplist: 'Possibile Responsabile',
workerslist: 'Lavoratore Attivo',
resp: "Responsabile", resp: "Responsabile",
viceResp: "Vice Rrsponsabile", viceResp: "Vice Rrsponsabile",
userslist: "Lista Persone", userslist: "Lista Persone",
@@ -501,6 +503,8 @@ const msg_it = {
completed_at: 'Data Completamento', completed_at: 'Data Completamento',
expiring_at: 'Data Scadenza', expiring_at: 'Data Scadenza',
phase: 'Fase', phase: 'Fase',
assigned_to_userId: 'Assegnato a',
workers: 'Partecipanti Attivi'
}, },
notification: { notification: {
status: 'Stato', status: 'Stato',
@@ -530,7 +534,7 @@ const msg_it = {
hoursworked: 'Ore Lavorate', hoursworked: 'Ore Lavorate',
begin_development: 'Inizio Sviluppo', begin_development: 'Inizio Sviluppo',
begin_test: 'Inizio Test', begin_test: 'Inizio Test',
progresstask: 'Progressione', progresstask: 'Progr',
actualphase: 'Fase Attuale', actualphase: 'Fase Attuale',
hoursweeky_plannedtowork: 'Ore settimanali previste', hoursweeky_plannedtowork: 'Ore settimanali previste',
endwork_estimate: 'Data fine lavori stimata', endwork_estimate: 'Data fine lavori stimata',
@@ -539,7 +543,9 @@ const msg_it = {
totalphases: 'Totale Fasi', totalphases: 'Totale Fasi',
themecolor: 'Tema Colore', themecolor: 'Tema Colore',
themebgcolor: 'Tema Colore Sfondo', themebgcolor: 'Tema Colore Sfondo',
group: 'Gruppo' group: 'Gruppo',
respUsername: 'Responsabile',
viceRespUsername: 'Vice Responsabile'
}, },
where: { where: {
code: 'Id', code: 'Id',

View File

@@ -84,6 +84,8 @@ const state: IGlobalState = {
calzoom: [], calzoom: [],
producers: [], producers: [],
groups: [], groups: [],
resps: [],
workers: [],
storehouses: [], storehouses: [],
departments: [], departments: [],
sharewithus: [] sharewithus: []
@@ -208,6 +210,10 @@ namespace Getters {
return GlobalStore.state.storehouses return GlobalStore.state.storehouses
else if (table === 'groups') else if (table === 'groups')
return GlobalStore.state.groups return GlobalStore.state.groups
else if (table === 'resps')
return GlobalStore.state.resps
else if (table === 'workers')
return GlobalStore.state.workers
else if (table === 'departments') else if (table === 'departments')
return GlobalStore.state.departments return GlobalStore.state.departments
else if (table === 'sharewithus') else if (table === 'sharewithus')
@@ -239,7 +245,7 @@ namespace Getters {
const myrec = getters.getrecSettingsByKey(key, serv) const myrec = getters.getrecSettingsByKey(key, serv)
if (!!myrec) { if (!!myrec) {
if (myrec.type === tools.FieldType.date) if ((myrec.type === tools.FieldType.date) || (myrec.type === tools.FieldType.onlydate))
return myrec.value_date return myrec.value_date
else if (myrec.type === tools.FieldType.number) else if (myrec.type === tools.FieldType.number)
return myrec.value_num return myrec.value_num
@@ -431,7 +437,7 @@ namespace Mutations {
myrec = mystate.settings.find((rec) => rec.key === key) myrec = mystate.settings.find((rec) => rec.key === key)
if (!!myrec) { if (!!myrec) {
if (myrec.type === tools.FieldType.date) if ((myrec.type === tools.FieldType.date) || (myrec.type === tools.FieldType.onlydate))
myrec.value_date = value myrec.value_date = value
else if (myrec.type === tools.FieldType.number) else if (myrec.type === tools.FieldType.number)
myrec.value_num = value myrec.value_num = value
@@ -1098,6 +1104,8 @@ namespace Actions {
GlobalStore.state.producers = (res.data.producers) ? [...res.data.producers] : [] GlobalStore.state.producers = (res.data.producers) ? [...res.data.producers] : []
GlobalStore.state.storehouses = (res.data.storehouses) ? [...res.data.storehouses] : [] GlobalStore.state.storehouses = (res.data.storehouses) ? [...res.data.storehouses] : []
GlobalStore.state.groups = (res.data.groups) ? [...res.data.groups] : [] GlobalStore.state.groups = (res.data.groups) ? [...res.data.groups] : []
GlobalStore.state.resps = (res.data.resps) ? [...res.data.resps] : []
GlobalStore.state.workers = (res.data.workers) ? [...res.data.workers] : []
GlobalStore.state.departments = (res.data.departments) ? [...res.data.departments] : [] GlobalStore.state.departments = (res.data.departments) ? [...res.data.departments] : []
// console.log('res.data.cart', res.data.cart) // console.log('res.data.cart', res.data.cart)
if (res.data.cart) if (res.data.cart)
@@ -1197,7 +1205,7 @@ namespace Actions {
infooter: page.infooter, infooter: page.infooter,
onlyif_logged: page.onlyif_logged, onlyif_logged: page.onlyif_logged,
level_child: page.l_child, level_child: page.l_child,
level_parent: page.l_par, level_parent: page.l_par
}) })
} }
} }
@@ -1232,9 +1240,16 @@ namespace Actions {
} }
// Sort array // Sort array
static_data.routes = static_data.routes.sort((a, b) => a.order - b.order) static_data.routes = static_data.routes.sort((a, myb) => a.order - myb.order)
if (tools.sito_online(false)) { if (tools.sito_online(false)) {
router.addRoutes([...arrpagesroute, last])
} else {
router.addRoutes([sito_offline, last])
this.$router.replace('/sito_offline')
}
/* if (tools.sito_online(false)) {
for (const r of arrpagesroute) { for (const r of arrpagesroute) {
router.addRoute(r) router.addRoute(r)
} }
@@ -1245,7 +1260,8 @@ namespace Actions {
router.addRoute(last) router.addRoute(last)
// router.addRoutes([sito_offline, last]) // router.addRoutes([sito_offline, last])
this.$router.replace('/sito_offline') this.$router.replace('/sito_offline')
} }*/
} }
async function sendFile(context, formdata) { async function sendFile(context, formdata) {

View File

@@ -331,6 +331,24 @@ namespace Actions {
ApiTables.aftercalling(ris, checkPending, nametable) ApiTables.aftercalling(ris, checkPending, nametable)
} }
async function calculateHoursProjects(context, { projId, actualphase }) {
let ris = null
ris = await Api.SendReq('/projects/calc/' + projId + '/' + actualphase, 'GET', null)
.then((res) => {
if (res.data.rec) { // console.log('RISULTANTE CATEGORIES DAL SERVER = ', res.data.categories)
return res.data.rec
}
return null
})
.catch((error) => {
console.log('error calculateHoursProjects', error)
})
return ris
}
async function deleteItem(context, { idobj }) { async function deleteItem(context, { idobj }) {
console.log('deleteItem: KEY = ', idobj) console.log('deleteItem: KEY = ', idobj)
@@ -452,6 +470,7 @@ namespace Actions {
export const actions = { export const actions = {
dbLoad: b.dispatch(dbLoad), dbLoad: b.dispatch(dbLoad),
calculateHoursProjects: b.dispatch(calculateHoursProjects),
swapElems: b.dispatch(swapElems), swapElems: b.dispatch(swapElems),
deleteItem: b.dispatch(deleteItem), deleteItem: b.dispatch(deleteItem),
dbInsert: b.dispatch(dbInsert), dbInsert: b.dispatch(dbInsert),

View File

@@ -304,6 +304,24 @@ namespace Actions {
return ris return ris
} }
async function calculateHoursTodo(context, { todoId }) {
let ris = null
ris = await Api.SendReq('/todos/calc/' + todoId, 'GET', null)
.then((res) => {
if (res.data.rec) { // console.log('RISULTANTE CATEGORIES DAL SERVER = ', res.data.categories)
return res.data.rec
}
return null
})
.catch((error) => {
console.log('error calculateHoursTodo', error)
})
return ris
}
async function deleteItemtodo(context, { cat, idobj }) { async function deleteItemtodo(context, { cat, idobj }) {
console.log('deleteItemtodo: KEY = ', idobj) console.log('deleteItemtodo: KEY = ', idobj)
@@ -465,6 +483,7 @@ namespace Actions {
export const actions = { export const actions = {
dbLoad: b.dispatch(dbLoad), dbLoad: b.dispatch(dbLoad),
calculateHoursTodo: b.dispatch(calculateHoursTodo),
swapElems: b.dispatch(swapElems), swapElems: b.dispatch(swapElems),
deleteItemtodo: b.dispatch(deleteItemtodo), deleteItemtodo: b.dispatch(deleteItemtodo),
dbInsert: b.dispatch(dbInsert), dbInsert: b.dispatch(dbInsert),

View File

@@ -49,7 +49,8 @@ function AddCol(params: IColGridTable) {
fieldtype: (params.fieldtype === undefined) ? tools.FieldType.string : params.fieldtype, fieldtype: (params.fieldtype === undefined) ? tools.FieldType.string : params.fieldtype,
visuonlyEditVal: (params.visuonlyEditVal === undefined) ? false : params.visuonlyEditVal, visuonlyEditVal: (params.visuonlyEditVal === undefined) ? false : params.visuonlyEditVal,
askaction: (params.askaction === undefined) ? '' : params.askaction, askaction: (params.askaction === undefined) ? '' : params.askaction,
jointable: (params.jointable === undefined) ? '' : params.jointable jointable: (params.jointable === undefined) ? '' : params.jointable,
notShowInNewRec: (params.notShowInNewRec === undefined) ? false : params.notShowInNewRec
} }
} }
@@ -188,6 +189,20 @@ export const colTableShareWithUs = [
AddCol({ name: 'numshared', label_trans: 'share.numshared', fieldtype: tools.FieldType.number }), AddCol({ name: 'numshared', label_trans: 'share.numshared', fieldtype: tools.FieldType.number }),
AddCol({ name: 'rating', label_trans: 'share.rating', fieldtype: tools.FieldType.number }), AddCol({ name: 'rating', label_trans: 'share.rating', fieldtype: tools.FieldType.number }),
] ]
export const colTableHours = [
// AddCol({ name: 'userId', label_trans: 'hours.userId' }),
// AddCol({ name: 'todoId', label_trans: 'hours.todoId' }),
AddCol({ name: 'descr', label_trans: 'hours.descr' }),
AddCol({ name: 'username', label_trans: 'reg.username_short', notShowInNewRec: true }),
AddCol({ name: 'date', label_trans: 'hours.date', fieldtype: tools.FieldType.onlydate }),
AddCol({ name: 'time_start', label_trans: 'hours.time_start', fieldtype: tools.FieldType.number }),
AddCol({ name: 'time_end', label_trans: 'hours.time_end', fieldtype: tools.FieldType.number }),
AddCol({ name: 'hours', label_trans: 'hours.hours', fieldtype: tools.FieldType.number }),
AddCol(DeleteRec),
AddCol(DuplicateRec)
]
export const colTablegroups = [ export const colTablegroups = [
AddCol({ name: 'descr', label_trans: 'share.description' }), AddCol({ name: 'descr', label_trans: 'share.description' }),
AddCol({ name: 'resp', label_trans: 'reg.resp' }), AddCol({ name: 'resp', label_trans: 'reg.resp' }),
@@ -268,6 +283,14 @@ const colpaymenttype = [
AddCol(DeleteRec) AddCol(DeleteRec)
] ]
const colworkers = [
AddCol({ name: '_id', label_trans: 'others.value' }),
AddCol({ name: 'username', label_trans: 'reg.username' }),
AddCol({ name: 'name', label_trans: 'reg.name' }),
AddCol({ name: 'surname', label_trans: 'reg.surname' }),
AddCol(DeleteRec)
]
const colflotte = [ const colflotte = [
AddCol({ name: 'index', label_trans: 'others.value' }), AddCol({ name: 'index', label_trans: 'others.value' }),
AddCol({ name: 'riga', label_trans: 'reg.riga' }), AddCol({ name: 'riga', label_trans: 'reg.riga' }),
@@ -639,6 +662,20 @@ export const fieldsTable = {
AddCol({ name: 'surname', label_trans: 'reg.surname' }), AddCol({ name: 'surname', label_trans: 'reg.surname' }),
AddCol({ name: 'email', label_trans: 'reg.email' }), AddCol({ name: 'email', label_trans: 'reg.email' }),
AddCol({ name: 'verified_email', label_trans: 'reg.verified_email', fieldtype: tools.FieldType.boolean }), AddCol({ name: 'verified_email', label_trans: 'reg.verified_email', fieldtype: tools.FieldType.boolean }),
AddCol({
name: 'profile.resplist',
field: 'profile',
subfield: 'resplist',
label_trans: 'reg.resplist',
fieldtype: tools.FieldType.boolean
}),
AddCol({
name: 'profile.workerslist',
field: 'profile',
subfield: 'workerslist',
label_trans: 'reg.workerslist',
fieldtype: tools.FieldType.boolean
}),
AddCol({ name: 'profile.teleg_id', field: 'profile', subfield: 'teleg_id', label_trans: 'reg.teleg_id' }), AddCol({ name: 'profile.teleg_id', field: 'profile', subfield: 'teleg_id', label_trans: 'reg.teleg_id' }),
AddCol({ AddCol({
name: 'profile.saw_and_accepted', name: 'profile.saw_and_accepted',
@@ -793,6 +830,20 @@ export const fieldsTable = {
AddCol({ name: 'note', label_trans: 'reg.note' }), AddCol({ name: 'note', label_trans: 'reg.note' }),
// AddCol({ name: 'aportador_solidario', label_trans: 'reg.aportador_solidario' }), // AddCol({ name: 'aportador_solidario', label_trans: 'reg.aportador_solidario' }),
AddCol({ name: 'verified_email', label_trans: 'reg.verified_email', fieldtype: tools.FieldType.boolean }), AddCol({ name: 'verified_email', label_trans: 'reg.verified_email', fieldtype: tools.FieldType.boolean }),
AddCol({
name: 'profile.resplist',
field: 'profile',
subfield: 'resplist',
label_trans: 'reg.resplist',
fieldtype: tools.FieldType.boolean
}),
AddCol({
name: 'profile.workerslist',
field: 'profile',
subfield: 'workerslist',
label_trans: 'reg.workerslist',
fieldtype: tools.FieldType.boolean
}),
AddCol({ AddCol({
name: 'profile.special_req', name: 'profile.special_req',
field: 'profile', field: 'profile',
@@ -1012,6 +1063,13 @@ export const fieldsTable = {
colkey: 'key', colkey: 'key',
collabel: 'label' collabel: 'label'
}, },
{
value: 'workers',
label: 'Lavoratori Attivi',
columns: colworkers,
colkey: '_id',
collabel: (rec) => rec.name + ' ' + rec.surname
},
{ {
value: 'navi', value: 'navi',
label: 'Navi', label: 'Navi',

View File

@@ -187,7 +187,8 @@ export const tools = {
image: 2048, image: 2048,
nationality: 4096, nationality: 4096,
intcode: 5000, intcode: 5000,
multioption: 6000 multioption: 6000,
onlydate: 7000
}, },
FieldTypeArr: [ FieldTypeArr: [
@@ -2148,6 +2149,14 @@ export const tools = {
return UserStore.state.my.profile.socioresidente return UserStore.state.my.profile.socioresidente
}, },
isResp() {
return UserStore.state.my.profile.resplist
},
isWorkers() {
return UserStore.state.my.profile.workerslist
},
isDepartment() { isDepartment() {
return UserStore.state.isDepartment return UserStore.state.isDepartment
}, },
@@ -3478,13 +3487,29 @@ export const tools = {
return splitStr.join(' ') return splitStr.join(' ')
}, },
getValDb(keystr, serv, def?, table?, subkey?, id?) { getValDb(keystr, serv, def?, table?, subkey?, id?, idmain?) {
if (table === 'users') { if (table === 'users') {
if (keystr === 'profile') { if (keystr === 'profile') {
return UserStore.state.my.profile[subkey] return UserStore.state.my.profile[subkey]
} else { } else {
return UserStore.state.my[keystr] return UserStore.state.my[keystr]
} }
} else if (table === 'todos') {
// console.log('id', id, 'idmain', idmain)
const indcat = Todos.state.categories.indexOf(idmain)
console.log('indcat', indcat)
if (indcat >= 0) {
const myrec = Todos.state.todos[indcat].find((rec) => rec._id === id)
console.log('myrec', myrec)
let ris = null
if (myrec) {
ris = myrec[keystr]
}
console.log('ris', ris)
return ris
}
return ''
} else { } else {
const ris = GlobalStore.getters.getValueSettingsByKey(keystr, serv) const ris = GlobalStore.getters.getValueSettingsByKey(keystr, serv)
@@ -4029,6 +4054,54 @@ export const tools = {
} }
return mylist
},
getRespList() {
// console.log('GlobalStore.state.groups', GlobalStore.state.groups)
const mylist = {
it: [],
es: [],
enUs: []
}
let myrec = {}
for (const myresp of GlobalStore.state.resps) {
myrec = {
id: myresp._id,
label: myresp.name + ' ' + myresp.surname,
value: myresp.username
}
mylist.it.push(myrec)
}
return mylist
},
getWorkersList() {
// console.log('GlobalStore.state.groups', GlobalStore.state.groups)
const mylist = {
it: [],
es: [],
enUs: []
}
let myrec = {}
for (const myresp of GlobalStore.state.workers) {
myrec = {
id: myresp._id,
label: myresp.name + ' ' + myresp.surname,
value: myresp.username
}
mylist.it.push(myrec)
}
return mylist return mylist
} }

View File

@@ -9,7 +9,7 @@ $heightBtn: 100%;
} }
.flex-container, .flex-container_col{ .flex-container, .flex-container_col {
background-color: rgb(250, 250, 250); background-color: rgb(250, 250, 250);
padding: 2px 4px 2px 4px; padding: 2px 4px 2px 4px;
margin: 2px; margin: 2px;
@@ -19,10 +19,30 @@ $heightBtn: 100%;
justify-content: space-between; justify-content: space-between;
} }
.q-tab-panel {
padding: 8px;
}
.flex-container_col { .flex-container_col {
flex-direction: column; flex-direction: column;
} }
@media (max-width: 600px) {
.flex-item {
padding: 1px;
margin: 1px;
}
.flex-container {
margin: 0;
padding: 0;
}
.q-tab-panel {
padding: 4px;
}
}
.mycard { .mycard {
visibility: hidden; visibility: hidden;
@@ -38,11 +58,11 @@ $heightBtn: 100%;
transition: all .4s; transition: all .4s;
} }
.titlePriority, .titleCompleted{ .titlePriority, .titleCompleted {
border-width: 0px 0px 1px 0px; border-width: 0px 0px 1px 0px;
border-style: solid; border-style: solid;
border-color: #ccc; border-color: #ccc;
color:white; color: white;
} }
.titleCompleted { .titleCompleted {
@@ -62,7 +82,6 @@ $heightBtn: 100%;
} }
.myitemdrag-enter, .myitemdrag-leave-active { .myitemdrag-enter, .myitemdrag-leave-active {
opacity: 0; opacity: 0;
} }
@@ -76,8 +95,8 @@ $heightBtn: 100%;
} }
.categorytitle{ .categorytitle {
color:blue; color: blue;
background-color: lightblue; background-color: lightblue;
font-size: 1.25rem !important; font-size: 1.25rem !important;
font-weight: bold; font-weight: bold;
@@ -85,7 +104,7 @@ $heightBtn: 100%;
flex: 1; flex: 1;
} }
.projecttitle{ .projecttitle {
color: white; color: white;
// color:blue; // color:blue;
background-color: rgba(65, 152, 239, 0.6); background-color: rgba(65, 152, 239, 0.6);
@@ -95,20 +114,20 @@ $heightBtn: 100%;
flex: 1; flex: 1;
} }
.itemdescr{ .itemdescr {
font-size: 1rem; font-size: 1rem;
flex: 1; flex: 1;
} }
.itemstatus{ .itemstatus {
flex: 1; flex: 1;
padding: 2px; padding: 2px;
} }
.itemdata{ .itemdata {
font-size: 1rem; font-size: 1rem;
flex: 1; flex: 1;
padding: 2px; padding: 1px;
} }
.progress-item { .progress-item {
@@ -126,7 +145,7 @@ $heightBtn: 100%;
height: 10px; height: 10px;
} }
.flex-icon{ .flex-icon {
padding: 3px; padding: 3px;
font-size: 1.5rem; font-size: 1.5rem;
} }
@@ -155,7 +174,7 @@ $heightBtn: 100%;
} }
} }
.divdrag{ .divdrag {
animation: fadeIn 0.2s ease-in 1 forwards; animation: fadeIn 0.2s ease-in 1 forwards;
min-height: 50px; min-height: 50px;
background-color: #9f9f9f; background-color: #9f9f9f;

View File

@@ -11,20 +11,20 @@ import { lists } from '../../../store/Modules/lists'
import * as ApiTables from '../../../store/Modules/ApiTables' import * as ApiTables from '../../../store/Modules/ApiTables'
import { GlobalStore, Projects, Todos } from '@store' import { GlobalStore, Projects, Todos } from '@store'
import { UserStore } from '@store'
import { Getter } from 'vuex-class' import { Getter } from 'vuex-class'
import { date, Screen } from 'quasar' import { date, Screen } from 'quasar'
import { CProgress } from '../../../components/CProgress' import { CProgress } from '../../../components/CProgress'
import { CDate } from '../../../components/CDate' import { CDate } from '../../../components/CDate'
import { RouteNames } from '@src/router/route-names' import { CMyFieldDb } from '../../../components/CMyFieldDb'
import { CHours } from '../../../components/CHours'
const namespace: string = 'Projects' const namespace: string = 'Projects'
@Component({ @Component({
components: { SingleProject, CProgress, CTodo, CDate }, components: { SingleProject, CProgress, CTodo, CDate, CMyFieldDb, CHours },
filters: { filters: {
capitalize(value) { capitalize(value) {
if (!value) { if (!value) {
@@ -38,7 +38,7 @@ const namespace: string = 'Projects'
export default class ProjList extends Vue { export default class ProjList extends Vue {
public tabproj: string = 'info' public tabproj: string = 'lista'
get classTitle() { get classTitle() {
let cl = 'flex-item categorytitle shadow-4' let cl = 'flex-item categorytitle shadow-4'
@@ -171,6 +171,7 @@ export default class ProjList extends Vue {
return Math.round(this.itemselproj.hoursworked / this.itemselproj.hoursplanned * 100) return Math.round(this.itemselproj.hoursworked / this.itemselproj.hoursplanned * 100)
} }
get getCalcHoursLeft() { get getCalcHoursLeft() {
if (this.itemselproj.hoursleft <= 0) { if (this.itemselproj.hoursleft <= 0) {
@@ -246,6 +247,7 @@ export default class ProjList extends Vue {
else else
return '' return ''
} }
public $q: any public $q: any
public projbottom: string = '' public projbottom: string = ''
public prova: string = '' public prova: string = ''
@@ -270,6 +272,8 @@ export default class ProjList extends Vue {
public selectPhase: any[] = tools.selectPhase[toolsext.getLocale()] public selectPhase: any[] = tools.selectPhase[toolsext.getLocale()]
public selectPrivacy: any[] = tools.selectPrivacy[toolsext.getLocale()] public selectPrivacy: any[] = tools.selectPrivacy[toolsext.getLocale()]
public selectGroup: any[] = [] public selectGroup: any[] = []
public selectResp: any[] = []
public selectWorkers: any[] = []
public $refs: { public $refs: {
singleproject: SingleProject[], singleproject: SingleProject[],
@@ -286,6 +290,7 @@ export default class ProjList extends Vue {
@Watch('$route.name') @Watch('$route.name')
public changename() { public changename() {
// console.log('tools.getUrlByTipoProj(this.tipoProj)', tools.getUrlByTipoProj(this.tipoProj)) // console.log('tools.getUrlByTipoProj(this.tipoProj)', tools.getUrlByTipoProj(this.tipoProj))
this.changeparent() this.changeparent()
} }
@@ -303,6 +308,45 @@ export default class ProjList extends Vue {
this.updateclasses() this.updateclasses()
} }
@Watch('itemselproj._id')
public changeidproj() {
this.aggiornastat()
}
@Watch('tabproj')
public changetabproj() {
this.aggiornastat()
}
@Watch('itemtodosel._id')
public changeidtodo() {
this.aggiornastat()
}
public aggiornastat() {
if (this.tabproj === 'stat') {
if (!!this.itemselproj) {
Projects.actions.calculateHoursProjects({
projId: this.itemselproj._id,
actualphase: this.itemselproj.actualphase
})
.then((rec) => {
if (rec) {
this.itemselproj.hoursworked = rec.hoursworked
}
})
} else if (!!this.itemtodosel) {
Todos.actions.calculateHoursTodo({ todoId: this.itemtodosel._id })
.then((rec) => {
if (rec) {
this.itemtodosel.hoursworked = rec.hoursworked
}
})
}
}
}
public keyDownArea(e) { public keyDownArea(e) {
// console.log('keyDownArea') // console.log('keyDownArea')
} }
@@ -386,6 +430,8 @@ export default class ProjList extends Vue {
} }
this.selectGroup = tools.getGroupList()[toolsext.getLocale()] this.selectGroup = tools.getGroupList()[toolsext.getLocale()]
this.selectResp = tools.getRespList()[toolsext.getLocale()]
this.selectWorkers = tools.getWorkersList()[toolsext.getLocale()]
console.log('this.selectGroup', this.selectGroup) console.log('this.selectGroup', this.selectGroup)
@@ -518,6 +564,7 @@ export default class ProjList extends Vue {
public setidsel(id: string) { public setidsel(id: string) {
this.idsel = id this.idsel = id
this.whatisSel = tools.WHAT_PROJECT this.whatisSel = tools.WHAT_PROJECT
this.itemtodosel = null
this.itemselproj = Projects.getters.getRecordById(this.idsel) this.itemselproj = Projects.getters.getRecordById(this.idsel)
if ((this.itemselproj === undefined || this.itemselproj === null)) if ((this.itemselproj === undefined || this.itemselproj === null))
this.whatisSel = tools.WHAT_NOTHING this.whatisSel = tools.WHAT_NOTHING
@@ -526,12 +573,12 @@ export default class ProjList extends Vue {
this.checkiftoenable() this.checkiftoenable()
} }
public setitemsel(item: ITodo) { public setitemsel(item: ITodo) {
this.itemselproj = null
this.itemtodosel = item this.itemtodosel = item
if (item !== null) if (item !== null)
this.whatisSel = tools.WHAT_TODO this.whatisSel = tools.WHAT_TODO
else
this.whatisSel = tools.WHAT_NOTHING
this.checkiftoenable() this.checkiftoenable()
} }
@@ -576,7 +623,7 @@ export default class ProjList extends Vue {
// @ts-ignore // @ts-ignore
for (const i in this.$refs.ctodo.$refs.single) { for (const i in this.$refs.ctodo.$refs.single) {
// @ts-ignore // @ts-ignore
const contr = this.$refs.ctodo.$refs.single[i] as SingleTodo const contr = this.$refs.ctodo.$refs.single[i] as SingleTodo
let des = true let des = true
if (check) { if (check) {
@@ -644,7 +691,7 @@ export default class ProjList extends Vue {
if (!!this.itemselproj) { if (!!this.itemselproj) {
this.colProgress = tools.getProgressColor(this.itemselproj.progressCalc) this.colProgress = tools.getProgressColor(this.itemselproj.progressCalc)
} else { } else {
this.whatisSel = tools.WHAT_NOTHING // this.whatisSel = tools.WHAT_NOTHING
} }
} }
@@ -677,8 +724,7 @@ export default class ProjList extends Vue {
} // expand_less } // expand_less
else if (this.itemtodosel.priority === tools.Priority.PRIORITY_NORMAL) { else if (this.itemtodosel.priority === tools.Priority.PRIORITY_NORMAL) {
iconpriority = 'remove' iconpriority = 'remove'
} } else if (this.itemtodosel.priority === tools.Priority.PRIORITY_LOW) {
else if (this.itemtodosel.priority === tools.Priority.PRIORITY_LOW) {
iconpriority = 'expand_more' iconpriority = 'expand_more'
} // expand_more } // expand_more

View File

@@ -1,14 +1,37 @@
<template> <template>
<q-page> <q-page>
<div class="panel"> <div class="panel">
<q-splitter <q-tabs
v-model="tabproj"
dense
class="bg-blue text-white shadow-2"
indicator-color="white"
align="center"
>
<q-tab name="lista" icon="fas fa-list-alt" :label="$t('gallery.list')"></q-tab>
<q-tab name="info" icon="fas fa-check" :label="$t('dashboard.info')" :disable="!whatisSel"></q-tab>
<q-tab v-if="(whatisSel === tools.WHAT_TODO) && (!!itemtodosel.descr)" name="ore" icon="fas fa-chart-line" :label="$t('pages.hours')" :disable="!whatisSel"></q-tab>
<q-tab name="stat" icon="fas fa-chart-line" :label="$t('pages.status')" :disable="!whatisSel"></q-tab>
</q-tabs>
<!--<q-splitter
v-model="splitterModel" v-model="splitterModel"
:horizontal="isHorizontal" :horizontal="isHorizontal"
:style="myStyle" :style="myStyle"
:limits="[50, 100]" :limits="[50, 100]"
>
<template v-slot:before> <template v-slot:before>
>-->
<div v-if="(whatisSel === tools.WHAT_PROJECT) && (!!itemselproj.descr)">
</div>
<div v-else-if="(whatisSel === tools.WHAT_TODO) && (!!itemtodosel.descr)" name="info">
</div>
<q-tab-panels v-model="tabproj" animated>
<q-tab-panel name="lista">
<div> <div>
<!-- idProjAtt: {{ idProjAtt }} --> <!-- idProjAtt: {{ idProjAtt }} -->
<div class="divtitlecat clMain"> <div class="divtitlecat clMain">
@@ -129,338 +152,375 @@
</CTodo> </CTodo>
</div> </div>
</template> </q-tab-panel>
<template v-if="(whatisSel === tools.WHAT_PROJECT) && (!!itemselproj.descr)" v-slot:after> <q-tab-panel name="info">
<div v-if="(whatisSel === tools.WHAT_PROJECT) && (!!itemselproj.descr)">
<div class="q-pa-xs clMain">
<q-tabs <div class="flex-container clMain">
v-model="tabproj"
dense
class="bg-blue text-white shadow-2"
indicator-color="white"
align="center"
narrow-indicator
>
<q-tab name="info" icon="fas fa-check" :label="$t('dashboard.info')"></q-tab>
<q-tab name="stat" icon="fas fa-chart-line" :label="$t('pages.status')"></q-tab>
</q-tabs> <q-icon class="flex-item flex-icon" name="format_align_center"/>
<div :class="classTitleProjSel">
{{ itemselproj.descr }}
</div>
<div class="q-pa-xs clMain"> </div>
<div class="flex-container 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="itemselproj.longdescr"
:label="$t('proj.longdescr')"
outlined
debounce="1000"
autogrow
style="flex: auto">
</q-input>
</div>
</div>
<!--<q-rating--> <div v-if="CanISeeProjectSel" class="flex-container clMain">
<!--v-model="itemselproj.favourite"--> <q-icon class="flex-item flex-icon" name="fas fa-sort-amount-up-alt"/>
<!--class="flex-item flex-icon"--> <div class="flex-item itemdescr">
<!--size="2em"--> <q-input
<!--:max="1"--> v-model="itemselproj.pos"
<!--color="primary">--> type="number"
rounded outlined
debounce="500"
style="max-width: 100px;"
:label="$t('dashboard.posizione')"></q-input>
</div>
</div>
<!--</q-rating>--> <div v-if="CanISeeProjectSel" class="flex-container clMain">
<q-icon class="flex-item flex-icon" name="format_align_center"/> <q-icon class="flex-item flex-icon" name="group"/>
<div :class="classTitleProjSel"> <div class="flex-item itemstatus">
{{ itemselproj.descr }} <q-select style="min-width: 200px"
:readonly="readonly_PanelPrivacySel"
rounded outlined v-model="itemselproj.groupId" :options="selectGroup"
:label="$t('proj.group')" emit-value map-options>
</q-select>
</div>
</div>
<div v-if="CanISeeProjectSel" class="flex-container clMain">
<q-icon class="flex-item flex-icon" name="border_color"/>
<div class="flex-item itemstatus">
<q-select style="min-width: 200px"
:readonly="readonly_PanelPrivacySel"
rounded outlined v-model="itemselproj.respUsername" :options="selectResp"
:label="$t('proj.respUsername')" emit-value map-options>
</q-select>
</div>
</div>
<div v-if="CanISeeProjectSel" class="flex-container clMain">
<q-icon class="flex-item flex-icon" name="border_color"/>
<div class="flex-item itemdescr">
<q-select style="min-width: 200px"
:readonly="readonly_PanelPrivacySel"
rounded outlined v-model="itemselproj.viceRespUsername" :options="selectResp"
:label="$t('proj.viceRespUsername')" emit-value map-options>
</q-select>
</div>
</div>
<div v-if="CanISeeProjectSel" class="flex-container clMain">
<q-icon class="flex-item flex-icon" name="lock"/>
<div class="flex-item itemstatus">
<q-select style="min-width: 200px"
:readonly="readonly_PanelPrivacySel"
rounded outlined v-model="itemselproj.privacyread" :options="selectPrivacy"
:label="$t('proj.privacyread')" emit-value map-options>
</q-select>
</div>
</div>
<div v-if="CanISeeProjectSel" class="flex-container clMain">
<q-icon class="flex-item flex-icon" name="edit"/>
<div class="flex-item itemstatus">
<q-select style="min-width: 200px" :readonly="readonly_PanelPrivacySel" rounded outlined
v-model="itemselproj.privacywrite" :options="selectPrivacy"
:label="$t('proj.privacywrite')" emit-value map-options>
</q-select>
</div>
</div>
</div>
</div>
<div v-else-if="(whatisSel === tools.WHAT_TODO) && (!!itemtodosel.descr)">
<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-icon size="md" :name="iconPriority" color="primary"/>
<q-input
ref="input4"
v-model="itemtodosel.descr"
:class="classTitleTodoSel"
:label="$t('proj.longdescr')"
outlined
:readonly="readonly_PanelPrivacy"
debounce="1000"
autogrow
style="flex: auto">
</q-input>
</div>
</div>
<div class="flex-container clMain">
<q-icon class="flex-item flex-icon" name="fas fa-sort-amount-up-alt"/>
<div class="flex-item itemdescr">
<q-input
v-model="itemtodosel.pos"
type="number"
debounce="500"
rounded outlined
style="max-width: 100px;"
:label="$t('dashboard.posizione')"></q-input>
</div>
</div>
<div class="flex-item itemstatus">
<q-select style="min-width: 200px"
:readonly="readonly_PanelPrivacy"
rounded outlined v-model="itemtodosel.assigned_to_userId" :options="selectWorkers"
:label="$t('todo.assigned_to_userId')" emit-value map-options>
</q-select>
</div>
<div class="flex-item itemstatus">
<CMyFieldDb :title="$t('todo.workers')"
:id="itemtodosel._id"
:idmain="itemtodosel.category"
table="todos"
mykey="assignedToUsers"
:type="tools.FieldType.multiselect"
jointable="workers">
</CMyFieldDb>
</div>
<div class="flex-container clMain">
<q-icon class="flex-item flex-icon" name="done_outline"/>
<div class="flex-item itemstatus">
<q-select rounded outlined v-model="itemtodosel.statustodo" :options="selectStatus"
:readonly="readonly_PanelPrivacy"
:label="$t('todo.status')" emit-value map-options
@input="modifyfieldtodo('statustodo')">
</q-select>
</div>
</div> </div>
</div> </div>
<q-tab-panels v-model="tabproj" animated>
<q-tab-panel name="info">
<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="itemselproj.longdescr"
:label="$t('proj.longdescr')"
outlined
debounce="1000"
autogrow
style="flex: auto">
</q-input>
</div>
</div>
<div v-if="CanISeeProjectSel" class="flex-container clMain">
<q-icon class="flex-item flex-icon" name="fas fa-sort-amount-up-alt"/>
<div class="flex-item itemdescr">
<q-input
v-model="itemselproj.pos"
type="number"
rounded outlined
debounce="500"
style="max-width: 100px;"
:label="$t('dashboard.posizione')"></q-input>
</div>
</div>
<div v-if="CanISeeProjectSel" class="flex-container clMain">
<q-icon class="flex-item flex-icon" name="group"/>
<div class="flex-item itemstatus">
<q-select style="min-width: 200px"
:readonly="readonly_PanelPrivacySel"
rounded outlined v-model="itemselproj.groupId" :options="selectGroup"
:label="$t('proj.group')" emit-value map-options>
</q-select>
</div>
</div>
<div v-if="CanISeeProjectSel" class="flex-container clMain">
<q-icon class="flex-item flex-icon" name="lock"/>
<div class="flex-item itemstatus">
<q-select style="min-width: 200px"
:readonly="readonly_PanelPrivacySel"
rounded outlined v-model="itemselproj.privacyread" :options="selectPrivacy"
:label="$t('proj.privacyread')" emit-value map-options>
</q-select>
</div>
</div>
<div v-if="CanISeeProjectSel" class="flex-container clMain">
<q-icon class="flex-item flex-icon" name="edit"/>
<div class="flex-item itemstatus">
<q-select style="min-width: 200px" :readonly="readonly_PanelPrivacySel" rounded outlined
v-model="itemselproj.privacywrite" :options="selectPrivacy"
:label="$t('proj.privacywrite')" emit-value map-options>
</q-select>
</div>
</div>
</q-tab-panel>
<q-tab-panel name="stat">
<div v-if="CanISeeProjectSel">
<div class="flex-container clMain">
<q-icon class="flex-item flex-icon" name="work_outline"/>
<div class="flex-item itemdescr">
<q-input
ref="input2"
readonly
v-model="itemselproj.hoursworked"
type="number"
rounded outlined
:label="$t('proj.hoursworked')"
debounce="500"></q-input>
<CProgress descr="Fatte" :progressval="getCalcHoursWorked"></CProgress>
</div>
</div>
<div v-if="CanISeeProjectSel" class="flex-item items-center">
<q-icon class="flex-item flex-icon" name="watch_later"/>
<div class="flex-item itemdata content-center q-mx-sm">
<q-input
ref="input3"
type="number"
readonly
v-model="itemselproj.hoursplanned"
rounded outlined
:label="$t('proj.hoursplanned')"
debounce="500">
</q-input>
<CProgress :descr="$t('proj.progresstask')"
:progressval="itemselproj.progressCalc"></CProgress>
</div>
</div>
<div class="flex-container clMain">
<q-icon class="flex-item flex-icon" name="developer_mode"/>
<div class="flex-item itemdata">
<CDate :readonly="readonly_PanelPrivacySel" :mydate="itemselproj.begin_development"
@input="itemselproj.begin_development = new Date(arguments[0])"
:label="$t('proj.begin_development')">
</CDate>
</div>
<div style="margin: 10px;"></div>
<div class="flex-item itemdata">
<CDate :readonly="readonly_PanelPrivacySel" :mydate="itemselproj.begin_test"
@input="itemselproj.begin_test = new Date(arguments[0])"
:label="$t('proj.begin_test')">
</CDate>
</div>
</div>
<div class="flex-container clMain">
<q-icon class="flex-item flex-icon" name="outlined_flag"/>
<div class="flex-item itemstatus">
<q-select style="min-width: 150px" :readonly="readonly_PanelPrivacySel" rounded outlined
v-model="itemselproj.actualphase"
:options="selectPhase"
:label="$t('proj.actualphase')" emit-value map-options>
</q-select>
</div>
<q-icon class="flex-item flex-icon" name="outlined_flag"/>
<div class="flex-item itemstatus">
<q-select style="min-width: 150px"
:readonly="readonly_PanelPrivacySel" rounded outlined v-model="itemselproj.totalphases"
:options="selectPhase"
:label="$t('proj.totalphases')" emit-value map-options>
</q-select>
</div>
</div>
<div class="flex-container clMain">
<q-icon class="flex-item flex-icon" name="watch_later"/>
<div class="flex-item itemdata content-center">
<q-input
:readonly="readonly_PanelPrivacySel"
ref="input3"
type="number"
v-model="itemselproj.hoursweeky_plannedtowork"
rounded outlined
maxlength="2"
:label="$t('proj.hoursweeky_plannedtowork')"
debounce="500">
</q-input>
<CProgress :progressval="calcprogressWeekly"></CProgress>
</div>
<q-icon class="flex-item flex-icon" name="developer_mode"/>
<div class="flex-item itemdata">
<CDate color="green-2" :mydate="calcEndWork_Estimate" :readonly="true"
:label="$t('proj.endwork_estimate')">
</CDate>
</div>
</div>
</div>
</q-tab-panel>
</q-tab-panels>
</div> </div>
</q-tab-panel>
<q-tab-panel name="ore">
<div v-if="(whatisSel === tools.WHAT_PROJECT) && (!!itemselproj.descr)">
<div class="q-pa-xs clMain">
<div class="flex-container clMain">
</template> <q-icon class="flex-item flex-icon" name="format_align_center"/>
<template v-else-if="(whatisSel === tools.WHAT_TODO) && (!!itemtodosel.descr)" v-slot:after> <div :class="classTitleProjSel">
<q-tabs {{ itemselproj.descr }}
v-model="tabproj" </div>
dense
class="bg-blue text-white shadow-2"
indicator-color="white"
align="center"
narrow-indicator
>
<q-tab name="info" icon="fas fa-check" :label="$t('dashboard.info')"></q-tab>
<q-tab name="stat" icon="fas fa-chart-line" :label="$t('pages.status')"></q-tab>
</q-tabs> </div>
</div>
</div>
<div v-else-if="(whatisSel === tools.WHAT_TODO) && (!!itemtodosel.descr)">
<CHours v-if="!!itemtodosel" :todoId="itemtodosel._id"></CHours>
</div>
</q-tab-panel>
<q-tab-panel name="stat">
<div v-if="(whatisSel === tools.WHAT_PROJECT) && (!!itemselproj.descr)">
<div class="q-pa-xs clMain">
<div class="flex-container clMain">
<div class="q-pa-xs clMain"> <q-icon class="flex-item flex-icon" name="format_align_center"/>
<div :class="classTitleProjSel">
{{ itemselproj.descr }}
</div>
<div class="flex-container clMain">
<q-icon class="flex-item flex-icon" name="format_align_center"/>
<div :class="classTitleProjSel">
{{ itemtodosel.descr }}
</div> </div>
</div> </div>
<q-tab-panels v-model="tabproj" animated> <div v-if="CanISeeProjectSel">
<q-tab-panel name="info"> <div v-if="!!itemselproj">
<div class="flex-container clMain"> itemselproj._id: {{ itemselproj._id }}
<q-icon class="flex-item flex-icon" name="border_color"/> </div>
<div class="flex-item itemdescr"> <div class="flex-container clMain">
<q-input <q-icon class="flex-item flex-icon" name="work_outline"/>
ref="input4" <div class="flex-item itemdescr">
v-model="itemtodosel.descr" <q-input
:class="classTitleTodoSel" ref="input2"
:label="$t('proj.longdescr')" readonly
outlined v-model="itemselproj.hoursworked"
:readonly="readonly_PanelPrivacy" type="number"
debounce="1000" rounded outlined
autogrow> :label="$t('proj.hoursworked')"
debounce="500"></q-input>
</q-input> <CProgress descr="Fatte" :progressval="getCalcHoursWorked"></CProgress>
<q-icon size="md" :name="iconPriority" color="primary"/>
</div>
</div> </div>
</div>
<div v-if="CanISeeProjectSel" class="flex-item items-center">
<q-icon class="flex-item flex-icon" name="watch_later"/>
<div class="flex-item itemdata content-center q-mx-sm">
<q-input
ref="input3"
type="number"
readonly
v-model="itemselproj.hoursplanned"
rounded outlined
:label="$t('proj.hoursplanned')"
debounce="500">
<div class="flex-container clMain"> </q-input>
<q-icon class="flex-item flex-icon" name="fas fa-sort-amount-up-alt"/> <CProgress :descr="$t('proj.progresstask')"
<div class="flex-item itemdescr"> :progressval="itemselproj.progressCalc"></CProgress>
<q-input
v-model="itemtodosel.pos"
type="number"
debounce="500"
rounded outlined
style="max-width: 100px;"
:label="$t('dashboard.posizione')"></q-input>
</div>
</div> </div>
</div>
<div class="flex-container clMain"> <div class="flex-container clMain">
<q-icon class="flex-item flex-icon" name="done_outline"/> <q-icon class="flex-item flex-icon" name="developer_mode"/>
<div class="flex-item itemstatus"> <div class="flex-item itemdata">
<q-select rounded outlined v-model="itemtodosel.statustodo" :options="selectStatus" <CDate :readonly="readonly_PanelPrivacySel" :mydate="itemselproj.begin_development"
:readonly="readonly_PanelPrivacy" @input="itemselproj.begin_development = new Date(arguments[0])"
:label="$t('todo.status')" emit-value map-options :label="$t('proj.begin_development')">
@input="modifyfieldtodo('statustodo')"> </CDate>
</q-select>
</div>
<q-icon class="flex-item flex-icon" name="outlined_flag"/>
<div class="flex-item itemstatus">
<q-select rounded outlined v-model="itemtodosel.phase" :options="selectPhase"
:readonly="readonly_PanelPrivacy"
:label="$t('todo.phase')" emit-value map-options>
</q-select>
</div>
</div> </div>
</q-tab-panel> <div style="margin: 10px;"></div>
<q-tab-panel name="stat"> <div class="flex-item itemdata">
<div class="flex-container clMain"> <CDate :readonly="readonly_PanelPrivacySel" :mydate="itemselproj.begin_test"
<q-icon class="flex-item flex-icon" name="work_outline"/> @input="itemselproj.begin_test = new Date(arguments[0])"
<div class="flex-item itemdescr"> :label="$t('proj.begin_test')">
<q-input </CDate>
ref="input5"
:readonly="readonly_PanelPrivacy"
v-model="itemtodosel.hoursworked"
type="number"
rounded outlined
:label="$t('proj.hoursworked')"
debounce="500">
</q-input>
<CProgress descr="" :progressval="getCalcTodoHoursWorked"></CProgress>
</div>
</div> </div>
<div class="flex-container clMain"> </div>
<q-icon class="flex-item flex-icon" name="watch_later"/> <div class="flex-container clMain">
<div class="flex-item itemdata content-center"> <q-icon class="flex-item flex-icon" name="outlined_flag"/>
<q-input <div class="flex-item itemstatus">
ref="input6" <q-select style="min-width: 150px" :readonly="readonly_PanelPrivacySel" rounded outlined
:readonly="readonly_PanelPrivacy" v-model="itemselproj.actualphase"
type="number" :options="selectPhase"
v-model="itemtodosel.hoursplanned" :label="$t('proj.actualphase')" emit-value map-options>
rounded outlined </q-select>
:label="$t('proj.hoursplanned')"
debounce="500">
</q-input>
<CProgress :descr="$t('proj.progresstask')"
:readonly="readonly_PanelPrivacy"
:progressval="itemtodosel.progress"
:slider="true" @input="itemtodosel.progress = arguments[0]"></CProgress>
</div>
</div> </div>
<div class="flex-container clMain"> <q-icon class="flex-item flex-icon" name="outlined_flag"/>
<q-icon class="flex-item flex-icon" name="developer_mode"/> <div class="flex-item itemstatus">
<div class="flex-item itemdata"> <q-select style="min-width: 150px"
<CDate :mydate="itemtodosel.start_date" :readonly="readonly_PanelPrivacySel" rounded outlined v-model="itemselproj.totalphases"
:readonly="readonly_PanelPrivacy" :options="selectPhase"
@input="itemtodosel.start_date = new Date(arguments[0])" :label="$t('proj.totalphases')" emit-value map-options>
:label="$t('todo.start_date')"> </q-select>
</CDate>
</div>
<div style="margin: 10px;"></div>
<q-icon class="flex-item flex-icon" name="event"/>
<div class="flex-item itemdata">
<CDate :readonly="((itemtodosel.statustodo !== tools.Status.COMPLETED) || readonly_PanelPrivacy)"
:mydate="itemtodosel.completed_at"
@input="itemtodosel.completed_at = new Date(arguments[0])"
:label="$t('todo.completed_at')">
</CDate>
</div>
</div> </div>
</div>
<div class="flex-container clMain">
<q-icon class="flex-item flex-icon" name="watch_later"/>
<div class="flex-item itemdata content-center">
<q-input
:readonly="readonly_PanelPrivacySel"
ref="input3"
type="number"
v-model="itemselproj.hoursweeky_plannedtowork"
rounded outlined
maxlength="2"
:label="$t('proj.hoursweeky_plannedtowork')"
debounce="500">
</q-input>
<CProgress :progressval="calcprogressWeekly"></CProgress>
</div>
<q-icon class="flex-item flex-icon" name="developer_mode"/>
<div class="flex-item itemdata">
<CDate color="green-2" :mydate="calcEndWork_Estimate" :readonly="true"
:label="$t('proj.endwork_estimate')">
</CDate>
</div>
</div>
</div>
</q-tab-panel>
</q-tab-panels>
</div> </div>
</template> <div v-else-if="(whatisSel === tools.WHAT_TODO) && (!!itemtodosel.descr)">
</q-splitter> <div class="q-pa-xs clMain">
<div class="flex-container clMain">
<q-icon class="flex-item flex-icon" name="format_align_center"/>
<div :class="classTitleProjSel">
{{ itemtodosel.descr }}
</div>
</div>
</div>
<div>
itemtodosel._id: {{ itemtodosel._id }}
<div class="flex-container clMain">
<q-icon class="flex-item flex-icon" name="work_outline"/>
<div class="flex-item itemdescr">
<q-input
ref="input5"
:readonly="true"
v-model="itemtodosel.hoursworked"
type="number"
rounded outlined
:label="$t('proj.hoursworked')"
debounce="500">
</q-input>
<CProgress descr="" :progressval="getCalcTodoHoursWorked"></CProgress>
</div>
</div>
<div class="flex-container clMain">
<q-icon class="flex-item flex-icon" name="watch_later"/>
<div class="flex-item itemdata content-center">
<q-input
ref="input6"
:readonly="readonly_PanelPrivacy"
type="number"
v-model="itemtodosel.hoursplanned"
rounded outlined
:label="$t('proj.hoursplanned')"
debounce="500">
</q-input>
<CProgress :descr="$t('proj.progresstask')"
:readonly="readonly_PanelPrivacy"
:progressval="itemtodosel.progress"
:slider="true" @input="itemtodosel.progress = arguments[0]"></CProgress>
</div>
</div>
<div class="flex-container clMain">
<q-icon class="flex-item flex-icon" name="developer_mode"/>
<div class="flex-item itemdata">
<CDate :mydate="itemtodosel.start_date"
:readonly="readonly_PanelPrivacy"
@input="itemtodosel.start_date = new Date(arguments[0])"
:label="$t('todo.start_date')">
</CDate>
</div>
<div style="margin: 10px;"></div>
<q-icon class="flex-item flex-icon" name="event"/>
<div class="flex-item itemdata">
<CDate :readonly="((itemtodosel.statustodo !== tools.Status.COMPLETED) || readonly_PanelPrivacy)"
:mydate="itemtodosel.completed_at"
@input="itemtodosel.completed_at = new Date(arguments[0])"
:label="$t('todo.completed_at')">
</CDate>
</div>
</div>
<div class="flex-container clMain">
<q-icon class="flex-item flex-icon" name="outlined_flag"/>
<div class="flex-item itemstatus">
<q-select rounded outlined v-model="itemtodosel.phase" :options="selectPhase"
:readonly="readonly_PanelPrivacy"
:label="$t('todo.phase')" emit-value map-options>
</q-select>
</div>
</div>
</div>
</div>
</q-tab-panel>
</q-tab-panels>
</div> </div>
</q-page> </q-page>
</template> </template>