This commit is contained in:
2025-07-16 21:52:57 +03:00
parent b51a472738
commit 3e43efc70d
31 changed files with 801 additions and 391 deletions

View File

@@ -8,7 +8,7 @@
v-model="search"
clearable
clear-icon="close"
:placeholder="$t('project_chats__search')"
:placeholder="$t('chats__search')"
dense
class="col-grow"
v-if="chats.length !== 0"
@@ -71,8 +71,8 @@
<pn-onboard-btn
v-if="chats.length === 0 && chatsInit"
icon="mdi-chat-plus-outline"
:message1="$t('project_chat__onboard_msg1')"
:message2="$t('project_chat__onboard_msg2')"
:message1="$t('chats__onboard_msg1')"
:message2="$t('chats__onboard_msg2')"
@click="showOverlay=true; fabState=true"
/>
<div
@@ -110,7 +110,7 @@
anchor="center left" self="center end"
style="width: calc(min(100vw, var(--body-width)) - 102px) !important;"
>
{{ $t('project_chats_disabled_FAB')}}
{{ $t('chats_disabled_FAB')}}
</q-tooltip>
</template>
<q-fab-action
@@ -152,9 +152,10 @@
v-model="showDialogDeleteChat"
icon="mdi-link-off"
color="negative"
title="project_chat__delete_warning"
message1="project_chat__delete_warning_message"
mainBtnLabel="project_chat__dialog_cancel_ok"
title="chats__dialog_unlink_title"
message1="chats__dialog_unlink_message"
message2="chats__dialog_unlink_message2"
mainBtnLabel="chats__dialog_unlink_ok"
@clickMainBtn="onConfirm()"
@close="onCancel()"
@before-hide="onDialogBeforeHide()"
@@ -190,8 +191,8 @@
const chatsInit = computed(() => chatsStore.isInit)
const fabMenu = [
{id: 1, icon: 'mdi-chat-plus-outline', name: 'project_chats__attach_chat', description: 'project_chats__attach_chat_description', func: attachChat},
{id: 2, icon: 'mdi-share-outline', name: 'project_chats__send_chat', description: 'project_chats__send_chat_description', func: sendChat},
{id: 1, icon: 'mdi-chat-plus-outline', name: 'chats__attach_chat', description: 'chats__attach_chat_description', func: attachChat},
{id: 2, icon: 'mdi-share-outline', name: 'chats__send_chat', description: 'chats__send_chat_description', func: sendChat},
]
const displayChats = computed(() => {
@@ -253,7 +254,7 @@
const key = await chatsStore.getKey()
const message = urlAdmin + key + urlAdminPermission
const tgShareUrl = 'https://t.me/share/url?url=' +
encodeURIComponent( t('project_chats__send_chat_title')) +
encodeURIComponent( t('chats__send_chat_title')) +
'&text=' + `${encodeURIComponent(message)}`
tg.openTelegramLink(tgShareUrl)
}

View File

@@ -7,7 +7,7 @@
:color="companies.length <= 2 ? 'grey-6' : 'primary'"
flat
no-caps
@click="maskCompany()"
@click="maskCompany"
:disable="companies.length <= 2"
class="q-pr-md"
rounded
@@ -16,9 +16,10 @@
left
size="sm"
name="mdi-domino-mask"
class="q-mr-xs"
/>
<div>
{{ $t('company__mask')}}
{{ $t('companies__mask')}}
</div>
</q-btn>
</div>
@@ -53,7 +54,7 @@
<q-item-label lines="1" class="text-caption text-amber-10" v-if="item.id === myCompany?.id">
<div class="flex items-center">
<q-icon name="star" class="q-pr-xs"/>
{{ $t('company__my_company') }}
{{ $t('companies__my_company') }}
</div>
</q-item-label>
<q-item-label lines="1" class="text-bold">{{ item.name }}</q-item-label>
@@ -93,9 +94,9 @@
<pn-onboard-btn
v-if="companies.length <= 1 && companiesInit"
icon="mdi-account-multiple-plus-outline"
:message1="$t('company__onboard_msg1')"
:message2="$t('company__onboard_msg2')"
@btn-click="createCompany()"
:message1="$t('companies__onboard_msg1')"
:message2="$t('companies__onboard_msg2')"
@btn-click="createCompany"
/>
<div
class="flex column justify-center items-center w100"
@@ -130,9 +131,10 @@
v-model="showDialogDeleteCompany"
icon="mdi-account-multiple-minus-outline"
color="negative"
title="company__dialog_delete_title"
message1="company__dialog_delete_message"
mainBtnLabel="company__dialog_delete_ok"
title="companies__dialog_delete_title"
message1="companies__dialog_delete_message"
message2="companies__dialog_delete_message2"
mainBtnLabel="companies__dialog_delete_ok"
@clickMainBtn="onConfirm()"
@close="onCancel()"
@before-hide="onDialogBeforeHide()"

View File

@@ -7,7 +7,7 @@
v-model="search"
clearable
clear-icon="close"
:placeholder="$t('project_users__search')"
:placeholder="$t('users__search')"
dense
class="col-grow"
>
@@ -60,27 +60,92 @@
</q-slide-item>
</q-list>
<!-- LEAVE USERS SECTION -->
<div
v-if="leaveUsers.length!==0"
class="flex column items-center w100"
:class="showLeaveUsers ? 'bg-grey-12' : ''"
>
<q-btn
class="w100 rotate-icon-btn"
color="grey"
flat
no-caps
@click="showLeaveUsers=!showLeaveUsers"
icon-right="arrow_drop_down"
:class="{ 'rotate-icon': showLeaveUsers }"
>
<span class="text-caption">
{{ !showLeaveUsers
? $t('users__show_left_users') + ' (' + leaveUsers.length +')'
: $t('users__hide_left_users')
}}
</span>
</q-btn>
<div class="w100" style="overflow: hidden">
<transition
appear
enter-active-class="animated slideInDown"
leave-active-class="animated slideOutUp"
>
<q-list separator v-if="showLeaveUsers" class="w100">
<q-item
v-for = "item in leaveUsers"
:key="item.id"
class="w100 text-grey"
>
<q-item-section avatar>
<pn-auto-avatar
:img="item.photo"
:name="item.section1"
/>
</q-item-section>
<q-item-section>
<q-item-label lines="1" class="text-bold" v-if="item.section1">
{{item.section1}}
</q-item-label>
<q-item-label lines="1" caption v-if="item.section3">
{{item.section3}}
</q-item-label>
<q-item-label caption lines="2">
<div class="flex items-center">
<q-icon name="telegram" v-if="item.section2_1 || item.section2_2" class="q-pr-xs" style="color: #27a7e7"/>
<div v-if="item.section2_1" class="q-mr-sm text-bold">{{item.section2_1}}</div>
<div class="text-blue" v-if="item.section2_2">{{'@' + item.section2_2}}</div>
</div>
</q-item-label>
</q-item-section>
</q-item>
</q-list>
</transition>
</div>
</div>
<!-- END LEAVE USERS SECTION -->
<!-- BLOCKED USERS SECTION -->
<div
v-if="blockedUsers.length!==0"
class="flex column items-center w100"
:class="showBlockedUsers ? 'bg-grey-12' : ''"
>
<q-btn-dropdown
class="w100 fix-rotate-arrow"
<q-btn
class="w100 rotate-icon-btn"
color="grey"
flat no-caps
flat
no-caps
@click="showBlockedUsers=!showBlockedUsers"
dropdown-icon="arrow_drop_up"
icon-right="arrow_drop_down"
:class="{ 'rotate-icon': showBlockedUsers }"
>
<template #label>
<span class="text-caption">
{{ !showBlockedUsers
? $t('users__show_archive') + ' (' + blockedUsers.length +')'
: $t('user__hide_archive')
}}
</span>
</template>
</q-btn-dropdown>
<span class="text-caption">
{{ !showBlockedUsers
? $t('users__show_blocked_users') + ' (' + blockedUsers.length +')'
: $t('users__hide_blocked_users')
}}
</span>
</q-btn>
<div class="w100" style="overflow: hidden">
<transition
@@ -123,12 +188,13 @@
</transition>
</div>
</div>
<!-- END BLOCKED USERS SECTION -->
<pn-onboard-btn
v-if="users.length === 0 && usersInit"
icon="mdi-account-outline"
:message1="$t('project_users__onboard_msg1')"
:message2="$t('project_users__onboard_msg2')"
:message1="$t('users__onboard_msg1')"
:message2="$t('users__onboard_msg2')"
noBtn
/>
<div
@@ -142,13 +208,14 @@
</div>
<pn-small-dialog
v-model="showDialogDeleteUser"
v-model="showDialogBlockUser"
icon="mdi-account-remove-outline"
color="negative"
title="user__dialog_delete_title"
message1="user__dialog_delete_message"
mainBtnLabel="user__dialog_delete_ok"
@clickMainBtn="onConfirmDeleteUser()"
title="users__dialog_block_title"
message1="users__dialog_block_message"
message2="users__dialog_block_message2"
mainBtnLabel="users__dialog_block_ok"
@clickMainBtn="onConfirmBlockUser()"
@close="onCancel()"
@before-hide="onDialogBeforeHide()"
/>
@@ -157,9 +224,10 @@
v-model="showDialogRestoreUser"
icon="mdi-account-reactivate-outline"
color="green"
title="user__dialog_restore_title"
message1="user__dialog_restore_message"
mainBtnLabel="user__dialog_restore_ok"
title="users__dialog_restore_title"
message1="users__dialog_restore_message"
message2="users__dialog_restore_message2"
mainBtnLabel="users__dialog_restore_ok"
@clickMainBtn="onConfirmRestoreUser()"
/>
@@ -183,12 +251,18 @@
const users = usersStore.getUsers
const usersInit = computed(() => usersStore.isInit)
const deleteUserId = ref<number | undefined>(undefined)
const showDialogDeleteUser = ref<boolean>(false)
const blockUserId = ref<number | undefined>(undefined)
const showDialogBlockUser = ref<boolean>(false)
const currentSlideEvent = ref<SlideEvent | null>(null)
const closedByUserAction = ref(false)
const mapUsers = computed(() => users.map(el => ({...el, ...userSection(el)})))
const mapUsers = computed(() => users.map(el => ({
...el,
...userSection(el),
companyName: el.company_id && companiesStore.companyById(el.company_id)
? companiesStore.companyById(el.company_id)?.name
: null
})))
interface SlideEvent {
reset: () => void
@@ -202,12 +276,13 @@
el.section1.toLowerCase().includes(searchValue) ||
el.section2_1.toLowerCase().includes(searchValue) ||
el.section2_2.toLowerCase().includes(searchValue) ||
el.section3.toLowerCase().includes(searchValue)
el.section3.toLowerCase().includes(searchValue) ||
el.companyName && el.companyName.toLowerCase().includes(searchValue)
)
return arrOut
})
const displayUsers = computed(() => displayUsersAll.value.filter(el => !el.is_block))
const displayUsers = computed(() => displayUsersAll.value.filter(el => !el.is_blocked))
function userSection (user: User) {
const tname = () => {
@@ -244,8 +319,8 @@
function handleSlide (event: SlideEvent, id: number) {
currentSlideEvent.value = event
showDialogDeleteUser.value = true
deleteUserId.value = id
showDialogBlockUser.value = true
blockUserId.value = id
}
function onDialogBeforeHide () {
@@ -263,26 +338,29 @@
}
}
async function onConfirmDeleteUser() {
async function onConfirmBlockUser() {
closedByUserAction.value = true
if (deleteUserId.value) {
await usersStore.blockUser(deleteUserId.value)
if (blockUserId.value) {
await usersStore.blockUser(blockUserId.value)
}
currentSlideEvent.value = null
}
const showBlockedUsers = ref(false)
const blockedUsers = computed(() => displayUsersAll.value.filter(el => el.is_block))
const blockedUsers = computed(() => displayUsersAll.value.filter(el => el.is_blocked))
const unblockUserId = ref<number | undefined> (undefined)
const showDialogRestoreUser = ref(false)
const showLeaveUsers = ref(false)
const leaveUsers = computed(() => displayUsersAll.value.filter(el => el.is_leave))
function handleUnblockUser (id: number) {
showDialogRestoreUser.value = true
unblockUserId.value = id
}
async function onConfirmRestoreUser () {
if (unblockUserId.value) await usersStore.restore(unblockUserId.value)
if (unblockUserId.value) await usersStore.unblockUser(unblockUserId.value)
}
watch(showDialogRestoreUser, (newD :boolean) => {
@@ -293,5 +371,18 @@
</script>
<style>
<style scoped>
.rotate-icon-btn {
transition: transform 0.3s;
}
.rotate-icon-btn.rotate-icon :deep(.q-icon) {
transform: rotate(180deg);
transition: transform 0.3s cubic-bezier(0.25, 0.8, 0.5, 1);
}
.rotate-icon-btn :deep(.q-icon) {
transform: rotate(0deg);
transition: transform 0.3s cubic-bezier(0.25, 0.8, 0.5, 1);
}
</style>