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 :
KeyResultComments.vue
| Size :
15.13
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" @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 active" @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" :delay="{show: 0, 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">{{ $t('progress_type_text_simple.' + keyResult.progress_type, { to: ($options.filters.numeral(parseFloat(keyResult.target), '0a')), unit: keyResult.unity, from: $options.filters.numeral(parseFloat(keyResult.start_value), '0a')}) }}</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('key-result-comments.title') }} <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"> <div class="btn-blue-tbf add-btn btn-space-mr" @click="showAddComment" v-if="$route.name != 'public-master-goal'"><icon-plus class="icon-plus" /></div> <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="create-comment" v-if="viewCreateComment"> <div class="header-and-actions"> <div class="label">{{ $t('key-result-comments.label-description') }}</div> <div class="actions"> <button class="btn-default-tbf btn-delete" @click="viewCreateComment = false">{{ $t('key-result-comments.cancel') }}</button> <button class="btn-blue-tbf btn-save" @click="storeComment">{{ $t('key-result-comments.save') }}</button> </div> </div> <div class="input-comment" v-bind:class="{has_error: $v.newComment.description.$error}" > <textarea class="input-textarea" :placeholder="$t('key-result-comments.input-placeholder')" v-model="newComment.description" v-autosize rows="3"></textarea> </div> <div class="label-status">{{ $t('key-result-comments.label-status') }}</div> <div class="list-status-inputs" v-bind:class="{has_error: $v.newComment.status.$error}"> <div class="status-input" v-for="status in statusList" @click="newComment.status = status" v-bind:class="{selected: newComment.status == status}"> <div class="icon"> <img :src="'/build/icons/comment-status-' + status + '-active.svg'" class="active-icon"> <img :src="'/build/icons/comment-status-' + status + '.svg'" class="simple-icon"> </div> <div class="text">{{ $t('key-result-comments.status-' + status) }}</div> </div> </div> </div> <div class="list-tbf list-comments" v-if="comments.length > 0"> <div class="item-tbf item-comment" v-for="comment in comments"> <div class="main-comment"> <div class="user-avatar" v-bind:class="{red: comment.status == 'not_satisfied', yellow: comment.status == 'info', blue: comment.status == 'good_job' }"> <img :src="comment.user.avatar" v-if="comment.user.avatar"> <div class="user-circle" v-else> <icon-user-settings/> </div> <div class="user-name" v-if="$resize && $mq.below(600)">{{ comment.user.first_name + ' ' + comment.user.last_name }}</div> </div> <div class="data-comment"> <div class="header"> <div class="user-name" v-if="$resize && $mq.above(600)">{{ comment.user.first_name + ' ' + comment.user.last_name }}</div> <div class="created-at">{{ comment.created_at | moment('DD MMMM YYYY HH:mm') }}</div> <div class="status-comment"> <div class="icon"><img :src="'/build/icons/comment-status-' + comment.status + '.svg'"></div> <div class="text">{{ $t('key-result-comments.status-' + comment.status) }}</div> </div> </div> <textarea class="input-textarea-edit" v-model="currentEdit" v-autosize rows="1" ref="edit_input" v-if="currentEditComment == comment.id"></textarea> <div class="message" v-else>{{ comment.message }}</div> <div v-if="currentEditComment != comment.id"> <div class="inline-button edit-btn" v-if="$auth.user().id == comment.user.id && $route.name != 'public-master-goal'" @click="editComment(comment)">{{ $t('key-result-comments.edit-btn') }}</div> <div class="inline-button" @click="viewReplyPopulate(comment.id)" v-if="$route.name != 'public-master-goal'">{{ $t('key-result-comments.reply') }}</div> </div> <div v-else> <div class="inline-button cancel-btn" @click="cancelEdit(comment)">{{ $t('key-result-comments.cancel-btn') }}</div> <div class="inline-button save-btn" @click="updateComment(comment)">{{ $t('key-result-comments.save') }}</div> </div> </div> </div> <div class="main-comment" v-for="reply_comm in comment.replys.data"> <div class="user-avatar"> <img :src="reply_comm.user.avatar" v-if="reply_comm.user.avatar"> <div class="user-circle" v-else> <icon-user-settings/> </div> </div> <div class="data-comment"> <div class="header"> <div class="user-name">{{ reply_comm.user.first_name + ' ' + reply_comm.user.last_name }}</div> <div class="created-at">{{ reply_comm.created_at | moment('DD MMMM YYYY H:m') }}</div> <div class="actions"> <img src="/build/icons/reply-icn.svg"> </div> </div> <textarea class="input-textarea-edit" v-model="currentEdit" v-autosize rows="1" ref="edit_input" v-if="currentEditComment == reply_comm.id"></textarea> <div class="message" v-else>{{ reply_comm.message }}</div> <div v-if="currentEditComment != reply_comm.id"> <div class="inline-button edit-btn" v-if="$auth.user().id == reply_comm.user.id && $route.name != 'public-master-goal'" @click="editComment(reply_comm)">{{ $t('key-result-comments.edit-btn') }}</div> </div> <div v-else> <div class="inline-button cancel-btn" @click="cancelEdit(reply_comm)">{{ $t('key-result-comments.cancel-btn') }}</div> <div class="inline-button save-btn" @click="updateComment(reply_comm)">{{ $t('key-result-comments.save') }}</div> </div> </div> </div> <div class="main-comment create-reply" v-if="viewReply == comment.id"> <div class="user-avatar"> <img :src="$auth.user().avatar" v-if="$auth.user().avatar"> <div class="user-circle" v-else> <icon-user-settings/> </div> </div> <div class="data-comment"> <div class="input-reply"> <div class="header"> <div class="label">{{ $t('key-result-comments.reply-placeholder') }}</div> <div class="actions"> <button class="btn-default-tbf btn-save" @click="replyCommentSave(comment, $event)">{{ $t('key-result-comments.save') }}</button> <button class="btn-delete" @click="viewReply = ''"><icon-delete /></button> </div> </div> <textarea class="input-textarea" v-model="replyComment" v-autosize rows="1" ref="reply_input"></textarea> </div> </div> </div> </div> </div> <div class="empty-box" v-else-if="!viewCreateComment && comments.length == 0"> <div class="empty-row"> <div class="title"> {{ $t('key-result.no-comments') }} </div> <div class="description" v-html="$t('key-result.no-comments-description')"> </div> </div> </div> </div> <div class="container-content-modal" v-else> <div class="list-tbf list-comments"> <div class="item-tbf item-comment" v-for="n in 3"> <div class="main-comment"> <div class="user-avatar"> <div class="placeholder-loader" style="height: 40px; width: 40px;"></div> </div> <div class="data-comment"> <div class="header"> <div class="user-name"><div class="placeholder-loader" style="height: 16px; width: 100px;"></div></div> <div class="created-at"><div class="placeholder-loader" style="height: 16px; width: 90px;"></div></div> <div class="actions" > <div class="created-at"><div class="placeholder-loader" style="height: 30px; width: 100px;"></div></div> </div> </div> <div class="message"><div class="placeholder-loader" style="height: 16px; width: 250px;"></div></div> </div> </div> </div> </div> </div> </div> </div> </template> <script type="text/javascript"> import IconPlus from "../Icons/Plus" import IconCheck from "../Icons/Check" import IconDelete from "../Icons/Delete" import IconKeyResults from "../Icons/KeyResults" import IconArrow from "../Icons/Arrow" import IconInfo from "../Icons/Info" import IconList from '../Icons/List' import IconUserSettings from '../Icons/UserSettings' import { required, decimal } from 'vuelidate/lib/validators' export default { data() { return { loaded: false, viewCreateComment: false, comments: [], statusList: [], newComment: { description: '', status: '' }, replyComment: '', viewReply: '', currentEdit: '', currentEditComment: false }; }, props:{ keyResult: Object, keyResultId: String, Uuid: String }, components: { IconPlus, IconCheck, IconDelete, IconKeyResults, IconArrow, IconInfo, IconList, IconUserSettings }, validations: { newComment: { description: {required}, status: {required} } }, async mounted() { await this.getComments() if(this.$route.name != 'public-master-goal'){ await this.getStatusList() } }, methods: { async getComments(){ await axios.get('/key-results/public/' + this.Uuid + '/comments') .then(({data}) => { this.comments = data.data }) .then(() => { setTimeout(()=>{ this.loaded = true setTimeout(() => { $('.opacity-page').addClass('show') }, 0) }, 300) }) }, async getStatusList(){ await axios.get('/key-result-comments/status-list').then(({data}) => { this.statusList = data.data }) }, 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'); }, activateTab(type){ this.$emit("changeTab", type); }, showAddComment(){ this.viewCreateComment = true }, storeComment(e){ $(e.target).attr('disabled', 'disabled') this.$v.$touch() if(!this.$v.$invalid){ axios.post('/key-result-comments/store',{ key_result_id: this.keyResultId, message: this.newComment.description, status: this.newComment.status }).then(({data}) => { this.getComments() this.newComment = { description: '', status: ''} this.viewCreateComment = false $(e.target).attr('disabled', false); }) }else{ $(e.target).attr('disabled', false) } }, replyCommentSave(parent, e){ $(e.target).attr('disabled', 'disabled') if(this.replyComment != ''){ axios.post('/key-result-comments/store',{ key_result_id: this.keyResultId, parent_id: parent.id, status: parent.status, message: this.replyComment }).then(({data}) => { this.getComments() this.replyComment = '' this.viewReply = '' $(e.target).attr('disabled', false); }) }else{ $(e.target).attr('disabled', false) } }, viewReplyPopulate(commentId){ this.viewReply = commentId == this.viewReply ? '' : commentId setTimeout(() => { $('.input-reply textarea').focus() }, 100) }, editComment(comment){ this.currentEditComment = comment.id this.currentEdit = comment.message setTimeout(() => { this.$refs.edit_input[0].focus() }, 100) }, cancelEdit(comment){ this.currentEditComment = false this.currentEdit = '' }, updateComment(comment){ axios.patch('/key-result-comments/' + comment.id, { key_result_id: this.keyResultId, message: this.currentEdit, status: comment.status }).then((data) => { this.getComments().then(() => { setTimeout(() => { this.currentEditComment = false this.currentEdit = '' }, 100) }) }) }, 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