Reportistica Ore 2

This commit is contained in:
Paolo Arena
2021-02-24 04:52:33 +01:00
parent f8ad20d1ae
commit 1fdafbb0e4
16 changed files with 396 additions and 176 deletions

View File

@@ -39,6 +39,9 @@ export const shared_consts = {
FILTER_HOURS_MYLIST: 65536, FILTER_HOURS_MYLIST: 65536,
FILTER_HOURS_ALL: 131072, FILTER_HOURS_ALL: 131072,
REPORT_FILT_RESP: 1,
REPORT_FILT_ATTIVITA: 2,
Permissions: { Permissions: {
Admin: { Admin: {
value: 1, value: 1,

View File

@@ -471,6 +471,7 @@
:enable-themes="enableThemes === true" :enable-themes="enableThemes === true"
--> -->
<q-calendar <q-calendar
v-if="visuAllCal" v-if="visuAllCal"
ref="calendar" ref="calendar"

View File

@@ -10,7 +10,7 @@ $heightdescr: 20px;
.flex-container2 { .flex-container2 {
flex-flow: row wrap; flex-flow: row wrap;
justify-content: space-between; justify-content: space-between;
margin: 0px 10px 0px 10px; // top right bottom left // margin: 0px 10px 0px 10px; // top right bottom left
} }
// Set visibility: visible to the icon menu of pos-item-popover // Set visibility: visible to the icon menu of pos-item-popover
@@ -79,7 +79,7 @@ $heightdescr: 20px;
} }
.pos-go { .pos-go {
order: 1; // order: 1;
} }
@@ -163,8 +163,10 @@ $heightdescr: 20px;
padding-bottom: 4px; padding-bottom: 4px;
max-width: 36px; max-width: 36px;
min-width: 32px; min-width: 32px;
flex: 1; display: inline-block;
order: 1; vertical-align: middle;
// flex: 1;
// order: 1;
} }
.progrbar-item { .progrbar-item {
@@ -393,3 +395,13 @@ $heightdescr: 20px;
flex: 1; flex: 1;
} }
*/ */
.clResp{
font-weight: bold;
color: darkgreen;
}
.clViceResp{
font-weight: bold;
color: red;
}

View File

@@ -6,7 +6,7 @@ import { tools } from '../../../store/Modules/tools'
import { toolsext } from '@src/store/Modules/toolsext' import { toolsext } from '@src/store/Modules/toolsext'
import { lists } from '../../../store/Modules/lists' import { lists } from '../../../store/Modules/lists'
import { IProject } from '../../../model/index' import { IProject, TipoVisu } from '../../../model/index'
import { SubMenusProj } from '../SubMenusProj' import { SubMenusProj } from '../SubMenusProj'
import { CDate } from '../../CDate' import { CDate } from '../../CDate'
@@ -14,6 +14,7 @@ import { CDate } from '../../CDate'
import { date } from 'quasar' import { date } from 'quasar'
import { GlobalStore } from '@store' import { GlobalStore } from '@store'
import { RouteNames } from '@src/router/route-names' import { RouteNames } from '@src/router/route-names'
import { shared_consts } from '@src/common/shared_vuejs'
@Component({ @Component({
components: { SubMenusProj, CDate }, components: { SubMenusProj, CDate },
@@ -51,6 +52,17 @@ export default class SingleProject extends Vue {
return Projects.getters.CanIModifyPanelPrivacy(this.itemproject) return Projects.getters.CanIModifyPanelPrivacy(this.itemproject)
} }
get TipoVisu() {
return TipoVisu
}
get getTipovisuByProjParent() {
let myprojparent = Projects.getters.getRecordById(this.itemproject.id_parent)
if (!myprojparent)
myprojparent = this.itemproject
return Projects.getters.getTipoVisuProj(myprojparent)
}
@Prop({ required: true }) public itemproject: IProject @Prop({ required: true }) public itemproject: IProject
@Watch('itemproject.enableExpiring') @Watch('itemproject.enableExpiring')
@@ -143,6 +155,11 @@ export default class SingleProject extends Vue {
this.watchupdate('privacywrite') this.watchupdate('privacywrite')
} }
@Watch('itemproject.tipovisu')
public valueChanged_tipovisu() {
this.watchupdate('tipovisu')
}
@Watch('itemproject.totalphases') @Watch('itemproject.totalphases')
public valueChangedtotalphases() { public valueChangedtotalphases() {
this.watchupdate('totalphases') this.watchupdate('totalphases')
@@ -196,8 +213,8 @@ export default class SingleProject extends Vue {
public updateClasses() { public updateClasses() {
// this.classCompleted = 'completed-item' // this.classCompleted = 'completed-item'
this.classDescr = 'flex-item div_descr show donotdrag' this.classDescr = ''
this.classDescrEdit = 'flex-item div_descr_edit donotdrag' this.classDescrEdit = 'div_descr_edit donotdrag'
if (!this.isProject()) { if (!this.isProject()) {
this.classDescr += ' titleLista-item' this.classDescr += ' titleLista-item'
this.classDescrEdit += ' titleLista-item' this.classDescrEdit += ' titleLista-item'
@@ -208,7 +225,7 @@ export default class SingleProject extends Vue {
this.percProgress = 'percProgress' this.percProgress = 'percProgress'
this.classExpiring = 'flex-item data-item shadow-1 hide-if-small' this.classExpiring = 'data-item shadow-1 hide-if-small'
this.classExpiringEx = '' this.classExpiringEx = ''
this.clButtPopover = this.sel ? 'pos-item-popover comp_selected' : 'pos-item-popover' this.clButtPopover = this.sel ? 'pos-item-popover comp_selected' : 'pos-item-popover'
@@ -628,4 +645,18 @@ export default class SingleProject extends Vue {
*/ */
} }
public getResp() {
if (!!GlobalStore.state.resps)
return this.itemproject.respUsername ? GlobalStore.getters.getRespByUsername(this.itemproject.respUsername) : ''
else
return ''
}
public getViceResp() {
if (!!GlobalStore.state.resps)
return this.itemproject.viceRespUsername ? GlobalStore.getters.getRespByUsername(this.itemproject.viceRespUsername) : ''
else
return ''
}
} }

View File

@@ -1,6 +1,8 @@
<template> <template>
<div :class="getClassRow()" @click="clickProject"> <q-item @click="clickProject" clickable>
<q-item-section avatar>
<q-btn <q-btn
v-if="isProject()" v-if="isProject()"
:class="(itemproject.respUsername !== '' && itemproject.viceRespUsername !== '') ? 'clresp' : 'clrespempty' + ' clButtPopover pos-item'" :class="(itemproject.respUsername !== '' && itemproject.viceRespUsername !== '') ? 'clresp' : 'clrespempty' + ' clButtPopover pos-item'"
@@ -16,13 +18,17 @@
@selectSubMenu="selectSubMenu"></SubMenusProj> @selectSubMenu="selectSubMenu"></SubMenusProj>
</q-menu> </q-menu>
</q-btn> </q-btn>
</q-item-section>
<q-item-section>
<div :class="getClassRow()">
<!--<div :class="(itemproject.respUsername !== '' && itemproject.viceRespUsername !== '') ? 'clresp' : 'clrespempty' + ' pos-group flex-item'"> <!--<div :class="(itemproject.respUsername !== '' && itemproject.viceRespUsername !== '') ? 'clresp' : 'clrespempty' + ' pos-group flex-item'">
<q-icon class="" name="fas fa-user-friends"></q-icon> <q-icon class="" name="fas fa-user-friends"></q-icon>
</div>--> </div>-->
<!--<div class="q-mx-xs"></div>--> <!--<div class="q-mx-xs"></div>-->
<div class="flex-item donotdrag divdescrTot"> <q-item-label>
<div class="flex-item donotdrag">
<q-input v-if="(sel && inEdit)" hide-underline type="textarea" ref="inputprojdescr" <q-input v-if="(sel && inEdit)" hide-underline type="textarea" ref="inputprojdescr"
v-model.trim="precDescr" v-model.trim="precDescr"
autogrow autogrow
@@ -40,15 +46,31 @@
<!--<div class="clpos">{{ itemproject.pos }}.</div> --> <!--<div class="clpos">{{ itemproject.pos }}.</div> -->
{{ itemproject.descr }} {{ itemproject.descr }}
</div> </div>
</div> </div>
</q-item-label>
<q-item-label v-if="getTipovisuByProjParent === TipoVisu.responsabili" caption lines="2">
<span v-if="getResp()">Responsabile: <span class="clResp">{{ getResp() }}</span><br></span>
<span v-if="getViceResp()">ViceResponsabile: <span class="clViceResp">{{ getViceResp() }}</span></span>
</q-item-label>
<!--<div> <!--<div>
{{ tools.getGroupById(itemproject.groupId) }} {{ tools.getGroupById(itemproject.groupId) }}
</div>--> </div>-->
<div v-if="isProject()" class="flex-item donotdrag progress-item shadow-1"> <div v-if="itemproject.enableExpiring" :class="classExpiring">
<CDate :mydate="itemproject.expiring_at" @input="itemproject.expiring_at = new Date(arguments[0])"
data_class="data_string">
</CDate>
</div>
</div>
</q-item-section>
<q-item-section side>
<q-item-label caption>
<div v-if="isProject() && itemproject.tipovisu === TipoVisu.taskProgress && percentageProgress > 0"
class="donotdrag progress-item shadow-1">
<q-linear-progress <q-linear-progress
stripe stripe
rounded rounded
@@ -61,21 +83,16 @@
{{ percentageProgress }}% {{ percentageProgress }}%
</div> </div>
</div> </div>
<q-btn :disable="isDisable" class="pos-go" size="sm" push color="primary" round
<div v-if="itemproject.enableExpiring" :class="classExpiring">
<CDate :mydate="itemproject.expiring_at" @input="itemproject.expiring_at = new Date(arguments[0])"
data_class="data_string">
</CDate>
</div>
<q-btn :disable="isDisable" class="flex-item donotdrag pos-go" size="sm" push color="primary" round
icon="arrow_forward" icon="arrow_forward"
:to="getrouteto"> :to="getrouteto">
</q-btn> </q-btn>
</q-item-label>
</q-item-section>
</q-item>
</div>
</template> </template>
<script lang="ts" src="./SingleProject.ts"> <script lang="ts" src="./SingleProject.ts">

View File

@@ -44,6 +44,7 @@ export interface IProject {
actualphase?: number actualphase?: number
privacyread?: string privacyread?: string
privacywrite?: string privacywrite?: string
tipovisu?: number
themecolor?: string themecolor?: string
themebgcolor?: string themebgcolor?: string
groupId?: string groupId?: string
@@ -66,6 +67,13 @@ export const Privacy = {
inherited: 'inherited' inherited: 'inherited'
} }
export const TipoVisu = {
inherited: 0,
simplelist: 1,
taskProgress: 2,
responsabili: 3
}
export const TypeProj = { export const TypeProj = {
TYPE_PROJECT: 1, TYPE_PROJECT: 1,
TYPE_SUBDIR: 2 TYPE_SUBDIR: 2

View File

@@ -540,6 +540,7 @@ const msg_it = {
endwork_estimate: 'Data fine lavori stimata', endwork_estimate: 'Data fine lavori stimata',
privacyread: 'Chi lo puo vedere:', privacyread: 'Chi lo puo vedere:',
privacywrite: 'Chi lo puo modificare:', privacywrite: 'Chi lo puo modificare:',
tipovisu: 'Visualizzazione:',
totalphases: 'Totale Fasi', totalphases: 'Totale Fasi',
themecolor: 'Tema Colore', themecolor: 'Tema Colore',
themebgcolor: 'Tema Colore Sfondo', themebgcolor: 'Tema Colore Sfondo',

View File

@@ -180,6 +180,11 @@ namespace Getters {
return ris return ris
}, 't') }, 't')
const getRespByUsername = b.read((state) => (username) => {
const rec = state.resps.find((rec) => rec.username === username)
return !!rec ? rec.name + ' ' + rec.surname : ''
}, 'getRespByUsername')
const getListByTable = b.read((state) => (table) => { const getListByTable = b.read((state) => (table) => {
if (table === tools.TABEVENTS) if (table === tools.TABEVENTS)
return CalendarStore.state.eventlist return CalendarStore.state.eventlist
@@ -308,6 +313,10 @@ namespace Getters {
return getListByTable() return getListByTable()
}, },
get getRespByUsername() {
return getRespByUsername()
},
get getCmdClick() { get getCmdClick() {
return getCmdClick() return getCmdClick()
}, },

View File

@@ -1,5 +1,5 @@
import { IProject, IProjectsState, IDrag, IMenuList, IAction } from 'model' import { IProject, IProjectsState, IDrag, IMenuList, IAction } from 'model'
import { Privacy } from '@src/model' import { Privacy, TipoVisu } from '@src/model'
import { storeBuilder } from './Store/Store' import { storeBuilder } from './Store/Store'
import Api from '@api' import Api from '@api'
@@ -30,7 +30,7 @@ const stateglob: IProjectsState = {
const listFieldsToChange: string [] = ['descr', 'respUsername', 'viceRespUsername', 'longdescr', 'hoursplanned', 'hoursleft', 'hoursworked', 'id_parent', 'statusproj', const listFieldsToChange: string [] = ['descr', 'respUsername', 'viceRespUsername', 'longdescr', 'hoursplanned', 'hoursleft', 'hoursworked', 'id_parent', 'statusproj',
'category', 'expiring_at', 'priority', 'pos', 'groupId', 'enableExpiring', 'progressCalc', 'live_url', 'test_url', 'category', 'expiring_at', 'priority', 'pos', 'groupId', 'enableExpiring', 'progressCalc', 'live_url', 'test_url',
'begin_development', 'begin_test', 'actualphase', 'totalphases', 'hoursweeky_plannedtowork', 'endwork_estimate', 'begin_development', 'begin_test', 'actualphase', 'totalphases', 'hoursweeky_plannedtowork', 'endwork_estimate',
'privacyread', 'privacywrite', 'id_main_project', 'typeproj', 'favourite', 'themecolor', 'themebgcolor'] 'privacyread', 'privacywrite', 'tipovisu', 'id_main_project', 'typeproj', 'favourite', 'themecolor', 'themebgcolor']
const listFieldsUpdateCalculation: string [] = ['hoursplanned', 'hoursleft', 'hoursworked', 'progressCalc', 'endwork_estimate'] const listFieldsUpdateCalculation: string [] = ['hoursplanned', 'hoursleft', 'hoursworked', 'progressCalc', 'endwork_estimate']
@@ -50,6 +50,19 @@ function getFirstInherited(proj, idparent, state) {
return myprojtocheck return myprojtocheck
} }
function getFirstInheritedTipoVisu(proj, idparent, state) {
let tipovisuproj = null
while (!proj.tipovisu || proj.tipovisu <= 0) {
tipovisuproj = state.projects.find((rec) => rec._id === idparent)
if (!tipovisuproj)
return null
idparent = tipovisuproj.id_parent
proj = tipovisuproj
}
return tipovisuproj.tipovisu
}
function getarrByCategory(category: string) { function getarrByCategory(category: string) {
if (!stateglob.projects) { if (!stateglob.projects) {
return [] return []
@@ -128,7 +141,8 @@ namespace Getters {
themebgcolor: '', themebgcolor: '',
groupId: '', groupId: '',
respUsername: '', respUsername: '',
viceRespUsername: '' viceRespUsername: '',
tipovisu: 0
} }
return obj return obj
@@ -236,6 +250,27 @@ namespace Getters {
}, 'getifCanISeeProj') }, 'getifCanISeeProj')
const getTipoVisuProj = b.read((state: IProjectsState) => (proj: IProject): number => {
if ((proj === undefined) || (proj === null))
return TipoVisu.simplelist
if (!!UserStore.state) {
let tipovisuproj = proj
if (tipovisuproj.tipovisu === TipoVisu.inherited) {
tipovisuproj = getFirstInheritedTipoVisu(proj, proj.id_parent, state)
if (!tipovisuproj)
return TipoVisu.simplelist
}
return tipovisuproj.tipovisu
} else {
return TipoVisu.simplelist
}
}, 'getTipoVisuProj')
const CanIModifyPanelPrivacy = b.read((state: IProjectsState) => (proj: IProject): boolean => { const CanIModifyPanelPrivacy = b.read((state: IProjectsState) => (proj: IProject): boolean => {
if ((proj === undefined) || (proj === null)) if ((proj === undefined) || (proj === null))
return false return false
@@ -266,6 +301,9 @@ namespace Getters {
get CanIModifyPanelPrivacy() { get CanIModifyPanelPrivacy() {
return CanIModifyPanelPrivacy() return CanIModifyPanelPrivacy()
}, },
get getTipoVisuProj() {
return getTipoVisuProj()
},
get getRecordEmpty() { get getRecordEmpty() {
return getRecordEmpty() return getRecordEmpty()
}, },
@@ -449,6 +487,7 @@ namespace Actions {
objproj.privacyread = myobj.privacyread objproj.privacyread = myobj.privacyread
objproj.privacywrite = myobj.privacywrite objproj.privacywrite = myobj.privacywrite
objproj.actualphase = myobj.actualphase objproj.actualphase = myobj.actualphase
objproj.tipovisu = myobj.tipovisu
let elemtochange: IProject = null let elemtochange: IProject = null

View File

@@ -19,7 +19,7 @@ import {
IParamDialog, IParamDialog,
IProject, IProject,
ITodo, ITodo,
Privacy Privacy, TipoVisu
} from '@src/model' } from '@src/model'
import * as ApiTables from '@src/store/Modules/ApiTables' import * as ApiTables from '@src/store/Modules/ApiTables'
import translate from '@src/globalroutines/util' import translate from '@src/globalroutines/util'
@@ -448,6 +448,31 @@ export const tools = {
] ]
}, },
selectTipoVisu: {
it: [
{
id: 1,
label: translation.it.privacy.inherited,
value: TipoVisu.inherited
},
{
id: 2,
label: translation.it.tipovisu.simplelist,
value: TipoVisu.simplelist
},
{
id: 3,
label: translation.it.tipovisu.taskProgress,
value: TipoVisu.taskProgress
},
{
id: 4,
label: translation.it.tipovisu.responsabili,
value: TipoVisu.responsabili
}
]
},
selectStatus: { selectStatus: {
it: [ it: [
{ {
@@ -2587,6 +2612,11 @@ export const tools = {
return isNaN(dayOfWeek) ? '' : myday[lang][dayOfWeek].substring(0, 3) return isNaN(dayOfWeek) ? '' : myday[lang][dayOfWeek].substring(0, 3)
}, },
isSunday(mydate) {
const dayOfWeek = new Date(mydate).getDay()
return dayOfWeek === 0
},
getDateNowEvent() { getDateNowEvent() {
return tools.addDays(tools.getDateNow(), -1) return tools.addDays(tools.getDateNow(), -1)
}, },
@@ -2650,8 +2680,7 @@ export const tools = {
getprivacywritebytipoproj(tipoproj) { getprivacywritebytipoproj(tipoproj) {
return Privacy.inherited return Privacy.inherited
} },
,
addRoute(myarr, values) { addRoute(myarr, values) {
myarr.push(values) myarr.push(values)

View File

@@ -8,6 +8,11 @@ export const translation = {
onlyme: 'Solo io', onlyme: 'Solo io',
inherited: 'Ereditato' inherited: 'Ereditato'
}, },
tipovisu : {
simplelist: 'Lista Semplice',
taskProgress: 'Statistiche',
responsabili: 'Responsabili',
},
proj: { proj: {
newproj: 'Nuovo Progetto', newproj: 'Nuovo Progetto',
newsubproj: 'Nuovo Sotto-Progetto', newsubproj: 'Nuovo Sotto-Progetto',

View File

@@ -17,11 +17,14 @@
<br> <br>
<!--
<div class="row"> <div class="row">
<q-btn label="Crea Utenti Test" color="primary" @click="EseguiFunz('creaUtentiTest')"></q-btn> <q-btn label="Crea Utenti Test" color="primary" @click="EseguiFunz('creaUtentiTest')"></q-btn>
<br> <br>
</div> </div>
<!--<div class="row">
<div class="row">
<q-btn label="Passa i codici Telefoni sul campo cell" color="primary" <q-btn label="Passa i codici Telefoni sul campo cell" color="primary"
@click="EseguiFunz('changeCellInt')"></q-btn> @click="EseguiFunz('changeCellInt')"></q-btn>
<br></div> <br></div>
@@ -59,18 +62,18 @@
@click="EseguiFunz('delNaviNoStarted')"></q-btn> @click="EseguiFunz('delNaviNoStarted')"></q-btn>
<br> <br>
</div>--> </div>-->
<!--
<div class="row"> <div class="row">
<q-btn label="Rigenera (Elim, Genera Graduat, Add Navi Temp" color="positive" size="lg" <q-btn label="Rigenera (Elim, Genera Graduat, Add Navi Temp" color="positive" size="lg"
@click="EseguiFunz('rigeneraTutto')"></q-btn> @click="EseguiFunz('rigeneraTutto')"></q-btn>
<!--<q-btn label="Crea ListaIngresso" color="positive" @click="EseguiFunz('creaLista')"></q-btn>-->
</div> </div>
<br> <br>
<div class="row"> <div class="row">
<q-btn label="Elimina Navi Provvisorie" color="negative" <q-btn label="Elimina Navi Provvisorie" color="negative"
@click="EseguiFunz('delNaviProvvisorie')"></q-btn> @click="EseguiFunz('delNaviProvvisorie')"></q-btn>
<!--<q-btn label="Crea ListaIngresso" color="positive" @click="EseguiFunz('creaLista')"></q-btn>-->
</div> </div>
<q-btn label="Genera Graduatoria" color="primary" <q-btn label="Genera Graduatoria" color="primary"
@click="EseguiFunz('GeneraGraduatoria')"></q-btn> @click="EseguiFunz('GeneraGraduatoria')"></q-btn>
@@ -100,16 +103,6 @@
:serv="false" :serv="false"
:type="tools.FieldType.number"> :type="tools.FieldType.number">
</CMyFieldDb> </CMyFieldDb>
<!--<CMyFieldDb title="Riga Doni"
mykey="rigadoni"
:serv="false"
:type="tools.FieldType.number">
</CMyFieldDb>
<CMyFieldDb title="Col Doni"
mykey="coldoni"
:serv="false"
:type="tools.FieldType.number">
</CMyFieldDb>-->
<CMyFieldDb title="Visu_TEST" <CMyFieldDb title="Visu_TEST"
mykey="VISU_TEST" mykey="VISU_TEST"
:serv="false" :serv="false"
@@ -136,14 +129,6 @@
<q-btn label="Visualizza Lista Nave" color="primary" @click="EseguiFunz('visuListaNave')"></q-btn> <q-btn label="Visualizza Lista Nave" color="primary" @click="EseguiFunz('visuListaNave')"></q-btn>
</div> </div>
<!--<div class="row">
<q-btn label="Visualizza ListaIngresso" color="primary"
@click="EseguiFunz('visuListaIngresso')"></q-btn>
<br>
<q-btn label="Visualizza ListaIngresso Nuovi" color="primary"
@click="EseguiFunz('visuListaIngressoNuovi')"></q-btn>
<br>
</div>-->
<q-btn label="Aggiorna Indice Graduatoria" color="primary" <q-btn label="Aggiorna Indice Graduatoria" color="primary"
@click="EseguiFunz('AggiornaIndiceGraduatoria')"></q-btn> @click="EseguiFunz('AggiornaIndiceGraduatoria')"></q-btn>
@@ -179,13 +164,7 @@
@click="EseguiFunz('mettiSognoePaypal')"></q-btn> @click="EseguiFunz('mettiSognoePaypal')"></q-btn>
<br> <br>
</div> </div>
<!--<div class="row">
<q-btn label="AGGIUNGI NAVE PER UTENTI CHE NON CE L'HANNO (flag navinonpresenti)!" color="primary"
@click="EseguiFunz('addNavePerUtentiNaviNonPresenti')"></q-btn>
<br>
</div>-->
<!--
<div class="row"> <div class="row">
<q-btn label="1) CONVERTI TUTTA LA STRUTTURA NEL NUOVO SISTEMA !" color="negative" <q-btn label="1) CONVERTI TUTTA LA STRUTTURA NEL NUOVO SISTEMA !" color="negative"
@click="EseguiFunz('creaTessituraeConv')"></q-btn> @click="EseguiFunz('creaTessituraeConv')"></q-btn>
@@ -201,14 +180,8 @@
@click="EseguiFunz('RendiVisibileIrecordNascosti')"></q-btn> @click="EseguiFunz('RendiVisibileIrecordNascosti')"></q-btn>
<br> <br>
</div> </div>
-->
<br> <br>
<br> <br>
<!--<div class="row">
<q-btn label="CHECK SE INSERIRE UTENTI IN Nave" color="primary"
@click="EseguiFunz('checkInserimentiUtentiInNave')"></q-btn>
<br>
</div>-->
<div class="row"> <div class="row">
<q-input v-model="riga" type="number" autofocus label="Riga" style="width: 50px;"></q-input> <q-input v-model="riga" type="number" autofocus label="Riga" style="width: 50px;"></q-input>
@@ -223,6 +196,13 @@
style="width: 500px; height: 400px;"></q-input> style="width: 500px; height: 400px;"></q-input>
<br> <br>
</div> </div>
-->
</div>
<div class="row">
<q-btn label="Correggi Tabella Hours con userId" color="negative"
@click="EseguiFunz('CorreggiTabHours')"></q-btn>
<br>
</div> </div>

View File

@@ -1,7 +1,17 @@
import Vue from 'vue' import Vue from 'vue'
import { Component, Watch } from 'vue-property-decorator' import { Component, Watch } from 'vue-property-decorator'
import { IAction, IDrag, IGlobalState, IProject, IProjectsState, ITodo, Privacy, TypeProj } from '../../../model/index' import {
IAction,
IDrag,
IGlobalState,
IProject,
IProjectsState,
ITodo,
Privacy,
TipoVisu,
TypeProj
} from '../../../model/index'
import { SingleProject } from '../../../components/projects/SingleProject/index' import { SingleProject } from '../../../components/projects/SingleProject/index'
import { CTodo } from '../../../components/todos/CTodo' import { CTodo } from '../../../components/todos/CTodo'
@@ -46,6 +56,10 @@ export default class ProjList extends Vue {
public tabproj: string = 'lista' public tabproj: string = 'lista'
get TipoVisu() {
return TipoVisu
}
get classTitle() { get classTitle() {
let cl = 'flex-item categorytitle shadow-4' let cl = 'flex-item categorytitle shadow-4'
if (!!this.itemprojparent) { if (!!this.itemprojparent) {
@@ -321,6 +335,7 @@ export default class ProjList extends Vue {
public selectStatus: any[] = tools.selectStatus[toolsext.getLocale()] public selectStatus: any[] = tools.selectStatus[toolsext.getLocale()]
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 selectTipoVisu: any[] = tools.selectTipoVisu[toolsext.getLocale()]
public selectGroup: any[] = [] public selectGroup: any[] = []
public selectResp: any[] = [] public selectResp: any[] = []
public selectWorkers: any[] = [] public selectWorkers: any[] = []
@@ -632,6 +647,7 @@ export default class ProjList extends Vue {
id_parent: this.idProjAtt, id_parent: this.idProjAtt,
privacyread: tools.getprivacyreadbytipoproj(tipoproj), privacyread: tools.getprivacyreadbytipoproj(tipoproj),
privacywrite: tools.getprivacywritebytipoproj(tipoproj), privacywrite: tools.getprivacywritebytipoproj(tipoproj),
tipovisu: TipoVisu.inherited
} }
if (projatt) { if (projatt) {
@@ -647,6 +663,7 @@ export default class ProjList extends Vue {
myobj.actualphase = projatt.actualphase myobj.actualphase = projatt.actualphase
myobj.privacyread = projatt.privacyread myobj.privacyread = projatt.privacyread
myobj.privacywrite = projatt.privacywrite myobj.privacywrite = projatt.privacywrite
myobj.tipovisu = projatt.tipovisu
} }
} }

View File

@@ -106,6 +106,7 @@
<!--<q-infinite-scroll :handler="loadMoreTodo" :offset="7">--> <!--<q-infinite-scroll :handler="loadMoreTodo" :offset="7">-->
<!--<div class="container" v-dragula="projs_dacompletare(idProjAtt, gettipoProj)" drake="second"> --> <!--<div class="container" v-dragula="projs_dacompletare(idProjAtt, gettipoProj)" drake="second"> -->
<div class="container"> <div class="container">
<q-list bordered>
<div :id="tools.getmyid(myproj._id)" :index="index" <div :id="tools.getmyid(myproj._id)" :index="index"
v-for="(myproj, index) in projs_dacompletare(idProjAtt, gettipoProj)" v-for="(myproj, index) in projs_dacompletare(idProjAtt, gettipoProj)"
:key="myproj._id" class="myitemdrag"> :key="myproj._id" class="myitemdrag">
@@ -120,6 +121,7 @@
</SingleProject> </SingleProject>
</div> </div>
</q-list>
</div> </div>
</div> </div>
<q-separator></q-separator> <q-separator></q-separator>
@@ -218,6 +220,17 @@
</q-select> </q-select>
</div> </div>
</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.tipovisu"
:options="selectTipoVisu"
@input="modifyfieldproj('tipovisu')"
:label="$t('proj.tipovisu')" emit-value map-options>
</q-select>
</div>
</div>
<div v-if="CanISeeProjectSel" class="flex-container clMain"> <div v-if="CanISeeProjectSel" class="flex-container clMain">
<q-icon class="flex-item flex-icon" name="lock"/> <q-icon class="flex-item flex-icon" name="lock"/>
<div class="flex-item itemstatus"> <div class="flex-item itemstatus">

View File

@@ -6,6 +6,7 @@ import Global = WebAssembly.Global
import { CalendarStore, GlobalStore, UserStore } from '@store' import { CalendarStore, GlobalStore, UserStore } from '@store'
import { colors, Screen, Platform, date } from 'quasar' import { colors, Screen, Platform, date } from 'quasar'
import { tools } from '@src/store/Modules/tools' import { tools } from '@src/store/Modules/tools'
import { shared_consts } from '@src/common/shared_vuejs'
@Component({ @Component({
@@ -21,10 +22,23 @@ export default class Report extends MixinBase {
calendar: any calendar: any
} }
public resourceHeight = 100
public valfilter: number = 0
public arrfilters = [
// { label: 'Responsabili', value: 1, ris: false },
{ label: 'Attività', value: 2, ris: false }
]
public mounted() { public mounted() {
this.load()
}
public load() {
const date_start = tools.addDays(new Date(tools.getTimestampsNow()), -90) const date_start = tools.addDays(new Date(tools.getTimestampsNow()), -90)
const date_end = tools.addDays(new Date(tools.getTimestampsNow()), 365) const date_end = tools.addDays(new Date(tools.getTimestampsNow()), 30)
UserStore.actions.reportload({ date_start, date_end }) UserStore.actions.reportload({ date_start, date_end, filter: this.valfilter })
.then((myris) => { .then((myris) => {
if (!!myris) { if (!!myris) {
console.log('myris', myris) console.log('myris', myris)
@@ -36,10 +50,12 @@ export default class Report extends MixinBase {
public calendarNext() { public calendarNext() {
this.$refs.calendar.next() this.$refs.calendar.next()
console.log('SelectedDate', this.selectedDate)
} }
public calendarPrev() { public calendarPrev() {
this.$refs.calendar.prev() this.$refs.calendar.prev()
console.log('SelectedDate', this.selectedDate)
} }
public getEventDate(eventparam) { public getEventDate(eventparam) {
@@ -68,43 +84,35 @@ export default class Report extends MixinBase {
return (new Date(myevent.dateTimeEnd) >= datenow) return (new Date(myevent.dateTimeEnd) >= datenow)
} }
public badgeStyles(eventparam, type, timeStartPos, timeDurationHeight) { public badgeStyles(eventparam) {
const s = { color: '', top: '', height: '', opacity: 1 } const s = { color: '', top: '', height: '', opacity: 1 }
if (tools.isCssColor(eventparam.bgcolor)) { if (tools.isCssColor(eventparam.bgcolor)) {
s['background-color'] = eventparam.bgcolor s['background-color'] = eventparam.bgcolor
s.color = colors.luminosity(eventparam.bgcolor) > 0.5 ? 'black' : 'white' s.color = colors.luminosity(eventparam.bgcolor) > 0.5 ? 'black' : 'white'
} }
if (timeStartPos) {
s.top = timeStartPos(tools.getstrTime(eventparam.dateTimeStart)) + 'px'
}
if (timeDurationHeight) {
s.height = timeDurationHeight(this.func_tools.getMinutesDuration(eventparam.dateTimeStart, eventparam.dateTimeEnd)) + 'px'
}
if (!this.isEventEnabled(eventparam)) { // if (!this.isEventEnabled(eventparam)) {
s.opacity = 0.5 // s.opacity = 0.5
} // }
s['align-items'] = 'flex-start' s['align-items'] = 'flex-start'
return s return s
} }
public getEvents(dt, objres) { public getEvents(dt, objres) {
console.log('dt', dt, 'objres', objres)
const eventsloc = [] const eventsloc = []
if (!!this.arrhour[objres.username]) { if (!!this.arrhour[objres.username]) {
if (this.arrhour[objres.username].length > 0) { if (this.arrhour[objres.username].length > 0) {
this.arrhour[objres.username].forEach((item) => { this.arrhour[objres.username].forEach((item) => {
if (item) { if (item) {
if (tools.getstrYYMMDDDate(item.date) === dt) { if (tools.getstrYYMMDDDate(item.date) === dt.date) {
if (eventsloc.length > 0) { // console.log('dt', dt, 'objres', objres, 'this.arrhour[objres.username]', this.arrhour[objres.username])
// check for overlapping times // console.log('Eccolo!', item)
eventsloc.push(item) eventsloc.push(item)
} }
} }
}
}) })
} }
} }
@@ -126,4 +134,21 @@ export default class Report extends MixinBase {
return arr return arr
} }
public refreshFilter() {
this.valfilter = 0
for (const filter of this.arrfilters) {
if (filter.ris)
this.valfilter += filter.value
if (filter.value === shared_consts.REPORT_FILT_ATTIVITA && filter.ris) {
this.resourceHeight = 120
} else {
this.resourceHeight = 60
}
}
this.load()
}
} }

View File

@@ -2,11 +2,21 @@
<q-page> <q-page>
<div> <div>
<CTitleBanner title="Report"></CTitleBanner> <CTitleBanner title="Report"></CTitleBanner>
<div v-for="filter in arrfilters">
<q-toggle dark color="green" v-model="filter.ris" :label="filter.label"
@input="refreshFilter"></q-toggle>
</div>
</div>
<q-calendar <q-calendar
v-model="selectedDate" v-model="selectedDate"
ref="calendar" ref="calendar"
view="week-scheduler" view="week-scheduler"
:weekdays="[1,2,3,4,5,6,0]"
animated animated
:resource-height="resourceHeight"
:resource-width="60"
transition-prev="slide-right" transition-prev="slide-right"
transition-next="slide-left" transition-next="slide-left"
:resources="resources" :resources="resources"
@@ -26,13 +36,33 @@
<template #scheduler-resource-day="{ timestamp, /* index, */ resource }"> <template #scheduler-resource-day="{ timestamp, /* index, */ resource }">
<template v-for="(event, index) in getEvents(timestamp, resource)"> <template v-for="(event, index) in getEvents(timestamp, resource)">
<div v-if="event.totalhours > 0" class="centermydiv">
<p
:key="index"
class="flex justify-center text-h7"
>
{{ event.totalhours }}
</p>
</div>
<div v-if="event.totalacchours > 0" class="row justify-center items-center">
<p
:key="index"
class="flex justify-center text-h7 boldhigh text-blue"
>
Tot: {{ event.totalacchours }}
</p>
</div>
<div v-if="!!event.title">
<q-badge <q-badge
:key="index" :key="index"
class="my-event justify-center ellipsis" class="my-event justify-center ellipsis"
:class="badgeClasses(event, 'body')"
:style="badgeStyles(event)"
> >
<!--<q-icon v-if="event.icon" :name="event.icon" class="q-mr-xs"></q-icon>-->
<span class="ellipsis">{{ event.title }}</span> <span class="ellipsis">{{ event.title }}</span>
</q-badge> </q-badge>
</div>
<!--<q-icon v-if="event.icon" :name="event.icon" class="q-mr-xs"></q-icon>-->
</template> </template>
</template> </template>