Ngiler SH3LL 360
Home
Information
Create File
Create Folder
:
/
home
/
tbf
/
membru.tbf.ro
/
src
/
components
/
Pages
/
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 :
Users.vue
| Size :
19.83
KB
Copy
<template> <div v-if="loaded" class="opacity-page"> <div class="fe-btn-translation" @click="$root.$emit('open_modal_translation', 'Users', arrayTranslations)" v-if="globalTranslate">OPEN TRANSLATION</div> <div class="item-page" v-if="notPaid"> <not-paid></not-paid> </div> <div class="item-page" v-else-if="notAllowed"> <not-allowed></not-allowed> </div> <div class="list-page-tbf people-page" v-else-if="users.length && !notAllowed"> <section class="header-list-page-section"> <div class="space-left"> <img src="/build/icons/search-disabled.svg" /> </div> <div class="content-section"> <div class="header-table"> <div class="left-part"> <input type="text" name="search" :placeholder="$t('filter_users.search_by_name')" id="inputSearch" v-model="search_text" autocomplete="off" class="search-box"> </div> <div class="right-part"> <div class="action-header filter-tags dropdown-tbf"> <button class="btn-default-tbf" id="dropdownFilter" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" v-if="$resize && $mq.above(600)"> <span class="value" v-if="selectedTags.length">{{ selectedTags.length == 1 ? tags.find(el => el.id == selectedTags[0]).name : $t('filter_users.selected', {n: selectedTags.length}) }}</span> <span class="value" v-else>{{ $t('filter_users.search_tags') }}</span> <icon-arrow class="icon-arrow" v-if="selectedTags.length == 0"/> <img class="clearFilter" src="/build/icons/close.svg" @click.stop="clearSelectedTags" v-else> </button> <button class="btn-default-tbf" id="dropdownFilter" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" v-else><icon-filter /></button> <div class="dropdown-menu" aria-labelledby="dropdownFilter"> <div class="filter-dropdown"> <input type="text" v-model="searchTags" :placeholder="$t('filter_users.search_tag_by_name')"> </div> <div class="dropdown-list-checkboxes"> <div v-for="tag in filteredTags" class="dropdown-item" @click.stop="selectTag(tag)" v-bind:class="{active: selectedTags.includes(tag.id)}"> <div class="checkmark"></div><span class="text">{{ tag.name }}</span> </div> </div> </div> </div> <div class="action-header filter-date filter-promises dropdown-tbf" v-if="$resize && $mq.above(600)"> <button class="btn-default-tbf" id="dropdownFilter" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"> {{ $t('filter_users.' + activeStatus) }} <icon-arrow class="icon-arrow" v-if="activeStatus == 'promises-all'"/> <img class="clearFilter" src="/build/icons/close.svg" @click.stop="activeStatus = 'promises-all'" v-else> </button> <div class="dropdown-menu" aria-labelledby="dropdownFilter"> <div v-for="objStatus in acceptedStatuses" class="dropdown-item" @click="changeActiveStatus(objStatus)" v-bind:class="{active: activeStatus == objStatus}"> {{ $t('filter_users.option-'+objStatus) }} </div> </div> </div> <div class="action-header add-button" v-if="$auth.user().rights.can_create"> <button class="button-tbf-blue" @click="$auth.user().rights.can_create_user ? showModal('user') : openModalV2('cant_create_more', false, 'users')"><icon-plus class="white" />{{ $resize && $mq.above(600) ? $t('users.title_new') : ''}}</button> </div> </div> </div> </div> <div class="space-right"></div> </section> <section class="list-items-section" v-if="filteredUsers.length"> <div class="group_items" v-for="user in filteredUsers"> <div class="space-left"> <icon-arrow :id="'arrow-key-result-' + user.id" class="icon-arrow right"/> </div> <div class="content-row"> <div class="row-tbf action-row" @click="showProfile(user.slug)" v-bind:class="{'viewEdit': hoverUser == user.id}"> <div class="column-tbf user-img user-img-width"> <div class="user-circle"> <img :src="user.avatar" v-if="user.avatar"> <!-- <img src="/build/icons/avatar-missing.svg" class="no-avatar" v-else> --> <icon-user-settings v-else /> </div> </div> <div class="column-tbf row-title user-name-width"> <div class="text-medium" v-html="highlight(user.first_name.charAt(0).toUpperCase() + user.first_name.slice(1) + ' ' + user.last_name, search_text)"></div> <div class="group-tags" v-if="$resize && $mq.above(600)"> <div class="tag-color" v-bind:class="['color-' + tag.color_name, user.tags.length > 4 && index == 3 ? 'default-color' : '' ]" v-for="(tag, index) in user.tags.slice(0, 4)"> <div v-if="(user.tags.length <= 4) || (index != 3 && user.tags.length > 4)"><span></span>#{{ tag.name.toLowerCase() }}</div> <div v-if="user.tags.length > 4 && index == 3"><span></span>{{ '+' + (user.tags.length - 3) }}</div> </div> </div> </div> <div class="column-tbf column-value user-objectives-width" v-if="$resize && $mq.above(780)"> <div class="label">{{ $t('users.objectives')}}</div> <div class="value">{{ $t('users.assigned', {n: user.objectives_count}) }}</div> </div> <div class="column-tbf column-value user-key-results-width" v-if="$resize && $mq.above(780)"> <div class="label">{{ $t('users.key-results')}}</div> <div class="value">{{ $t('users.assigned', {n: user.key_results_count}) }}</div> </div> <div class="column-tbf column-value user-promise-width" v-if="$resize && $mq.above(600)"> <v-popover offset="5" trigger="hover" placement="bottom" popoverBaseClass="popover-tbf" :delay="{show: 200, hide: 0}"> <div class="label">{{$t('users.daily_promise')}}</div> <div class="value" v-if="user.has_daily_promise == 'has_promise'"><img class="circle-info" src="/build/icons/circle-check-green.svg"> {{ $t('users.promise_set') }}</div> <div class="value" v-else-if="user.has_daily_promise == 'promise_not_set'"><img class="circle-info" src="/build/icons/circle-info-red.svg"> {{ $t('users.promise_not_set') }}</div> <div class="value" v-else>{{ $t('users.promise_not_need') }}</div> <template slot="popover"> <div class="description" v-if="user.has_daily_promise == 'has_promise'">{{ user.promise.name }}</div> <div class="description" v-else-if="user.has_daily_promise == 'promise_not_set'">{{ $t('key-result-promises.not-set') }}</div> <div class="description" v-else>{{ $t('key-result-promises.promise-not-need') }}</div> <div class="objective-name" v-if="user.has_daily_promise == 'has_promise'"> <div class="label">{{ $t('key-result-promises.contribute-to') }}</div> <span>{{ user.promise.key_results_names }}</span> </div> </template> </v-popover> </div> </div> </div> <div class="space-right"> <div class="dots-edit" :id="'edit-key-result-' + user.id" v-click-outside="hideDropdown" v-if="user.rights.edit || user.rights.delete"> <div class="dropdown edit-item-dropdown"> <div class="overlay-button" @click.stop="showDropdown(user.id)"> </div> <div class="edit-item-button" :id="'dropdownEdit'+user.id" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"> <icon-edit-dots /> </div> <div class="dropdown-menu dropdown-menu-right" :id="'dropdownMenu'+ user.id " :aria-labelledby="'dropdownEdit'+user.id"> <div class="dropdown-item" @click.stop="showModal('user', user.slug)" v-if="user.rights.edit">{{$t('users.edit')}}</div> <div class="dropdown-item" @click.stop="openModalV2('delete', user, 'user', 'users')" v-if="user.rights.delete && $auth.user().id != user.id">{{$t('users.delete')}}</div> </div> </div> </div> </div> </div> </section> <section class="list-items-section" v-else> <div class="group_items"> <div class="space-left"></div> <div class="empty-row full"> <div class="icon"> <img src="/build/icons/no-results-found.svg"> </div> <div class="title"> {{$t('users.no-user')}} </div> <div class="description narrow" v-html="$t('users.desc-narrow')"> </div> <div class="add-button" v-if="$auth.user().rights.can_create"> <button class="button-tbf-blue" @click="showModal('user')"><icon-plus class="white" />Adauga om</button> </div> </div> <div class="space-right"></div> </div> </section> </div> <div div class="list-page-tbf people-page" v-else> <section class="list-items-section"> <div class="group_items"> <div class="space-left"></div> <div class="empty-row full"> <div class="icon"> <icon-user-empty /> </div> <div class="title"> {{$t('users.no-user-you')}} </div> <div class="description narrow"> {{$t('users.desc-narrow')}} </div> <div class="add-button" v-if="$auth.user().rights.can_create"> <button class="button-tbf-blue" @click="showModal('user')"><icon-plus class="white" />{{$t('users.title_new')}}</button> </div> </div> <div class="space-right"></div> </div> </section> </div> </div> <div v-else> <div class="list-page-tbf people-page"> <section class="header-list-page-section"> <div class="space-left"> <img src="/build/icons/search-disabled.svg" /> </div> <div class="content-section"> <div class="header-table"> <div class="left-part"> <div class="placeholder-loader" style="width: 150px; height: 24px"></div> </div> <div class="right-part"> <div class="placeholder-loader" style="min-width: 36px; width:100%; max-width: 140px; height: 37px; margin-right: 15px;"></div> <div class="placeholder-loader" style="min-width: 36px; width:100%; max-width: 130px; height: 37px; margin-right: 15px;" v-if="$resize && $mq.above(600)"></div> <div class="placeholder-loader" style="min-width: 36px; width:100%; max-width: 130px; height: 37px"></div> </div> </div> </div> <div class="space-right"></div> </section> <section class="list-items-section"> <div class="group_items" v-for="n in 5"> <div class="space-left"> <icon-arrow class="icon-arrow right"/> </div> <div class="content-row"> <div class="row-tbf"> <div class="column-tbf user-img user-img-width"> <div class="placeholder-loader user" style="height: 51px; width: 51px;"></div> </div> <div class="column-tbf row-title user-name-width"> <div class="text-medium placeholder-loader" style="height: 21px; width: 150px;"></div> <div class="group-tags"> <div class="placeholder-loader" style="height: 11px; width: 100px;"></div> </div> </div> <div class="column-tbf row-details user-key-results-width" v-if="$resize && $mq.above(780)"> <div class="placeholder-loader" style="height: 16px; width: 170px;"></div> </div> <div class="column-tbf row-details user-objectives-width" v-if="$resize && $mq.above(780)"> <div class="placeholder-loader" style="height: 16px; width: 140px;"></div> </div> <div class="column-tbf status user-promise-width" v-if="$resize && $mq.above(600)"> <div class="placeholder-loader" style="height: 16px; width: 160px;"></div> </div> </div> </div> <div class="space-right"> <div class="dots-edit"> <div class="dropdown edit-item-dropdown"> <div class="overlay-button"></div> <div class="edit-item-button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false"> <icon-edit-dots /> </div> </div> </div> </div> </div> </section> </div> </div> </template> <script type="text/javascript"> import EmptyPage from '../General/EmptyPage' import NotAllowed from '../General/NotAllowed' import NotPaid from '../General/NotPaid' import IconUserSettings from '../Icons/UserSettings' import IconPlus from '../Icons/Plus' import IconArrow from '../Icons/Arrow' import IconFilter from '../Icons/Filter' import IconEditDots from '../Icons/EditDots' export default { data() { return { loaded: false, search_text: '', users: [], notAllowed: '', notPaid: false, activeStatus: 'promises-all', acceptedStatuses: ['promises-all','promises-completed','promises-not-completed'], hoverUser: '', tags: [], selectedTags: [], searchTags: '', arrayTranslations: [ 'filter_users.no-tags', 'filter_users.option-promises-all', 'filter_users.option-promises-completed', 'filter_users.option-promises-not-completed', 'filter_users.promises-all', 'filter_users.promises-completed', 'filter_users.promises-not-completed', 'filter_users.search_by_name', 'filter_users.search_tag_by_krs', 'filter_users.search_tag_by_name', 'filter_users.search_tags', 'filter_users.selected', 'users.title_new', 'users.objectives', 'users.assigned', 'users.key-results', 'users.daily_promise', 'users.promise_set', 'users.promise_not_set', 'users.promise_not_need', 'key-result-promises.not-set', 'key-result-promises.promise-not-need', 'key-result-promises.contribute-to', 'users.edit', 'users.delete', 'users.no-user', 'users.desc-narrow', 'users.no-user-you', 'users.desc-narrow', 'navbar.people', ] }; }, components: { EmptyPage, NotAllowed, NotPaid, IconUserSettings, IconPlus, IconArrow, IconFilter, IconEditDots }, async mounted() { if(this.$auth.user().status == 'unpaid' || this.$auth.user().status == 'new'){ this.loaded = true this.notPaid = true setTimeout(() => { $('.opacity-page').addClass('show') var title = this.$t('navbar.people'); this.$root.$emit("navbar_title", title) }, 0) }else{ await this.getTags() await this.getUsers() } // filters if(this.acceptedStatuses.includes(this.$route.query.status)){ this.activeStatus = this.$route.query.status; } if(this.$route.query.tags && this.$route.query.tags != ""){ this.selectedTags = this.$route.query.tags.split(",").map(function(item) { return parseInt(item, 10); }); } if(this.$route.query.name && this.$route.query.name != ""){ this.search_text = this.$route.query.name; } // End filters this.$root.$on("refreshUsersList", () => { this.getUsers() }); }, beforeDestroy () { this.$root.$off('refreshUsersList') }, computed: { filteredUsers(){ return getByPromise(getByTags(getByKeyword(this.users, this.search_text), this.selectedTags), this.activeStatus) }, filteredTags(){ return getByKeywordTags(this.tags, this.searchTags) } }, watch: { search_text: function(val) { var data = Object.assign({}, this.$route.query); data['name'] = this.search_text; if(this.$route.query.name != this.search_text){ this.$router.push({query : data }); } } }, methods: { async getTags(){ await axios.get('/' + this.$auth.user().instance_id + '/tags') .then(({data}) => { this.tags = data.data }) }, async getUsers(){ await axios.get('/' + this.$auth.user().instance_id + '/people') .then(({data}) => { this.users = data.data }).catch(error => { var status = error.response.data.status this.notAllowed = status == 'not allowed' this.notPaid = status == 'payment_failed' || status == 'first_registration' if(status == 'error' && error.response.data.message == 'Unauthorized'){ this.$auth.refresh() setTimeout(() => { if(this.$auth.check()){ location.reload() } }, 300) } }) .then(() => { setTimeout(()=>{ this.loaded = true var title = this.$t('navbar.people'); this.$root.$emit("navbar_title", title) setTimeout(() => { $('.opacity-page').addClass('show') }, 0) }, 300) }) }, showModal(type, model = false, requiredData = false, userData = false){ if(model){ this.hideDropdown() } this.$root.$emit('open_modal', type, model, requiredData, userData, 'users'); }, openModalV2(type, model = false, typeDelete = false, fromDelete = false){ this.hideDropdown() this.$root.$emit('open_modal_v2', type, model, typeDelete, fromDelete); }, showProfile(userSlug){ this.$router.push({ name: 'show-user', params: { slug: userSlug }}) }, showDropdown(itemId){ if(itemId == this.hoverUser){ $('#dropdownEdit' + this.hoverUser).dropdown('toggle'); setTimeout(() => { this.hoverUser = '' }, 0) }else{ this.hoverUser = itemId setTimeout(() => { $('#dropdownEdit' + this.hoverUser).dropdown('toggle'); }, 0) } }, hideDropdown(){ if(this.hoverUser != ''){ $('#dropdownEdit' + this.hoverUser).dropdown('toggle'); setTimeout(() => { this.hoverUser = '' }, 0) } }, highlight(text, query){ String.prototype.replaceBetween = function(start, end, what) { return this.substring(0, start) + what + this.substring(end); }; if(query != ''){ var regex = new RegExp( query ,'ig'); var new_text = text var match = '' var match_obj = [] while ((match = regex.exec(text)) != null) { match_obj.push({ text_replace: text.substring(match.index, match.index+query.length), start_position: match.index, end_position: match.index+query.length }) } match_obj.reverse() if(match_obj.length){ match_obj.forEach(element => { new_text = new_text.replaceBetween(element.start_position, element.end_position, '<mark class="highlight">' + element.text_replace + '</mark>') }) } return new_text }else{ return text } }, changeActiveStatus(status){ this.activeStatus = status; var data = Object.assign({}, this.$route.query); data['status'] = status; if(this.$route.query.status != status){ this.$router.push({query : data }); } }, selectTag(item){ if(this.selectedTags.includes(parseInt(item.id))){ this.selectedTags.splice(this.selectedTags.indexOf(parseInt(item.id)), 1) }else{ this.selectedTags.push(parseInt(item.id)) } this.searchTags = '' this.addTagsToRouteQuery() }, clearSelectedTags(){ this.selectedTags = [] this.addTagsToRouteQuery() }, addTagsToRouteQuery(){ var data = Object.assign({}, this.$route.query); data['tags'] = this.selectedTags.toString(); this.$router.push({query : data }); } } }; function getByKeyword(list, keyword) { const search = keyword.trim() if (!search.length) return list return list.filter(item => (item.first_name + ' ' + item.last_name).toLowerCase().indexOf(search.toLowerCase()) > -1) } function getByKeywordTags(list, keyword) { const search = keyword.trim() if (!search.length) return list return list.filter(item => item.name.toLowerCase().indexOf(search.toLowerCase()) > -1) } function getByTags(list, tags) { if (tags.length == 0) return list return list.filter(item => item.tags.some(r => tags.indexOf(r.id) >= 0)) } function getByPromise(list, status){ if (status == 'promises-all') return list if(status == 'promises-completed'){ return list.filter(item => item.promise) }else if(status == 'promises-not-completed'){ return list.filter(item => !item.promise) } } </script> <style> @import "../../../node_modules/@syncfusion/ej2-base/styles/material.css"; /*@import "../../../node_modules/@syncfusion/ej2-inputs/styles/material.css";*/ @import "../../../node_modules/@syncfusion/ej2-vue-dropdowns/styles/material.css"; @import "../../../node_modules/@syncfusion/ej2-buttons/styles/material.css"; </style>
Back