This commit is contained in:
2026-01-28 22:37:27 +03:00
parent cbaa1cda9d
commit 53ca63ec91
64 changed files with 4375 additions and 2980 deletions

View File

@@ -1,7 +1,9 @@
<template>
<pn-page-card>
<pn-page-template>
<template #title>
{{ $t('projects__title') }}
<div class="q-pr-md ellipsis">
{{ $t('projects__title') }}
</div>
<q-btn
@click="goAccount"
flat rounded
@@ -14,41 +16,117 @@
<pn-account-block-name/>
</q-btn>
</template>
<pn-scroll-list
:hideHeader="projects.length === 0 && archiveProjects.length === 0"
>
<template #card-body-header>
<q-input
v-model="searchProject"
clearable
clear-icon="close"
:placeholder="$t('projects__search')"
dense filled
class="col-grow q-px-md q-py-md"
<template #card-header>
<pn-action-bar
v-model="searchProject"
placeholder="projects__search"
:show-calendar-btn="false"
:show-filter-btn="false"
/>
</template>
<q-list v-if="projects.length !== 0">
<template
v-for="item in activeProjects"
:key="item.id"
>
<q-slide-item
@right="handleSlideRight($event, item.id)"
clickable
v-ripple
@click="goProject(item.id)"
right-color="red"
left-color="green"
>
<template #prepend>
<q-icon name="mdi-magnify" />
<template #right>
<q-icon size="lg" name="mdi-briefcase-remove-outline"/>
</template>
</q-input>
<q-item>
<q-item-section avatar>
<pn-auto-avatar
:img="item.logo"
:name="item.name"
type="rounded"
size="lg"
/>
</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"
style="max-width: -webkit-fill-available; white-space: pre-line"
>
{{ item.description }}
</q-item-label>
<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"/>
<span>{{ item.chat_count }} </span>
</div>
<div class="flex items-center q-ml-xs">
<q-icon name="mdi-account-outline"/>
<span>{{ item.user_count }}</span>
</div>
</div>
</q-item-label>
</q-item-section>
<q-item-section side>
<q-item-label>
<q-btn
color="grey"
size="md"
dense flat round
icon="mdi-pencil"
class="q-ml-sm"
@click.stop="editProject(item.id)"
/>
</q-item-label>
</q-item-section>
</q-item>
</q-slide-item>
</template>
<q-list separator v-if="projects.length !== 0">
<template
v-for = "item in activeProjects"
:key="item.id"
</q-list>
<div
v-if="archiveProjects.length !== 0"
class="flex column items-center w100"
:class="showArchive ? 'bg-grey-12' : ''"
>
<q-btn
class="w100 rotate-icon-btn"
color="grey"
flat
no-caps
@click="showArchive=!showArchive"
icon-right="arrow_drop_down"
:class="{ 'rotate-icon': showArchive }"
>
<span class="text-caption">
{{ !showArchive
? $t('projects__show_archive') + ' (' + archiveProjects.length +')'
: $t('projects__hide_archive')
}}
</span>
</q-btn>
<div class="w100" style="overflow: hidden">
<transition
appear
enter-active-class="animated slideInDown"
leave-active-class="animated slideOutUp"
>
<q-slide-item
@right="handleSlideRight($event, item.id)"
clickable
v-ripple
@click="goProject(item.id)"
right-color="red"
left-color="green"
>
<template #right>
<q-icon size="lg" name="mdi-briefcase-remove-outline"/>
</template>
<q-item>
<q-list 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>
<pn-auto-avatar
:img="item.logo"
@@ -58,139 +136,51 @@
/>
</q-item-section>
<q-item-section>
<q-item-label lines="1" class="text-bold">
{{ item.name }}
</q-item-label>
<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-label lines="1" class="text-caption text-grey">
<div class="flex items-center">
<div class="flex items-center">
<q-icon name="mdi-chat-outline"/>
<span>{{ item.chat_count }} </span>
</div>
<div class="flex items-center q-ml-xs">
<q-icon name="mdi-account-outline"/>
<span>{{ item.user_count }}</span>
</div>
</div>
</q-item-label>
</q-item-section>
<q-item-section side>
<q-item-label>
<q-btn
color="grey"
size="md"
dense flat round
icon="mdi-pencil"
class="q-ml-sm"
@click.stop="editProject(item.id)"
/>
</q-item-label>
</q-item-section>
</q-item>
</q-slide-item>
</template>
</q-list>
<div
v-if="archiveProjects.length !== 0"
class="flex column items-center w100"
:class="showArchive ? 'bg-grey-12' : ''"
>
<q-btn
class="w100 rotate-icon-btn"
color="grey"
flat
no-caps
@click="showArchive=!showArchive"
icon-right="arrow_drop_down"
:class="{ 'rotate-icon': showArchive }"
>
<span class="text-caption">
{{ !showArchive
? $t('projects__show_archive') + ' (' + archiveProjects.length +')'
: $t('projects__hide_archive')
}}
</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="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>
<pn-auto-avatar
:img="item.logo"
:name="item.name"
type="rounded"
size="lg"
/>
</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"
style="max-width: -webkit-fill-available; white-space: pre-line"
>
{{ item.description }}
</q-item-label>
</q-item-section>
</q-item>
</q-list>
</transition>
</div>
</q-list>
</transition>
</div>
</div>
<pn-onboard-btn
v-if="projects.length===0 && projectsInit"
icon="mdi-briefcase-plus-outline"
:message1="$t('projects__lets_start')"
:message2="$t('projects__lets_start_description')"
@btn-click="createNewProject"
/>
<div
class="flex column justify-center items-center w100"
style="position: absolute; bottom: 0;"
v-if="!projectsInit"
>
<q-linear-progress indeterminate />
</div>
</pn-scroll-list>
<q-page-sticky
position="bottom-right"
:offset="[0, 18]"
class="fix-fab-offset"
<pn-onboard-btn
v-if="projects.length===0 && projectsInit"
icon="mdi-briefcase-plus-outline"
message1="projects__lets_start"
message2="projects__lets_start_description"
@btn-click="createNewProject"
/>
<div
class="column justify-center items-center w100"
style="position: absolute; bottom: 0;"
v-if="!projectsInit"
>
<q-linear-progress indeterminate />
</div>
<template #card-fab>
<transition
appear
enter-active-class="animated zoomIn"
>
<pn-glass-btn type="fab" color="primary">
<q-btn
fab
icon="add"
color="brand"
color="transparent"
@click="createNewProject"
/>
</pn-glass-btn>
</transition>
</q-page-sticky>
</pn-page-card>
</template>
</pn-page-template>
<pn-small-dialog
v-model="showDialogArchiveProject"
@@ -221,6 +211,8 @@
import { ref, computed, watch, onMounted } from 'vue'
import { useRouter } from 'vue-router'
import { useProjectsStore } from 'stores/projects'
import pnGlassBtn from 'components/pnGlassBtn.vue'
import pnActionBar from 'components/pnActionBar.vue'
import type { Project } from 'types/Project'
const router = useRouter()