Ngiler SH3LL 360
Home
Information
Create File
Create Folder
:
/
home
/
tbf
/
curs.tbf.ro
/
src
/
components
/
Modals
/
Information Server
MySQL :
OFF
Perl :
OFF
CURL :
ON
WGET :
OFF
PKEXEC :
OFF
Directive
Local Value
IP Address
89.40.16.97
System
Linux server.atelieruldeit.ro 3.10.0-1160.el7.x86_64 #1 SMP Mon Oct 19 16:18:59 UTC 2020 x86_64
User
tbf
PHP Version
7.3.33
Software
Apache
Doc root
Writable
close
Edit File :
KeyResultUpdates.vue
| Size :
17.06
KB
Copy
<template> <div class="container-modal"> <div class="header-modal"> <div class="tabs-title" v-if="$resize && $mq.above(660)"> <div class="tab-item active" @click="activateTab('updates')"> <span>{{ $t('general.updates') }}</span> </div> <div class="tab-item" @click="activateTab('promises')"> <span>{{ $t('general.promises') }}</span> </div> <div class="tab-item" @click="activateTab('tasks')"> <span>{{ $t('general.tasks') }}</span> </div> <div class="tab-item" @click="activateTab('comments')"> <span>{{ $t('key-result-comments.title') }}</span> </div> <div class="tab-item"> <v-popover offset="5" trigger="hover" placement="bottom" popoverBaseClass="popover-tbf description-popover" :delay="{show: 100, hide: 0}"> <icon-info /> <template slot="popover"> <div class="kr-title">{{ keyResult.name }}</div> <div class="kr-description">{{ keyResult.description }}</div> <div class="kr-info"> <div class="label">{{ $t('key-result-summary.progress-type') }}</div> <div class="label-desc" v-if="keyResult.target % 1 != 0 || keyResult.start_value % 1 != 0">{{ $t('progress_type_text_simple.' + keyResult.progress_type, { to: ($options.filters.numeral(parseFloat(keyResult.target), '0,0.00')), unit: keyResult.unity, from: $options.filters.numeral(parseFloat(keyResult.start_value), '0,0.00')}) }}</div> <div class="label-desc" v-else>{{ $t('progress_type_text_simple.' + keyResult.progress_type, { to: ($options.filters.numeral(parseFloat(keyResult.target), '0,0')), unit: keyResult.unity, from: $options.filters.numeral(parseFloat(keyResult.start_value), '0,0')}) }}</div> </div> <div class="kr-info"> <div class="label">{{ $t('key-result-summary.frequency-interval') }}</div> <div class="label-desc">{{ $t('key-result-updates.interval-update-desc') }} {{ $tc('days', keyResult.measurement) }}</div> </div> <div class="kr-info"> <div class="label">{{ $t('key-result-summary.period') }}</div> <div class="label-desc"><span class="date">{{ keyResult.start_date | moment('DD MMM') }}</span> {{ $t('key-result-summary.period-to') }} <span class="date">{{ keyResult.end_date | moment('DD MMM')}}</span></div> </div> </template> </v-popover> </div> </div> <div class="mobile-tabs" v-else> <button class="btn-default-tbf" id="dropdownFilter" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"> {{ $t('general.updates') }} <icon-arrow class="icon-arrow"/> </button> <div class="dropdown-menu" aria-labelledby="dropdownFilter"> <div class="dropdown-item" @click="activateTab('updates')">{{ $t('general.updates') }}</div> <div class="dropdown-item" @click="activateTab('promises')">{{ $t('general.promises') }}</div> <div class="dropdown-item" @click="activateTab('tasks')">{{ $t('general.tasks') }}</div> <div class="dropdown-item" @click="activateTab('comments')">{{ $t('key-result-comments.title') }}</div> </div> </div> <div class="actions"> <v-popover offset="5" trigger="click" placement="bottom" :disabled="keyResult.status != 'upcoming'" popoverBaseClass="popover-tbf" class="btn-space-mr" :delay="{show: 0, hide: 0}" v-if="$route.name != 'public-master-goal' && keyResult.rights.can_create"> <div class="btn-blue-tbf add-btn" @click="$auth.user().rights.can_create_key_result_logs ? (keyResult.status != 'upcoming' ? showSubModal('create_update') : '') : showCantAdd()" v-if="$route.name != 'public-master-goal'"><icon-plus class="icon-plus" /></div> <template slot="popover"> <div class="simple-text">{{ $t('key-result.tooltip-update-cant') }}</div> </template> </v-popover> <v-popover offset="5" trigger="hover" placement="bottom" popoverBaseClass="popover-tbf" class="btn-space-mr" :delay="{show: 500, hide: 0}" v-if="$route.name != 'public-master-goal' && keyResult.rights.can_create && parseInt(keyResult.percent) >= 100"> <button class="btn-default-tbf finish-kr" v-bind:class="{finished: keyResult.status == 'finished'}" @click="completeKr"><icon-check /></button> <template slot="popover"> <div class="simple-text">{{ keyResult.status == 'finished' ? $t('key-result.tooltip-not-finish-kr') : $t('key-result.tooltip-finish-kr') }}</div> </template> </v-popover> <div class="btn-default-tbf close-btn" @click="closeModal"><icon-plus class="icon-close" /></div> </div> </div> <div class="info-content"> <div class="container-content-modal opacity-page" v-if="loaded"> <div class="content-updates"> <div class="list-updates" v-if="key_result_logs.length > 0"> <div class="top-description" v-html="$t('key-result.top-updates-description', {start_date: moment(keyResult.start_date).format('DD MMM YYYY'), in_the_past: diffDaysFromCreate(keyResult.start_date), frec: keyResult.measurement, last_up_date: keyResult.diff_days_last_update})"></div> <div class="update-item" v-for="(update,index) in key_result_logs"> <div class="summary-update" :id="'summary_update_' + update.id" @click="update.value ? extendCollapse(update.id) : ''" v-bind:class="{disabled: !update.value}"> <div class="mood-img" v-if="$resize && $mq.above(660)"> <img :src="'/build/icons/mood-' + update.status + '-bw.svg'" v-if="update.value"> <img src="/build/icons/update-urgent.svg" v-else-if="update.needs_an_update"> <img src="/build/icons/update-waiting.svg" v-else> </div> <div class="date"> <div class="date-text">{{ update.created_at | moment('DD MMMM YYYY') }}</div> <div class="interval-days"> <div class="dot" v-bind:class="{'overdue': !update.was_made_in_interval}"></div> <div class="text">{{ index == 0 ? $tc('key-result-updates.days_from_createing_key_result', update.diff_days_from_last_log) : $tc('key-result-updates.days_from_last_update', update.diff_days_from_last_log) }}</div> </div> </div> <!-- last values box --> <div class="data-value" v-if="$resize && $mq.above(660)"> <div class="gauge-info" v-if="update.value % 1 != 0"> <div class="val">{{ update.value | numeral('0.00a') }} {{ optionsUnits[update.unity] ? update.unity : ''}}</div> <span>{{ !optionsUnits[update.unity] ? update.unity : optionsUnits[update.unity]}}</span> </div> <div class="gauge-info" v-else> <div class="value">{{ update.value | numeral('0a') }} {{ optionsUnits[update.unity] ? update.unity : ''}}</div> <span>{{ !optionsUnits[update.unity] ? update.unity : optionsUnits[update.unity]}}</span> </div> </div> <!-- end last values box --> <div class="progress-update" v-if="$resize && $mq.above(660)"> <v-popover offset="10" trigger="hover" placement="bottom" popoverBaseClass="popover-tbf" :delay="{show: 200, hide: 0}"> <div class="top-data"> <div class="current-value"> <div class="value">{{ update.key_result_percent + '%' }}</div> </div> <div class="info"><icon-info class="icon-info"/></div> </div> <div class="progress-bar-tbf"> <div class="complete-progress-tbf" v-bind:class="{pink: update.state == 'descending', green: update.state == 'ascending'}" :style="'width: calc(2px + ' + (parseInt(update.key_result_percent) < 1 ? '2px' : parseInt(update.key_result_percent) + '%') + ');'"></div> </div> <template slot="popover"> <div class="simple-text"> {{ $t('progress_type_text.' + keyResult.progress_type, { to: keyResult.target % 1 != 0 ? $options.filters.numeral(keyResult.target , '0,0.00') : $options.filters.numeral(keyResult.target , '0,0'), unit: keyResult.unity, from: keyResult.start_value % 1 != 0 ? $options.filters.numeral(keyResult.start_value , '0,0.00') : $options.filters.numeral(keyResult.start_value , '0,0')}) }}. {{ $t('progress_type_text.value') }}: {{ update.value % 1 != 0 ? $options.filters.numeral(update.value, '0,0.00') : $options.filters.numeral(update.value, '0,0')}} {{ update.unity }} </div> </template> </v-popover> </div> <div class="icon-dropdown"> <icon-arrow class="icon-arrow right" /> </div> </div> <div class="content" :id="'update_content_' + update.id"> <div class="description">{{ update.description }}</div> </div> </div> </div> <div class="empty-box" v-else-if="key_result_logs.length == 0"> <div class="empty-row"> <div class="title"> {{ keyResult.status == 'upcoming' ? $t('key-result.tooltip-update-cant') : $t('key-result.no-updates') }} </div> <div class="description" v-html="$t('key-result.no-updates-description', {start_date: moment(keyResult.start_date).format('DD MMM YYYY'), in_the_past: diffDaysFromCreate(keyResult.start_date), frec: keyResult.measurement, last_up_date: keyResult.diff_days_last_update})"> </div> </div> </div> </div> </div> <div class="container-content-modal" v-else> <div class="content-updates"> <div class="list-updates"> <div class="update-item" v-for="n in 3"> <div class="summary-update"> <div class="mood-img placeholder-loader" style="height: 41px; max-width: 41px; width: 100%;"></div> <div class="data-update placeholder-loader" style="margin-left: initial; height: 24px; max-width: 90px; width: 100px"></div> <div class="button-action placeholder-loader" style="height: 35px; max-width: 120px; width: 100px"></div> </div> </div> </div> </div> </div> </div> <div class="submodal-container" v-if="subModalShow"> <div class="overlay-submodal" @click="closeSubModal()"></div> <create-update v-if="show_subm_modal.create_update" id="submodal_create_update" :keyResult="keyResult" @close_modal="closeSubModal('create_update')" @refreshBack="emitRefresh" /> </div> </div> </template> <script type="text/javascript"> import IconPlus from "../Icons/Plus" import IconArrow from "../Icons/Arrow" import IconClose from "../Icons/Close" import IconCheck from "../Icons/Check" import IconInfo from "../Icons/Info" import IconInfoUpdates from "../Icons/InfoUpdates" import IconCircleCheck from "../Icons/CircleCheck" import IconList from '../Icons/List' import { required, decimal } from 'vuelidate/lib/validators' import CreateUpdate from "../SubModals/CreateUpdate" export default { data() { return { loaded: false, key_result_logs: [], selectedUpdate: '', lastUpdate: '', activeTooltip: '', update_key_result: { value: '', description: '', degree_of_confidence: '' }, optionsDegreeConfidence: ["uncertain","not_very_sure","sure"], subModalShow: false, show_subm_modal: { create_update: false }, activeSubModal: '', optionsUnits: { "€": 'Euro', "$": 'Dolar', "%": 'Procent', } }; }, components: { IconPlus, IconArrow, IconClose, IconCheck, IconInfo, IconList, IconInfoUpdates, IconCircleCheck, CreateUpdate }, props:{ keyResult: Object, Uuid: String }, validations: { update_key_result: { value: {required, decimal}, description: {required}, degree_of_confidence: {required} } }, async mounted() { await this.getUpdates() this.$root.$on("refreshKrLogs", () => { this.getUpdates() }); }, methods: { async getUpdates(){ await axios.get('/key-results/public/' + this.Uuid + '/key-result-logs') .then(({data}) => { this.key_result_logs = data.data var reverseArray = JSON.parse(JSON.stringify(this.key_result_logs)).reverse(); if(this.key_result_logs.length > 0){ var last_value_update = reverseArray.find(elem => elem.key_result_percent) if(last_value_update && last_value_update.state){ this.selectedUpdate = last_value_update this.lastUpdate = last_value_update } } }). then(() => { setTimeout(()=>{ this.loaded = true setTimeout(() => { $('.opacity-page').addClass('show') }, 0) }, 300) }) }, closeModal(){ this.$emit("toggle_modal_tab"); }, diffDays(end_date) { var a = moment().startOf('day'); var b = moment(end_date).startOf('day'); return b.diff(a, 'days'); }, diffDaysFromCreate(start_date) { var a = moment(start_date).startOf('day'); var b = moment().startOf('day'); return b.diff(a, 'days'); }, activateTab(type){ this.$emit("changeTab", type); }, extendCollapse(id){ document.getElementById('summary_update_' + id).classList.toggle("active"); var content = document.getElementById('update_content_' + id); if (content.style.maxHeight){ content.style.maxHeight = null; } else { content.style.maxHeight = content.scrollHeight + "px"; } }, expandUpdate(id){ document.getElementById('summary_update_' + id).classList.toggle("active"); var content = document.getElementById('expand_update_' + id); if (content.style.maxHeight){ content.style.maxHeight = null; } else { content.style.maxHeight = content.scrollHeight + "px"; } }, checkDiffUnity(unity){ var inlineUnits = ['€', '$', 'RON'] return inlineUnits.includes(unity) }, diffPercent(value){ if(value){ var percent = 0; var diffPercentVal = 0; switch (this.keyResult.progress_type) { case 'percentage': diffPercentVal = value - parseInt(this.keyResult.percent); return diffPercentVal < 0 ? diffPercentVal + '%' : '+' + diffPercentVal + '%'; case 'grow': percent = 100 - ((parseInt(this.keyResult.target) - value) / ((parseInt(this.keyResult.target) - parseInt(this.keyResult.start_value)) / 100)); diffPercentVal = percent - parseInt(this.keyResult.percent); return diffPercentVal < 0 ? diffPercentVal + '%' : '+' + diffPercentVal + '%'; case 'decrease': percent = 100 - ((value - parseInt(this.keyResult.target)) / ((parseInt(this.keyResult.start_value) - parseInt(this.keyResult.target)) / 100)); diffPercentVal = percent - parseInt(this.keyResult.percent); return diffPercentVal < 0 ? diffPercentVal + '%' : '+' + diffPercentVal + '%'; case 'above': percent = value > parseInt(this.keyResult.target) ? 100 : 0; diffPercentVal = percent - parseInt(this.keyResult.percent); return diffPercentVal < 0 ? diffPercentVal + '%' : '+' + diffPercentVal + '%'; case 'under': percent = value < parseInt(this.keyResult.target) ? 100 : 0; diffPercentVal = percent - parseInt(this.keyResult.percent); return diffPercentVal < 0 ? diffPercentVal + '%' : '+' + diffPercentVal + '%'; } }else{ return '0%' } }, submitUpdate(e, update){ $(e.target).attr('disabled', 'disabled') this.$v.$touch() if(!this.$v.$invalid){ axios.post('/' + this.keyResult.id + '/key-result-logs/store',{ key_result_id: this.keyResult.id, description: this.update_key_result.description, value: Number(this.update_key_result.value), status: this.update_key_result.degree_of_confidence, related_to_date: update.related_to_date }).then(({data}) => { $(e.target).attr('disabled', false) this.expandUpdate(update.related_to_date) this.update_key_result = { value: '', description: '', degree_of_confidence: ''} this.getUpdates() this.$emit('refresh') }) $(e.target).attr('disabled', false) }else{ $(e.target).attr('disabled', false) } }, showSubModal(type){ this.subModalShow = true this.show_subm_modal[type] = true this.activeSubModal = type setTimeout(() => { $('.submodal-container').addClass('active'); setTimeout(() => { $('#submodal_' + type).addClass('active'); }, 200); }, 0); }, closeSubModal(type = false){ var modalId = type ? type : this.activeSubModal $("#submodal_" + modalId).removeClass("active") setTimeout(() => { $('.submodal-container').removeClass('active') setTimeout(() => { this.subModalShow = false; this.show_subm_modal[modalId] = false }, 200); }, 200); }, emitRefresh(){ this.$emit('refresh') this.$emit('refreshModalData') }, showCantAdd(){ this.$root.$emit('change_modal', 'cant_add_more_updates') }, completeKr(e){ $(e.target).attr('disabled', 'disabled') var statusKr = this.keyResult.status == 'finished' ? 'active' : 'finished' axios.post(`/key-results/${this.keyResult.id}/update-status`, { status: statusKr }) .then(({data}) => { $(e.target).addClass('completed') setTimeout(() => { $(e.target).removeClass('completed') this.$emit('refreshModalData') this.$emit('refresh') }, 1500) }) .finally(() => { setTimeout(() => { $(e.target).attr('disabled', false) }, 2000) }) } } }; </script>
Back