This commit is contained in:
2025-11-02 10:08:57 +03:00
parent 83d2666f22
commit d3d8b7522a
41 changed files with 518 additions and 496 deletions

View File

@@ -92,6 +92,7 @@
))
const showStopUsingDialog = ref(false)
async function goTo (path: string) {
if (path !== 'stop_using') {
await router.push({ name: path })

View File

@@ -4,12 +4,12 @@
{{$t('agreements__title')}}
</template>
<pn-scroll-list>
<div class="flex column w100 q-pa-md q-gutter-y-md">
<div>
<div class="flex column w100 q-py-md q-px-lg q-gutter-y-sm text-caption">
<div class="text-bold">
<div v-if="route.query.type === 'update'">{{ $t('agreements__description_update') }}</div>
<div>{{ $t('agreements__description') }}</div>
</div>
<div class="flex items-center no-wrap text-caption">
<div class="flex items-center no-wrap">
<q-checkbox v-model="agreement" val="1" class="q-pr-sm"/>
<span>
{{ $t('agreements__checkbox_agreement_terms') + ' ' }}
@@ -21,7 +21,7 @@
</span>
</span>
</div>
<div class="flex items-center no-wrap text-caption">
<div class="flex items-center no-wrap">
<q-checkbox v-model="agreement" val="2" class="q-pr-sm"/>
<span>
{{ $t('agreements__checkbox_agreement_consent') + ' ' }}
@@ -43,7 +43,7 @@
</div>
</pn-scroll-list>
<template #footer>
<div class="flex no-wrap justify-center w100 q-gutter-x-md q-pb-md">
<div class="flex no-wrap justify-center w100 q-gutter-x-md q-py-md">
<q-btn
flat
color="negative"

View File

@@ -4,14 +4,16 @@
{{ $t('chat_card__title') }}
</template>
<template #footer>
<q-btn
rounded color="primary"
class="w100 q-mt-md q-mb-xs"
@click = "onSubmit"
v-if="chat && chat.invite_link"
>
{{ $t("chat_card__go_chat") }}
</q-btn>
<div class="w100 q-pa-md">
<q-btn
rounded color="primary"
class="w100"
@click="onSubmit"
v-if="chat"
>
{{ $t("chat_card__go_chat") }}
</q-btn>
</div>
</template>
<pn-scroll-list>
@@ -118,18 +120,18 @@
watch(() => chatsStore.isInit, initChat)
async function onSubmit () {
if (chat.value && chat.value.invite_link) tg.openTelegramLink(chat.value.invite_link)
if (chat.value) tg.openTelegramLink('https://t.me/c/' + chat.value.telegram_id + '/' + chat.value.message_id)
if (chat.value) await chatsStore.getChatUsers(chat.value.id)
}
const users = usersStore.getUsers
const users = computed(() => usersStore.users)
const companiesStore = useCompaniesStore()
const { userSection } = useUserSection()
const chatUsers = computed(() => {
if (!chat.value) return []
const idSet = new Set(chat.value.users)
const arr = users.filter(el => idSet.has(el.id))
const arr = users.value.filter(el => idSet.has(el.id))
return arr.map(el => ({
...el,
...userSection(el),

View File

@@ -1,6 +1,5 @@
<template>
<company-block
v-model="newCompany"
title="company_add__title_card"
btnText="company_add__btn"
@update="addCompany"
@@ -8,7 +7,6 @@
</template>
<script setup lang="ts">
import { ref } from 'vue'
import { useRouter } from 'vue-router'
import companyBlock from 'components/companyBlock.vue'
import { useCompaniesStore } from 'stores/companies'
@@ -17,8 +15,6 @@
const router = useRouter()
const companiesStore = useCompaniesStore()
const newCompany = ref<CompanyParams>({} as CompanyParams)
async function addCompany(companyData: CompanyParams) {
await companiesStore.add(companyData)
router.go(-1)

View File

@@ -1,7 +1,6 @@
<template>
<company-block
v-if="company"
v-model="company"
:company
title="company_edit__title_card"
btnText="company_edit__btn"
@update="updateCompany"
@@ -12,6 +11,7 @@
<q-icon name="star" class="q-pr-xs"/>
{{ $t('company_edit__my_company') }}
</div>
<div class="flex column">
<div class="text-caption" align="center" style="white-space: pre-wrap;">
{{ $t('company_edit__my_company_hint') }}
@@ -26,45 +26,29 @@
</template>
<script setup lang="ts">
import { ref, computed, watch } from 'vue'
import { computed } from 'vue'
import { useRouter, useRoute } from 'vue-router'
import companyBlock from 'components/companyBlock.vue'
import { useCompaniesStore } from 'stores/companies'
import { parseIntString } from 'src/utils/helpers'
import { parseIntString } from 'utils/helpers'
import type { CompanyParams } from 'types/Company'
const router = useRouter()
const route = useRoute()
const companiesStore = useCompaniesStore()
const company = ref<CompanyParams | null>(null)
const companyId = computed(() => parseIntString(route.params.companyId))
function initCompany() {
if (companiesStore.isInit && companyId.value) {
const foundCompany = companiesStore.companyById(companyId.value)
if (foundCompany) {
company.value = foundCompany as CompanyParams
}
}
}
if (companiesStore.isInit) initCompany()
watch(() => companiesStore.isInit, (isInit) => {
if (isInit) initCompany()
})
const company = companyId.value && companiesStore.companyById(companyId.value) || {} as CompanyParams
async function goMyCompany () {
await router.push({ name: 'your_company' })
}
async function updateCompany (companyData: CompanyParams) {
if (companyId.value) {
await companiesStore.update(companyId.value, companyData)
router.go(-1)
}
async function updateCompany (company: CompanyParams) {
if (!companyId .value || !company) return
await companiesStore.update(companyId.value, company)
router.go(-1)
}
</script>

View File

@@ -16,7 +16,7 @@
<pn-scroll-list>
<template #card-body-header>
<div class="q-ma-sm q-pa-sm bg-grey-11 flex no-wrap items-center" style="border-radius: var(--top-raduis);">
<div class="q-ma-sm q-pa-sm bg-grey-11 flex no-wrap items-center" style="border-radius: var(--top-radius);">
<q-icon name="mdi-information q-pr-xs" size="sm" color="primary"/>
<span class="text-caption">
{{ $t('mask__info_block')}}

View File

@@ -238,6 +238,6 @@
<style scoped>
.login-card {
opacity: 0.9 !important;
border-radius: var(--top-raduis);
border-radius: var(--top-radius);
}
</style>

View File

@@ -1,6 +1,5 @@
<template>
<project-block
v-model="newProject"
title="project_create__title_card"
btnText="project_create__btn"
@update="addProject"
@@ -8,7 +7,6 @@
</template>
<script setup lang="ts">
import { ref } from 'vue'
import { useRouter } from 'vue-router'
import projectBlock from 'components/projectBlock.vue'
import { useProjectsStore } from 'stores/projects'
@@ -17,8 +15,6 @@
const router = useRouter()
const projectsStore = useProjectsStore()
const newProject = ref<ProjectParams>({} as ProjectParams)
async function addProject (projectData: ProjectParams) {
const newDataProject = await projectsStore.add(projectData)
await router.replace({ name: 'chats', params: { id: newDataProject.id }})

View File

@@ -1,7 +1,6 @@
<template>
<project-block
v-if="project"
v-model="project"
:project
title="project_edit__title_card"
btnText="project_edit__btn"
@update="updateProject"
@@ -9,7 +8,7 @@
</template>
<script setup lang="ts">
import { ref, computed, watch } from 'vue'
import { computed } from 'vue'
import { useRouter } from 'vue-router'
import projectBlock from 'components/projectBlock.vue'
import { useProjectsStore } from 'stores/projects'
@@ -18,27 +17,14 @@
const router = useRouter()
const projectsStore = useProjectsStore()
const project = ref<ProjectParams | null>(null)
const projectId = computed(() => projectsStore.currentProjectId)
if (projectsStore.isInit) {
project.value = projectId.value
? { ...projectsStore.projectById(projectId.value) } as ProjectParams
: null
}
watch(() => projectsStore.isInit, (isInit) => {
if (isInit && projectId.value && !project.value) {
project.value = { ...projectsStore.projectById(projectId.value) as ProjectParams }
}
})
const project = projectId.value && projectsStore.projectById(projectId.value) || {} as ProjectParams
async function updateProject (projectData: ProjectParams) {
if (projectId.value) {
await projectsStore.update(projectId.value, projectData)
router.go(-1)
}
if (!projectId .value || !project) return
await projectsStore.update(projectId.value, projectData)
router.go(-1)
}
</script>

View File

@@ -75,8 +75,8 @@
const usersStore = useUsersStore()
const companiesStore = useCompaniesStore()
const chatsQty = computed(() => chatsStore.getChats.length)
const usersQty = computed(() => usersStore.getUsers.length)
const chatsQty = computed(() => chatsStore.chats.length)
const usersQty = computed(() => usersStore.users.length)
const companiesQty = computed(() => companiesStore.getCompanies.length)
const tabs = ref([

View File

@@ -21,12 +21,12 @@
v-if="projects.length!==0 || archiveProjects.length!==0"
>
<q-input
v-if="projects.length!== 0"
v-if="projects.length!==0"
v-model="searchProject"
clearable
clear-icon="close"
:placeholder="$t('projects__search')"
dense
dense filled
class="col-grow q-px-md q-py-md"
>
<template #prepend>
@@ -61,16 +61,16 @@
/>
</q-item-section>
<q-item-section>
<q-item-label lines="1" class="text-bold">{{ item.name }}</q-item-label>
<q-item-label lines="1" class="text-bold">
{{ item.name }}
</q-item-label>
<q-item-label
caption lines="2"
style="max-width: -webkit-fill-available; white-space: pre-line"
>
{{ item.description }}
</q-item-label>
</q-item-section>
<q-item-section side top>
<q-item-label lines="1" class="text-caption">
<q-item-label lines="1" class="text-caption text-grey">
<div class="flex items-center">
<div class="flex items-center">
<q-icon name="mdi-chat-outline"/>
@@ -82,10 +82,12 @@
</div>
</div>
</q-item-label>
</q-item-section>
<q-item-section side>
<q-item-label>
<q-btn
color="grey"
size="sm"
size="md"
dense flat round
icon="mdi-pencil"
class="q-ml-sm"
@@ -225,7 +227,7 @@
const router = useRouter()
const projectsStore = useProjectsStore()
const projects = projectsStore.getProjects
const projects = computed(() => projectsStore.projects)
const projectsInit = computed(() => projectsStore.isInit)
const searchProject = ref('')
@@ -259,9 +261,9 @@
}
const displayProjects = computed(() => {
if (!searchProject.value || !(searchProject.value && searchProject.value.trim())) return projects
if (!searchProject.value || !(searchProject.value && searchProject.value.trim())) return projects.value
const searchChatValue = searchProject.value.trim().toLowerCase()
const arrOut = projects
const arrOut = projects.value
.filter((el: Project) =>
el.name.toLowerCase().includes(searchChatValue) ||
el.description && el.description.toLowerCase().includes(searchProject.value)

View File

@@ -1,7 +1,6 @@
<template>
<user-block
v-if="user"
v-model="user"
:user
title="user_edit__title_card"
btnText="user_edit__btn"
@update="updateUser"
@@ -9,38 +8,25 @@
</template>
<script setup lang="ts">
import { ref, computed, watch } from 'vue'
import { computed } from 'vue'
import { useRouter, useRoute } from 'vue-router'
import userBlock from 'components/userBlock.vue'
import { useUsersStore } from 'stores/users'
import { parseIntString } from 'src/utils/helpers'
import { parseIntString } from 'utils/helpers'
import type { User } from 'types/User'
const router = useRouter()
const route = useRoute()
const usersStore = useUsersStore()
const user = ref<User | null>(null)
const userId = computed(() => parseIntString(route.params.userId))
function initUser() {
if (usersStore.isInit && userId.value) {
const foundUser = usersStore.userById(userId.value)
if (foundUser) {
user.value = { ...foundUser } as User
}
}
}
const user = userId.value && usersStore.userById(userId.value) || {} as User
if (usersStore.isInit) initUser()
watch(() => usersStore.isInit, initUser)
async function updateUser (userData: User) {
if (userId.value) {
await usersStore.update(userId.value, userData)
router.go(-1)
}
async function updateUser (user: User) {
if (!userId .value || !user) return
await usersStore.update(userId.value, user)
router.go(-1)
}
</script>

View File

@@ -7,4 +7,4 @@
</script>
<style>
</style>
</style>

View File

@@ -8,107 +8,177 @@
</template>
<pn-scroll-list >
<div class="q-px-md">
<template #card-body-header>
<div
id="subscribe-current-balance"
class="flex w100 q-px-md q-py-sm row"
style="border-radius: var(--top-raduis); border: 1px solid var(--q-primary);"
class="flex w100 q-px-md q-py-md row"
>
<div class="flex w100 justify-between items-center no-wrap">
<div class="flex no-wrap items-center text-h6 col-9">
<div class="flex items-center text-grey">
{{ $t('subscribe__current_plan') }}
</div>
<div class="flex items-center column col-3">
<div class="flex items-center column text-right">
<span class="text-bold">
{{ currentPlanData?.name }}
</span>
<span class="text-caption" style="line-height: 0.5em;">
{{ $t('subscribe__plan_exp') }}
{{ date.formatDate(currentPlanData.exp * 1000, 'DD.MM.YYYY') }}
</span>
</div>
</div>
<div class="flex row w100 ow-wrap items-center text-caption q-pt-sm">
<div class="col-9">{{ $t('subscribe__plan_active_chats') }}</div>
<div class="col-3" align="center">
<span class="text-brand2 text-bold q-pr-xs">{{ currentPlanData?.active_chats }}</span>
<span class="text-grey">/{{ currentPlanData?.chatsQty }}</span>
<div
class="row w100 no-wrap items-center text-caption justify-between"
v-if="currentPlanData.name !== 'TEST'"
>
<div class="text-grey text-no-wrap ellipsis">
{{ $t('subscribe__plan_date') }}
</div>
</div>
</div>
<div class="flex w100 justify-center text-grey q-pt-md q-pb-none">{{ $t('subscribe__plans')}}</div>
<q-list separator>
<q-item
v-for="item in plans"
:key="item.id"
>
<q-item-section avatar>
<q-radio v-model="newPlan" :val="item" v-if="item.name!=='TEST'"/>
</q-item-section>
<q-item-section>
<q-item-label class="text-bold">{{ item.name }}</q-item-label>
<div class="flex no-wrap items-center text-caption">
<span v-if="item.chatsQty" class="q-pr-xs">
{{ $t('subscribe__chats_max') }}
</span>
<span v-if="item.chatsQty">
{{ item.chatsQty }}
</span>
<q-icon v-else name="mdi-all-inclusive" size="sm"/>
<span class="q-pl-xs">
{{ $t('subscribe__chats')}}
</span>
</div>
</q-item-section>
<q-item-section side>
<div v-if="item.price" class="flex column items-center">
<div class="flex no-wrap items-center">
<telegram-star color="gold" size="18px" class="q-mr-xs"/>
<span class="text-h6">{{ formatNumber(item.price) }}</span>
<span class="text-caption q-pl-xs">{{ $t('subscribe__per_month') }}</span>
</div>
</div>
<div v-else class="text-bold">
{{ $t('subscribe__free_tax') }}
</div>
</q-item-section>
</q-item>
</q-list>
<div class="flex w100 justify-center text-caption text-grey q-pt-sm text-center">
{{ $t('subscribe__plans_description') }}
</div>
<q-btn-group spread flat class="w100 q-py-sm">
<q-btn
v-for="period in periods"
:key="period.id"
:color="selectPeriod === period.value ? 'primary' : 'white'"
:text-color="selectPeriod === period.value ? 'white' : 'primary'"
@click="selectPeriod = period.value"
no-caps
>
<div class="column items-center w100 self-end">
<q-badge v-show="period.sale" color="red">{{ period.sale }}% off</q-badge>
<span>{{ $t(period.name) }}</span>
<span class="text-caption">({{ $t(period.name_in_days) }})</span>
</div>
</q-btn>
</q-btn-group>
<div class="text-caption column text-grey">
<span>{{ $t('subscribe__plans_period_notes') + ' ' }}</span>
<span
@click="router.push({ name: 'change_plan_rules' })"
class="text-info cursor-pointer"
>
{{ $t('subscribe__plans_period_notes_more_info') }}
<span class="text-no-wrap text-right">
{{ date.formatDate(currentPlanData.exp * 1000, 'DD.MM.YYYY') }}
</span>
</div>
<div class="row w100 no-wrap items-center text-caption text-grey justify-between">
<div>
{{ $t('subscribe__plan_active_chats') }}
</div>
<div class="text-right">
<span class="text-brand2 text-bold q-pr-xs">{{ currentPlanData?.active_chats }}</span>
<span>/{{ currentPlanData?.chatsQty }}</span>
</div>
</div>
</div>
</template>
<div class="w100 column items-center text-center text-grey q-px-md">
{{ $t('subscribe__plans')}}
<div class="text-caption">
{{ $t('subscribe__plans_description') }}
</div>
</div>
<q-list separator>
<q-item
v-for="item in plans"
:key="item.id"
clickable
v-ripple
tag="label"
:disable="item.name === 'TEST' && currentPlanData.name !== 'TEST'"
>
<q-item-section avatar>
<q-radio
v-model="newPlan"
:val="item"
:disable="item.name === 'TEST' && currentPlanData.name != 'TEST'"
:keep-color="item.name === 'TEST'&& currentPlanData.name !== 'TEST'"
:color="item.name === 'TEST' && currentPlanData.name !== 'TEST' ? 'grey-5' : ''"
/>
</q-item-section>
<q-item-section>
<div class="column">
<span class="text-bold">
{{ item.name }}
</span>
<div class="flex no-wrap items-center text-caption" style="line-height: 1em;">
<span v-if="item.chatsQty">
{{ $t('subscribe__chats_max') + ' ' + item.chatsQty }}
</span>
<q-icon v-else name="mdi-all-inclusive" size="sm"/>
<span class="q-pl-xs">
{{ $t('subscribe__chats')}}
</span>
</div>
<span
v-if="item.name === 'TEST' && currentPlanData.name !== 'TEST'"
class="text-caption text-grey-7"
>
{{ $t('subscribe__TEST_via_support')}}
</span>
</div>
</q-item-section>
<q-item-section
class="text-left"
:style="{ width: `${maxWidthStarsSection}px` }"
>
<q-resize-observer @resize="updateMaxWidthStarsSection" />
<div v-if="item.price" class="flex column justify-start">
<div class="flex no-wrap items-center">
<telegram-star color="gold" size="18px" class="q-mr-xs"/>
<span class="text-h6">{{ formatNumber(item.price) }}</span>
<span class="text-caption q-pl-xs">{{ $t('subscribe__per_month') }}</span>
</div>
</div>
<div v-else class="text-bold self-center">
{{ $t('subscribe__free_tax') }}
</div>
</q-item-section>
</q-item>
</q-list>
<div class="q-px-md">
<div class="w100 text-grey text-center q-pt-sm">
{{ $t('subscribe__plans_interval') }}
</div>
<q-btn-group spread flat class="w100 q-py-sm">
<q-btn
v-for="period in periods"
:key="period.id"
:outline="selectPeriod === period.value"
@click="selectPeriod = period.value"
:color="selectPeriod === period.value ? 'primary' : ''"
no-caps dense
>
<div class="column items-center w100 self-end">
<span
class="text-h6"
:class="selectPeriod === period.value ? 'text-primary' : 'text-black'"
>
{{ $t(period.name) }}
</span>
<div
class="row no-wrap w100 q-px-xs"
:class="period.sale ? 'justify-between' : 'justify-center'"
>
<span
class="text-caption text-grey"
>
{{ $t(period.name_in_days) }}
</span>
<q-badge v-show="period.sale" color="red">-{{ period.sale }}%</q-badge>
</div>
</div>
</q-btn>
</q-btn-group>
<div class="text-caption text-grey">
<span>{{ $t('subscribe__plans_period_notes') + ' ' }}</span>
<span
@click="router.push({ name: 'change_plan_rules' })"
class="text-info cursor-pointer"
>
{{ $t('subscribe__plans_period_notes_more_info') }}
</span>
</div>
<q-input
v-model="promocode"
dense
filled
:label="$t('subscribe__promocode')"
class="q-pt-md"
>
<template #append v-if="promocode !== ''">
<q-btn
round dense flat
color="primary"
icon="mdi-arrow-right-circle-outline"
@click="sendPromocode"
/>
</template>
</q-input>
</div>
</pn-scroll-list>
</pn-page-card>
@@ -121,12 +191,12 @@
import { date } from 'quasar'
import { useI18n } from 'vue-i18n'
import type { WebApp } from '@twa-dev/types'
import { colors } from 'quasar';
import { colors } from 'quasar'
import { useQuasar } from 'quasar'
const router = useRouter()
const tg = inject('tg') as WebApp
tg.MainButton.show()
// @ts-expect-error: get hex text
tg.MainButton.color = colors.getPaletteColor('primary')
@@ -146,7 +216,7 @@
const selectPeriod = ref(periods[1]?.value)
const newPlan = ref(plans[1])
const newPlan = ref(plans[0])
interface CurrentPlan {
plan: string
@@ -155,7 +225,7 @@
}
const currentPlan = ref<CurrentPlan>({ // temp, this get from api
plan: plans[0].val,
plan: plans[1].val,
active_chats: 20,
exp: Date.now() / 1000 + 500000
})
@@ -186,12 +256,12 @@
)
const newDateExp = date.addToDate(Date.now(), { months: Number(selectPeriod.value) })
return t('subscribe__pay') + ' ⭐' + stars +
return t(newPlan.value.id !== currentPlanData.value.id ? 'subscribe__pay' : 'subscribe__pay_renew') +
' ⭐' + stars +
' (' + t('subscribe__plan_exp') + ' ' +
date.formatDate(newDateExp, 'DD.MM.YYYY') + ')'
})
function formatNumber (number: string | number) {
return number.toString().replace(/\B(?=(\d{3})+(?!\d))/g, " ")
}
@@ -201,6 +271,43 @@
watch(textBtn, () => tg.MainButton.setText(textBtn.value),
{ immediate: true })
watch(newPlan, () =>
// eslint-disable-next-line @typescript-eslint/no-unused-expressions
{ newPlan.value.name === 'TEST' ? tg.MainButton.hide() : tg.MainButton.show() },
{ immediate: true })
const maxWidthStarsSection = ref(0)
interface sizeParams {
height: number,
width: number
}
function updateMaxWidthStarsSection (size: sizeParams) {
if (size.width > maxWidthStarsSection.value) {
maxWidthStarsSection.value = size.width
}
}
const promocode = ref('')
function sendPromocode () {
promocode.value = ''
showNotify('fail')
}
const $q = useQuasar()
const showNotify = (message: 'success' | 'fail') => {
$q.notify({
message: t(message === 'success' ? 'subscribe__promocode_success' : 'subscribe__promocode_fail'),
type: message === 'success' ? 'positive' : 'negative',
position: 'bottom',
timeout: 1000,
multiLine: true
})
}
</script>
<style lang="scss">

View File

@@ -2,14 +2,13 @@
<div class="q-pa-none flex column col-grow no-scroll">
<pn-scroll-list>
<template #card-body-header>
<div class="flex row q-ma-md justify-between" v-if="chats.length !== 0">
<q-input
v-model="search"
clearable
clear-icon="close"
:placeholder="$t('chats__search')"
dense
dense filled
class="col-grow"
v-if="chats.length !== 0"
>
@@ -52,18 +51,15 @@
{{ item.description }}
</q-item-label>
<q-item-label caption lines="1">
<div class = "flex justify-start items-center no-wrap">
<div class="q-mr-sm flex items-center no-wrap">
<q-icon name="mdi-account-multiple-outline" class="q-mr-xs"/>
<span>{{ item.user_count }}</span>
</div>
<div class="q-mx-sm flex items-center no-wrap ellipsis" v-if="item.owner_id">
<q-icon name="mdi-key" class="q-mr-xs"/>
<span class="ellipsis">{{ usersStore.userNameById(item.owner_id) }} </span>
</div>
</div>
</q-item-label>
</q-item-section>
<q-item-section side>
<div class="flex items-center no-wrap text-caption">
<q-icon name="mdi-account-outline"/>
<span>{{ item.user_count }}</span>
</div>
</q-item-section>
</q-item>
</q-slide-item>
</q-list>
@@ -166,7 +162,6 @@
<script setup lang="ts">
import { ref, computed, onActivated, onDeactivated, onBeforeUnmount, inject } from 'vue'
import { useChatsStore } from 'stores/chats'
import { useUsersStore } from 'stores/users'
import type { WebApp } from '@twa-dev/types'
import { useI18n } from "vue-i18n"
import { useRouter, useRoute } from 'vue-router'
@@ -179,7 +174,6 @@
const search = ref('')
const showOverlay = ref<boolean>(false)
const chatsStore = useChatsStore()
const usersStore = useUsersStore()
const showDialogDeleteChat = ref<boolean>(false)
const deleteChatId = ref<number | undefined>(undefined)
const currentSlideEvent = ref<SlideEvent | null>(null)
@@ -192,7 +186,7 @@
reset: () => void
}
const chats = chatsStore.getChats
const chats = computed(() => chatsStore.chats)
const chatsInit = computed(() => chatsStore.isInit)
const fabMenu = [
@@ -201,9 +195,9 @@
]
const displayChats = computed(() => {
if (!search.value || !(search.value && search.value.trim())) return chats
if (!search.value || !(search.value && search.value.trim())) return chats.value
const searchValue = search.value.trim().toLowerCase()
const arrOut = chats
const arrOut = chats.value
.filter(el =>
el.name.toLowerCase().includes(searchValue) ||
el.description && el.description.toLowerCase().includes(searchValue)

View File

@@ -1,29 +1,27 @@
<template>
<div class="q-pa-none flex column col-grow no-scroll">
<pn-scroll-list>
<template #card-body-header>
<div class="flex items-center justify-end q-pa-sm w100" v-if="companies.length !== 0">
<q-btn
:color="companies.length <= 2 ? 'grey-6' : 'primary'"
flat
no-caps
@click="maskCompany"
:disable="companies.length <= 2"
class="q-pr-md"
rounded
>
<q-icon
left
size="sm"
name="mdi-domino-mask"
class="q-mr-xs"
/>
<div>
{{ $t('companies__mask')}}
</div>
</q-btn>
</div>
</template>
<div class="flex items-center justify-end q-pa-sm w100" v-if="companies.length !== 0">
<q-btn
:color="companies.length <= 2 ? 'grey-6' : 'primary'"
flat
no-caps
@click="maskCompany"
:disable="companies.length <= 2"
class="q-pr-md"
rounded
>
<q-icon
left
size="sm"
name="mdi-domino-mask"
class="q-mr-xs"
/>
<div>
{{ $t('companies__mask')}}
</div>
</q-btn>
</div>
<q-list separator v-if="companies.length !== 0">
<q-slide-item

View File

@@ -1,6 +1,7 @@
<template>
<div
id="project-info"
v-if="project"
:style="{ height: headerHeight + 'px', minHeight: '48px' }"
class="flex row items-center justify-between no-wrap w100 q-gutter-x-sm"
style="overflow: hidden; transition: height 0.3s ease-in-out; margin-left: 0"
@@ -34,7 +35,7 @@
size="lg"
/>
<div class="flex column text-white fit">
<div class="flex column text-white fit q-pl-sm">
<div
class="text-h6 q-pl-sm text-field"
>
@@ -85,18 +86,15 @@
return currentProject
? {
name: currentProject.name,
description: currentProject.description ?? '',
logo: currentProject.logo ?? ''
}
: {
name: '',
description: '',
logo: ''
description: currentProject.description,
logo: currentProject.logo
}
: null
})
function toggleExpand () {
expandProjectInfo.value = !expandProjectInfo.value
if (project.value && (project.value.description || project.value.logo))
expandProjectInfo.value = !expandProjectInfo.value
}
async function toProjects () {

View File

@@ -8,7 +8,7 @@
clearable
clear-icon="close"
:placeholder="$t('users__search')"
dense
dense filled
class="col-grow"
>
<template #prepend>
@@ -254,7 +254,7 @@
const usersStore = useUsersStore()
const companiesStore = useCompaniesStore()
const users = usersStore.getUsers
const users = computed(() => usersStore.users)
const usersInit = computed(() => usersStore.isInit)
const blockUserId = ref<number | undefined>(undefined)
@@ -263,7 +263,7 @@
const closedByUserAction = ref(false)
const { userSection } = useUserSection()
const mapUsers = computed(() => users.map(el => ({
const mapUsers = computed(() => users.value.map(el => ({
...el,
...userSection(el),
companyName: el.company_id && companiesStore.companyById(el.company_id)