first commit
This commit is contained in:
228
src/pages/ProjectsPage.vue
Normal file
228
src/pages/ProjectsPage.vue
Normal file
@@ -0,0 +1,228 @@
|
||||
<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 size="32px">
|
||||
<img src="https://cdn.quasar.dev/img/avatar2.jpg">
|
||||
</q-avatar>
|
||||
<div class="q-ml-xs ellipsis" style="max-width: 100px">
|
||||
Alex mart
|
||||
</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-label caption lines="1">
|
||||
<div class = "flex justify-start items-center">
|
||||
<div class="q-mr-sm">
|
||||
<q-icon name="mdi-message-outline" class="q-mr-sm"/>
|
||||
<span>{{ item.chats }} </span>
|
||||
</div>
|
||||
<div class="q-mr-sm">
|
||||
<q-icon name="mdi-account-outline" class="q-mx-sm"/>
|
||||
<span>{{ item.persons }}</span>
|
||||
</div>
|
||||
<div class="q-mx-sm">
|
||||
<q-icon name="mdi-account-group-outline" class="q-mr-sm"/>
|
||||
<span>{{ item.companies }} </span>
|
||||
</div>
|
||||
</div>
|
||||
</q-item-label>
|
||||
</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_down">
|
||||
<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 } from 'vue'
|
||||
import { useRouter } from 'vue-router'
|
||||
import { useProjectsStore } from 'stores/projects'
|
||||
|
||||
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>
|
||||
Reference in New Issue
Block a user