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_ALL: 131072,
REPORT_FILT_RESP: 1,
REPORT_FILT_ATTIVITA: 2,
Permissions: {
Admin: {
value: 1,

View File

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

View File

@@ -10,7 +10,7 @@ $heightdescr: 20px;
.flex-container2 {
flex-flow: row wrap;
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
@@ -79,7 +79,7 @@ $heightdescr: 20px;
}
.pos-go {
order: 1;
// order: 1;
}
@@ -163,8 +163,10 @@ $heightdescr: 20px;
padding-bottom: 4px;
max-width: 36px;
min-width: 32px;
flex: 1;
order: 1;
display: inline-block;
vertical-align: middle;
// flex: 1;
// order: 1;
}
.progrbar-item {
@@ -393,3 +395,13 @@ $heightdescr: 20px;
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 { lists } from '../../../store/Modules/lists'
import { IProject } from '../../../model/index'
import { IProject, TipoVisu } from '../../../model/index'
import { SubMenusProj } from '../SubMenusProj'
import { CDate } from '../../CDate'
@@ -14,6 +14,7 @@ import { CDate } from '../../CDate'
import { date } from 'quasar'
import { GlobalStore } from '@store'
import { RouteNames } from '@src/router/route-names'
import { shared_consts } from '@src/common/shared_vuejs'
@Component({
components: { SubMenusProj, CDate },
@@ -51,6 +52,17 @@ export default class SingleProject extends Vue {
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
@Watch('itemproject.enableExpiring')
@@ -143,6 +155,11 @@ export default class SingleProject extends Vue {
this.watchupdate('privacywrite')
}
@Watch('itemproject.tipovisu')
public valueChanged_tipovisu() {
this.watchupdate('tipovisu')
}
@Watch('itemproject.totalphases')
public valueChangedtotalphases() {
this.watchupdate('totalphases')
@@ -196,8 +213,8 @@ export default class SingleProject extends Vue {
public updateClasses() {
// this.classCompleted = 'completed-item'
this.classDescr = 'flex-item div_descr show donotdrag'
this.classDescrEdit = 'flex-item div_descr_edit donotdrag'
this.classDescr = ''
this.classDescrEdit = 'div_descr_edit donotdrag'
if (!this.isProject()) {
this.classDescr += ' titleLista-item'
this.classDescrEdit += ' titleLista-item'
@@ -208,7 +225,7 @@ export default class SingleProject extends Vue {
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.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,81 +1,98 @@
<template>
<div :class="getClassRow()" @click="clickProject">
<q-item @click="clickProject" clickable>
<q-btn
v-if="isProject()"
:class="(itemproject.respUsername !== '' && itemproject.viceRespUsername !== '') ? 'clresp' : 'clrespempty' + ' clButtPopover pos-item'"
:readonly="!CanIModifyProject"
size="sm"
dense
flat
@mousedown="clickRiga"
:disable="!CanIModifyProject"
icon="menu">
<q-menu ref="popmenu" self="top right">
<SubMenusProj :menuPopupProj="menuPopupProj" :itemproject="itemproject" @clickMenu="clickMenu"
@selectSubMenu="selectSubMenu"></SubMenusProj>
</q-menu>
</q-btn>
<!--<div :class="(itemproject.respUsername !== '' && itemproject.viceRespUsername !== '') ? 'clresp' : 'clrespempty' + ' pos-group flex-item'">
<q-icon class="" name="fas fa-user-friends"></q-icon>
</div>-->
<!--<div class="q-mx-xs"></div>-->
<q-item-section avatar>
<q-btn
v-if="isProject()"
:class="(itemproject.respUsername !== '' && itemproject.viceRespUsername !== '') ? 'clresp' : 'clrespempty' + ' clButtPopover pos-item'"
:readonly="!CanIModifyProject"
size="sm"
dense
flat
@mousedown="clickRiga"
:disable="!CanIModifyProject"
icon="menu">
<q-menu ref="popmenu" self="top right">
<SubMenusProj :menuPopupProj="menuPopupProj" :itemproject="itemproject" @clickMenu="clickMenu"
@selectSubMenu="selectSubMenu"></SubMenusProj>
</q-menu>
</q-btn>
</q-item-section>
<q-item-section>
<div class="flex-item donotdrag divdescrTot">
<q-input v-if="(sel && inEdit)" hide-underline type="textarea" ref="inputprojdescr"
v-model.trim="precDescr"
autogrow
borderless
:label="getlabeltext"
dense
@focus="getFocus($event)"
:class="classDescrEdit" :max-height="100"
@keydown="keyDownArea" v-on:keydown.esc="exitEdit" @blur="exitEdit(true)" @click="editProject()">
</q-input>
<div :class="getClassRow()">
<!--<div :class="(itemproject.respUsername !== '' && itemproject.viceRespUsername !== '') ? 'clresp' : 'clrespempty' + ' pos-group flex-item'">
<q-icon class="" name="fas fa-user-friends"></q-icon>
</div>-->
<!--<div class="q-mx-xs"></div>-->
<div v-else :class="classDescr"
@keydown="keyDownRow">
<q-item-label>
<div class="flex-item donotdrag">
<q-input v-if="(sel && inEdit)" hide-underline type="textarea" ref="inputprojdescr"
v-model.trim="precDescr"
autogrow
borderless
:label="getlabeltext"
dense
@focus="getFocus($event)"
:class="classDescrEdit" :max-height="100"
@keydown="keyDownArea" v-on:keydown.esc="exitEdit" @blur="exitEdit(true)" @click="editProject()">
</q-input>
<!--<div class="clpos">{{ itemproject.pos }}.</div> -->
{{ itemproject.descr }}
<div v-else :class="classDescr"
@keydown="keyDownRow">
<!--<div class="clpos">{{ itemproject.pos }}.</div> -->
{{ itemproject.descr }}
</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>
{{ tools.getGroupById(itemproject.groupId) }}
</div>-->
<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>
</div>
<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
stripe
rounded
:value="percentageProgress / 100"
class="progrbar-item"
:color="colProgress"
>
</q-linear-progress>
<div :class="percProgress">
{{ percentageProgress }}%
</div>
</div>
<q-btn :disable="isDisable" class="pos-go" size="sm" push color="primary" round
icon="arrow_forward"
:to="getrouteto">
<!--<div>
{{ tools.getGroupById(itemproject.groupId) }}
</div>-->
</q-btn>
</q-item-label>
</q-item-section>
</q-item>
<div v-if="isProject()" class="flex-item donotdrag progress-item shadow-1">
<q-linear-progress
stripe
rounded
:value="percentageProgress / 100"
class="progrbar-item"
:color="colProgress"
>
</q-linear-progress>
<div :class="percProgress">
{{ percentageProgress }}%
</div>
</div>
<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"
:to="getrouteto">
</q-btn>
</div>
</template>
<script lang="ts" src="./SingleProject.ts">

View File

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

View File

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

View File

@@ -180,6 +180,11 @@ namespace Getters {
return ris
}, '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) => {
if (table === tools.TABEVENTS)
return CalendarStore.state.eventlist
@@ -308,6 +313,10 @@ namespace Getters {
return getListByTable()
},
get getRespByUsername() {
return getRespByUsername()
},
get getCmdClick() {
return getCmdClick()
},

View File

@@ -1,5 +1,5 @@
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 Api from '@api'
@@ -30,7 +30,7 @@ const stateglob: IProjectsState = {
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',
'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']
@@ -50,6 +50,19 @@ function getFirstInherited(proj, idparent, state) {
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) {
if (!stateglob.projects) {
return []
@@ -128,7 +141,8 @@ namespace Getters {
themebgcolor: '',
groupId: '',
respUsername: '',
viceRespUsername: ''
viceRespUsername: '',
tipovisu: 0
}
return obj
@@ -236,6 +250,27 @@ namespace Getters {
}, '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 => {
if ((proj === undefined) || (proj === null))
return false
@@ -266,6 +301,9 @@ namespace Getters {
get CanIModifyPanelPrivacy() {
return CanIModifyPanelPrivacy()
},
get getTipoVisuProj() {
return getTipoVisuProj()
},
get getRecordEmpty() {
return getRecordEmpty()
},
@@ -449,6 +487,7 @@ namespace Actions {
objproj.privacyread = myobj.privacyread
objproj.privacywrite = myobj.privacywrite
objproj.actualphase = myobj.actualphase
objproj.tipovisu = myobj.tipovisu
let elemtochange: IProject = null

View File

@@ -19,7 +19,7 @@ import {
IParamDialog,
IProject,
ITodo,
Privacy
Privacy, TipoVisu
} from '@src/model'
import * as ApiTables from '@src/store/Modules/ApiTables'
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: {
it: [
{
@@ -2587,6 +2612,11 @@ export const tools = {
return isNaN(dayOfWeek) ? '' : myday[lang][dayOfWeek].substring(0, 3)
},
isSunday(mydate) {
const dayOfWeek = new Date(mydate).getDay()
return dayOfWeek === 0
},
getDateNowEvent() {
return tools.addDays(tools.getDateNow(), -1)
},
@@ -2650,8 +2680,7 @@ export const tools = {
getprivacywritebytipoproj(tipoproj) {
return Privacy.inherited
}
,
},
addRoute(myarr, values) {
myarr.push(values)

View File

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

View File

@@ -17,11 +17,14 @@
<br>
<!--
<div class="row">
<q-btn label="Crea Utenti Test" color="primary" @click="EseguiFunz('creaUtentiTest')"></q-btn>
<br>
</div>
<!--<div class="row">
<div class="row">
<q-btn label="Passa i codici Telefoni sul campo cell" color="primary"
@click="EseguiFunz('changeCellInt')"></q-btn>
<br></div>
@@ -59,18 +62,18 @@
@click="EseguiFunz('delNaviNoStarted')"></q-btn>
<br>
</div>-->
<!--
<div class="row">
<q-btn label="Rigenera (Elim, Genera Graduat, Add Navi Temp" color="positive" size="lg"
@click="EseguiFunz('rigeneraTutto')"></q-btn>
<!--<q-btn label="Crea ListaIngresso" color="positive" @click="EseguiFunz('creaLista')"></q-btn>-->
</div>
<br>
<div class="row">
<q-btn label="Elimina Navi Provvisorie" color="negative"
@click="EseguiFunz('delNaviProvvisorie')"></q-btn>
<!--<q-btn label="Crea ListaIngresso" color="positive" @click="EseguiFunz('creaLista')"></q-btn>-->
</div>
<q-btn label="Genera Graduatoria" color="primary"
@click="EseguiFunz('GeneraGraduatoria')"></q-btn>
@@ -100,16 +103,6 @@
:serv="false"
:type="tools.FieldType.number">
</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"
mykey="VISU_TEST"
:serv="false"
@@ -136,14 +129,6 @@
<q-btn label="Visualizza Lista Nave" color="primary" @click="EseguiFunz('visuListaNave')"></q-btn>
</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"
@click="EseguiFunz('AggiornaIndiceGraduatoria')"></q-btn>
@@ -179,13 +164,7 @@
@click="EseguiFunz('mettiSognoePaypal')"></q-btn>
<br>
</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">
<q-btn label="1) CONVERTI TUTTA LA STRUTTURA NEL NUOVO SISTEMA !" color="negative"
@click="EseguiFunz('creaTessituraeConv')"></q-btn>
@@ -201,14 +180,8 @@
@click="EseguiFunz('RendiVisibileIrecordNascosti')"></q-btn>
<br>
</div>
-->
<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">
<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>
<br>
</div>
-->
</div>
<div class="row">
<q-btn label="Correggi Tabella Hours con userId" color="negative"
@click="EseguiFunz('CorreggiTabHours')"></q-btn>
<br>
</div>

View File

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

View File

@@ -18,12 +18,12 @@
<div :class="classTitleProjSelBread">
<div v-if="canShow">
<q-breadcrumbs gutter="xs">
<q-breadcrumbs-el v-for="(crumb, index) in listacrumb"
:key="index"
:label="crumb.description"
:to="getroutebyid(crumb.idelem)"/>
</q-breadcrumbs>
<q-breadcrumbs gutter="xs">
<q-breadcrumbs-el v-for="(crumb, index) in listacrumb"
:key="index"
:label="crumb.description"
:to="getroutebyid(crumb.idelem)"/>
</q-breadcrumbs>
</div>
<div v-else>
Progetti:
@@ -106,20 +106,22 @@
<!--<q-infinite-scroll :handler="loadMoreTodo" :offset="7">-->
<!--<div class="container" v-dragula="projs_dacompletare(idProjAtt, gettipoProj)" drake="second"> -->
<div class="container">
<div :id="tools.getmyid(myproj._id)" :index="index"
v-for="(myproj, index) in projs_dacompletare(idProjAtt, gettipoProj)"
:key="myproj._id" class="myitemdrag">
<q-list bordered>
<div :id="tools.getmyid(myproj._id)" :index="index"
v-for="(myproj, index) in projs_dacompletare(idProjAtt, gettipoProj)"
:key="myproj._id" class="myitemdrag">
<SingleProject ref="singleproject" @deleteItemproj="mydeleteitemproj(myproj._id)"
@eventupdateproj="updateitemproj"
@idsel="setidsel"
@deselectAllRowsproj="deselectAllRowsproj"
@deselectAllRowstodo="deselectAllRowstodo" @onEnd="onEndproj"
:itemproject='myproj'>
<SingleProject ref="singleproject" @deleteItemproj="mydeleteitemproj(myproj._id)"
@eventupdateproj="updateitemproj"
@idsel="setidsel"
@deselectAllRowsproj="deselectAllRowsproj"
@deselectAllRowstodo="deselectAllRowstodo" @onEnd="onEndproj"
:itemproject='myproj'>
</SingleProject>
</SingleProject>
</div>
</div>
</q-list>
</div>
</div>
<q-separator></q-separator>
@@ -218,6 +220,17 @@
</q-select>
</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">
<q-icon class="flex-item flex-icon" name="lock"/>
<div class="flex-item itemstatus">

View File

@@ -6,6 +6,7 @@ import Global = WebAssembly.Global
import { CalendarStore, GlobalStore, UserStore } from '@store'
import { colors, Screen, Platform, date } from 'quasar'
import { tools } from '@src/store/Modules/tools'
import { shared_consts } from '@src/common/shared_vuejs'
@Component({
@@ -21,10 +22,23 @@ export default class Report extends MixinBase {
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() {
this.load()
}
public load() {
const date_start = tools.addDays(new Date(tools.getTimestampsNow()), -90)
const date_end = tools.addDays(new Date(tools.getTimestampsNow()), 365)
UserStore.actions.reportload({ date_start, date_end })
const date_end = tools.addDays(new Date(tools.getTimestampsNow()), 30)
UserStore.actions.reportload({ date_start, date_end, filter: this.valfilter })
.then((myris) => {
if (!!myris) {
console.log('myris', myris)
@@ -36,10 +50,12 @@ export default class Report extends MixinBase {
public calendarNext() {
this.$refs.calendar.next()
console.log('SelectedDate', this.selectedDate)
}
public calendarPrev() {
this.$refs.calendar.prev()
console.log('SelectedDate', this.selectedDate)
}
public getEventDate(eventparam) {
@@ -68,41 +84,33 @@ export default class Report extends MixinBase {
return (new Date(myevent.dateTimeEnd) >= datenow)
}
public badgeStyles(eventparam, type, timeStartPos, timeDurationHeight) {
public badgeStyles(eventparam) {
const s = { color: '', top: '', height: '', opacity: 1 }
if (tools.isCssColor(eventparam.bgcolor)) {
s['background-color'] = eventparam.bgcolor
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)) {
s.opacity = 0.5
}
// if (!this.isEventEnabled(eventparam)) {
// s.opacity = 0.5
// }
s['align-items'] = 'flex-start'
return s
}
public getEvents(dt, objres) {
console.log('dt', dt, 'objres', objres)
const eventsloc = []
if (!!this.arrhour[objres.username]) {
if (this.arrhour[objres.username].length > 0) {
this.arrhour[objres.username].forEach((item) => {
if (item) {
if (tools.getstrYYMMDDDate(item.date) === dt) {
if (eventsloc.length > 0) {
// check for overlapping times
eventsloc.push(item)
}
if (tools.getstrYYMMDDDate(item.date) === dt.date) {
// console.log('dt', dt, 'objres', objres, 'this.arrhour[objres.username]', this.arrhour[objres.username])
// console.log('Eccolo!', item)
eventsloc.push(item)
}
}
})
@@ -126,4 +134,21 @@ export default class Report extends MixinBase {
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,41 +2,71 @@
<q-page>
<div>
<CTitleBanner title="Report"></CTitleBanner>
<q-calendar
v-model="selectedDate"
ref="calendar"
view="week-scheduler"
animated
transition-prev="slide-right"
transition-next="slide-left"
:resources="resources"
:locale="toolsext.getLocale()"
>
<!-- eslint-disable vue/no-unused-vars -->
<template #scheduler-resources-header>
<div class="row justify-center items-center">
<q-btn flat icon="fas fa-chevron-left" @click="calendarPrev" />
<q-btn flat icon="fas fa-chevron-right" @click="calendarNext" />
<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
v-model="selectedDate"
ref="calendar"
view="week-scheduler"
:weekdays="[1,2,3,4,5,6,0]"
animated
:resource-height="resourceHeight"
:resource-width="60"
transition-prev="slide-right"
transition-next="slide-left"
:resources="resources"
:locale="toolsext.getLocale()"
>
<!-- eslint-disable vue/no-unused-vars -->
<template #scheduler-resources-header>
<div class="row justify-center items-center">
<q-btn flat icon="fas fa-chevron-left" @click="calendarPrev"/>
<q-btn flat icon="fas fa-chevron-right" @click="calendarNext"/>
</div>
<!--<div class="full-height row justify-center items-center">
<q-btn label="here"/>
</div>-->
</template>
<template #scheduler-resource-day="{ timestamp, /* index, */ 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 class="full-height row justify-center items-center">
<q-btn label="here"/>
</div>-->
</template>
<template #scheduler-resource-day="{ timestamp, /* index, */ resource }">
<template v-for="(event, index) in getEvents(timestamp, resource)">
<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
:key="index"
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>
</q-badge>
</template>
</div>
<!--<q-icon v-if="event.icon" :name="event.icon" class="q-mr-xs"></q-icon>-->
</template>
</template>
</q-calendar>
</q-calendar>
</div>
</q-page>
</template>