234 lines
6.9 KiB
Vue
234 lines
6.9 KiB
Vue
<template>
|
|
<pn-page-card>
|
|
<template #title>
|
|
<div class="flex items-center justify-between col-grow">
|
|
|
|
<div>{{ $t('projects__projects') }}</div>
|
|
|
|
<div class="flex items-center">
|
|
<q-btn
|
|
@click="goAccount()"
|
|
flat
|
|
no-caps
|
|
icon-right="mdi-chevron-right"
|
|
align="right"
|
|
dense
|
|
>
|
|
<div class="flex items-center">
|
|
<q-avatar v-if="tgUser?.photo_url" size="32px">
|
|
<q-img :src="tgUser.photo_url"/>
|
|
</q-avatar>
|
|
<div class="q-ml-xs ellipsis" style="max-width: 100px">
|
|
{{
|
|
tgUser?.first_name +
|
|
(tgUser?.first_name && tgUser?.last_name ? ' ' : '') +
|
|
tgUser?.last_name
|
|
}}
|
|
</div>
|
|
</div>
|
|
</q-btn>
|
|
</div>
|
|
|
|
</div>
|
|
</template>
|
|
|
|
<pn-scroll-list>
|
|
<template #card-body-header>
|
|
<q-input
|
|
v-model="searchProject"
|
|
clearable
|
|
clear-icon="close"
|
|
:placeholder="$t('project_chats__search')"
|
|
dense
|
|
class="col-grow q-px-md q-py-md"
|
|
>
|
|
<template #prepend>
|
|
<q-icon name="mdi-magnify" />
|
|
</template>
|
|
</q-input>
|
|
</template>
|
|
|
|
<q-list separator>
|
|
<q-item
|
|
v-for = "item in activeProjects"
|
|
:key="item.id"
|
|
clickable
|
|
v-ripple
|
|
@click="goProject(item.id)"
|
|
class="w100"
|
|
>
|
|
<q-item-section avatar>
|
|
<q-avatar rounded >
|
|
<q-img v-if="item.logo" :src="item.logo" fit="cover" style="height: 40px"/>
|
|
<pn-auto-avatar v-else :name="item.name"/>
|
|
</q-avatar>
|
|
</q-item-section>
|
|
<q-item-section>
|
|
<q-item-label lines="1" class="text-bold">{{ item.name }}</q-item-label>
|
|
<q-item-label caption lines="2">{{item.description}}</q-item-label>
|
|
|
|
</q-item-section>
|
|
<q-item-section side class="text-caption ">
|
|
<div class="flex items-center column">
|
|
<div class="flex items-center">
|
|
<q-icon name="mdi-chat-outline"/>
|
|
<span>{{ item.chats }} </span>
|
|
</div>
|
|
<div class="flex items-center">
|
|
<q-icon name="mdi-account-outline"/>
|
|
<span>{{ item.persons }}</span>
|
|
</div>
|
|
</div>
|
|
</q-item-section>
|
|
</q-item>
|
|
</q-list>
|
|
<div v-if="archiveProjects.length !== 0" class="flex column items-center w100" :class="showArchive ? 'bg-grey-12' : ''">
|
|
<div id="btn_show_archive">
|
|
<q-btn-dropdown color="grey" flat no-caps @click="showArchive = !showArchive" dropdown-icon="arrow_drop_up">
|
|
<template #label>
|
|
<span class="text-caption">
|
|
<span v-if="!showArchive">{{ $t('projects__show_archive') }}</span>
|
|
<span v-else>{{ $t('projects__hide_archive') }}</span>
|
|
</span>
|
|
</template>
|
|
</q-btn-dropdown>
|
|
</div>
|
|
|
|
<q-list separator v-if="showArchive" class="w100">
|
|
<q-item
|
|
v-for = "item in archiveProjects"
|
|
:key="item.id"
|
|
clickable
|
|
v-ripple
|
|
@click="handleArchiveList(item.id)"
|
|
class="w100 text-grey"
|
|
>
|
|
<q-item-section avatar>
|
|
<q-avatar rounded >
|
|
<q-img v-if="item.logo" :src="item.logo" fit="cover" style="height: 40px"/>
|
|
<pn-auto-avatar v-else :name="item.name"/>
|
|
</q-avatar>
|
|
</q-item-section>
|
|
<q-item-section>
|
|
<q-item-label lines="1" class="text-bold">{{ item.name }}</q-item-label>
|
|
<q-item-label caption lines="2">{{item.description}}</q-item-label>
|
|
</q-item-section>
|
|
</q-item>
|
|
</q-list>
|
|
</div>
|
|
</pn-scroll-list>
|
|
|
|
<q-page-sticky
|
|
position="bottom-right"
|
|
:offset="[18, 18]"
|
|
>
|
|
<q-btn
|
|
fab
|
|
icon="add"
|
|
color="brand"
|
|
@click="createNewProject"
|
|
/>
|
|
</q-page-sticky>
|
|
</pn-page-card>
|
|
<q-dialog v-model="showDialogArchive">
|
|
<q-card class="q-pa-none q-ma-none">
|
|
<q-card-section align="center">
|
|
<div class="text-h6 text-negative ">{{ $t('projects__restore_archive_warning') }}</div>
|
|
</q-card-section>
|
|
|
|
<q-card-section class="q-pt-none" align="center">
|
|
{{ $t('projects__restore_archive_warning_message') }}
|
|
</q-card-section>
|
|
|
|
<q-card-actions align="center">
|
|
<q-btn
|
|
flat
|
|
:label="$t('back')"
|
|
color="primary"
|
|
v-close-popup
|
|
/>
|
|
<q-btn
|
|
flat
|
|
:label="$t('continue')"
|
|
color="primary"
|
|
v-close-popup
|
|
@click="restoreFromArchive()"
|
|
/>
|
|
</q-card-actions>
|
|
</q-card>
|
|
</q-dialog>
|
|
</template>
|
|
|
|
<script setup lang="ts">
|
|
import { ref, computed, watch, inject } from 'vue'
|
|
import { useRouter } from 'vue-router'
|
|
import { useProjectsStore } from 'stores/projects'
|
|
import type { WebApp } from '@twa-dev/types'
|
|
|
|
const tg = inject('tg') as WebApp
|
|
const tgUser = tg.initDataUnsafe.user
|
|
|
|
const router = useRouter()
|
|
const projectsStore = useProjectsStore()
|
|
const projects = projectsStore.projects
|
|
|
|
const searchProject = ref('')
|
|
const showArchive = ref(false)
|
|
const showDialogArchive = ref(false)
|
|
const archiveProjectId = ref<number | undefined> (undefined)
|
|
|
|
async function goProject (id: number) {
|
|
await router.push({ name: 'chats', params: { id }})
|
|
}
|
|
|
|
async function goAccount () {
|
|
await router.push({ name: 'account' })
|
|
}
|
|
|
|
async function createNewProject () {
|
|
await router.push({ name: 'project_add' })
|
|
}
|
|
|
|
function handleArchiveList (id: number) {
|
|
showDialogArchive.value = true
|
|
archiveProjectId.value = id
|
|
}
|
|
|
|
function restoreFromArchive () {
|
|
if (archiveProjectId.value) {
|
|
const projectTemp = projectsStore.projectById(archiveProjectId.value)
|
|
if (projectTemp) {
|
|
projectTemp.is_archive = false
|
|
projectsStore.updateProject(archiveProjectId.value, projectTemp)
|
|
}
|
|
}
|
|
}
|
|
|
|
const displayProjects = computed(() => {
|
|
if (!searchProject.value || !(searchProject.value && searchProject.value.trim())) return projects
|
|
const searchChatValue = searchProject.value.trim().toLowerCase()
|
|
const arrOut = projects
|
|
.filter(el =>
|
|
el.name.toLowerCase().includes(searchChatValue) ||
|
|
el.description && el.description.toLowerCase().includes(searchProject.value)
|
|
)
|
|
return arrOut
|
|
})
|
|
|
|
const activeProjects = computed(() => {
|
|
return displayProjects.value.filter(el => !el.is_archive)
|
|
})
|
|
|
|
const archiveProjects = computed(() => {
|
|
return displayProjects.value.filter(el => el.is_archive)
|
|
})
|
|
|
|
watch(showDialogArchive, (newD :boolean) => {
|
|
if (!newD) archiveProjectId.value = undefined
|
|
})
|
|
|
|
</script>
|
|
|
|
<style>
|
|
</style>
|