fix: implemented list group view in lead & deal
This commit is contained in:
parent
c86e78267d
commit
ed47d87315
@ -1 +1 @@
|
|||||||
Subproject commit 1394a12b6de105649c8ca5beeead62a38ef1b18e
|
Subproject commit 90c75affe85b2a1abfce68d61c0c5043f093a8a0
|
||||||
@ -29,18 +29,74 @@
|
|||||||
</Button>
|
</Button>
|
||||||
</ListHeaderItem>
|
</ListHeaderItem>
|
||||||
</ListHeader>
|
</ListHeader>
|
||||||
<ListRows id="list-rows">
|
<ListRows :rows="rows" v-slot="{ idx, column, item }">
|
||||||
<ListRow
|
<div v-if="column.key === '_assign'" class="flex items-center">
|
||||||
class="mx-5"
|
<MultipleAvatar
|
||||||
v-for="row in rows"
|
:avatars="item"
|
||||||
:key="row.name"
|
size="sm"
|
||||||
v-slot="{ idx, column, item }"
|
@click="
|
||||||
:row="row"
|
(event) =>
|
||||||
>
|
emit('applyFilter', {
|
||||||
<div v-if="column.key === '_assign'" class="flex items-center">
|
event,
|
||||||
<MultipleAvatar
|
idx,
|
||||||
:avatars="item"
|
column,
|
||||||
size="sm"
|
item,
|
||||||
|
firstColumn: columns[0],
|
||||||
|
})
|
||||||
|
"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<ListRowItem v-else :item="item">
|
||||||
|
<template #prefix>
|
||||||
|
<div v-if="column.key === 'status'">
|
||||||
|
<IndicatorIcon :class="item.color" />
|
||||||
|
</div>
|
||||||
|
<div v-else-if="column.key === 'organization'">
|
||||||
|
<Avatar
|
||||||
|
v-if="item.label"
|
||||||
|
class="flex items-center"
|
||||||
|
:image="item.logo"
|
||||||
|
:label="item.label"
|
||||||
|
size="sm"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div v-else-if="column.key === 'deal_owner'">
|
||||||
|
<Avatar
|
||||||
|
v-if="item.full_name"
|
||||||
|
class="flex items-center"
|
||||||
|
:image="item.user_image"
|
||||||
|
:label="item.full_name"
|
||||||
|
size="sm"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div v-else-if="column.key === 'mobile_no'">
|
||||||
|
<PhoneIcon class="h-4 w-4" />
|
||||||
|
</div>
|
||||||
|
<div v-else-if="column.key === '_liked_by'">
|
||||||
|
<Button
|
||||||
|
v-if="column.key == '_liked_by'"
|
||||||
|
variant="ghosted"
|
||||||
|
:class="isLiked(item) ? 'fill-red-500' : 'fill-white'"
|
||||||
|
@click.stop.prevent="
|
||||||
|
() => emit('likeDoc', { name: row.name, liked: isLiked(item) })
|
||||||
|
"
|
||||||
|
>
|
||||||
|
<HeartIcon class="h-4 w-4" />
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<template #default="{ label }">
|
||||||
|
<div
|
||||||
|
v-if="
|
||||||
|
[
|
||||||
|
'modified',
|
||||||
|
'creation',
|
||||||
|
'first_response_time',
|
||||||
|
'first_responded_on',
|
||||||
|
'response_by',
|
||||||
|
].includes(column.key)
|
||||||
|
"
|
||||||
|
class="truncate text-base"
|
||||||
@click="
|
@click="
|
||||||
(event) =>
|
(event) =>
|
||||||
emit('applyFilter', {
|
emit('applyFilter', {
|
||||||
@ -51,60 +107,21 @@
|
|||||||
firstColumn: columns[0],
|
firstColumn: columns[0],
|
||||||
})
|
})
|
||||||
"
|
"
|
||||||
/>
|
>
|
||||||
</div>
|
<Tooltip :text="item.label">
|
||||||
<ListRowItem v-else :item="item">
|
<div>{{ item.timeAgo }}</div>
|
||||||
<template #prefix>
|
</Tooltip>
|
||||||
<div v-if="column.key === 'status'">
|
</div>
|
||||||
<IndicatorIcon :class="item.color" />
|
<div
|
||||||
</div>
|
v-else-if="column.key === 'sla_status'"
|
||||||
<div v-else-if="column.key === 'organization'">
|
class="truncate text-base"
|
||||||
<Avatar
|
>
|
||||||
v-if="item.label"
|
<Badge
|
||||||
class="flex items-center"
|
v-if="item.value"
|
||||||
:image="item.logo"
|
:variant="'subtle'"
|
||||||
:label="item.label"
|
:theme="item.color"
|
||||||
size="sm"
|
size="md"
|
||||||
/>
|
:label="item.value"
|
||||||
</div>
|
|
||||||
<div v-else-if="column.key === 'deal_owner'">
|
|
||||||
<Avatar
|
|
||||||
v-if="item.full_name"
|
|
||||||
class="flex items-center"
|
|
||||||
:image="item.user_image"
|
|
||||||
:label="item.full_name"
|
|
||||||
size="sm"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div v-else-if="column.key === 'mobile_no'">
|
|
||||||
<PhoneIcon class="h-4 w-4" />
|
|
||||||
</div>
|
|
||||||
<div v-else-if="column.key === '_liked_by'">
|
|
||||||
<Button
|
|
||||||
v-if="column.key == '_liked_by'"
|
|
||||||
variant="ghosted"
|
|
||||||
:class="isLiked(item) ? 'fill-red-500' : 'fill-white'"
|
|
||||||
@click.stop.prevent="
|
|
||||||
() =>
|
|
||||||
emit('likeDoc', { name: row.name, liked: isLiked(item) })
|
|
||||||
"
|
|
||||||
>
|
|
||||||
<HeartIcon class="h-4 w-4" />
|
|
||||||
</Button>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
<template #default="{ label }">
|
|
||||||
<div
|
|
||||||
v-if="
|
|
||||||
[
|
|
||||||
'modified',
|
|
||||||
'creation',
|
|
||||||
'first_response_time',
|
|
||||||
'first_responded_on',
|
|
||||||
'response_by',
|
|
||||||
].includes(column.key)
|
|
||||||
"
|
|
||||||
class="truncate text-base"
|
|
||||||
@click="
|
@click="
|
||||||
(event) =>
|
(event) =>
|
||||||
emit('applyFilter', {
|
emit('applyFilter', {
|
||||||
@ -115,60 +132,34 @@
|
|||||||
firstColumn: columns[0],
|
firstColumn: columns[0],
|
||||||
})
|
})
|
||||||
"
|
"
|
||||||
>
|
/>
|
||||||
<Tooltip :text="item.label">
|
</div>
|
||||||
<div>{{ item.timeAgo }}</div>
|
<div v-else-if="column.type === 'Check'">
|
||||||
</Tooltip>
|
<FormControl
|
||||||
</div>
|
type="checkbox"
|
||||||
<div
|
:modelValue="item"
|
||||||
v-else-if="column.key === 'sla_status'"
|
:disabled="true"
|
||||||
class="truncate text-base"
|
class="text-gray-900"
|
||||||
>
|
/>
|
||||||
<Badge
|
</div>
|
||||||
v-if="item.value"
|
<div
|
||||||
:variant="'subtle'"
|
v-else
|
||||||
:theme="item.color"
|
class="truncate text-base"
|
||||||
size="md"
|
@click="
|
||||||
:label="item.value"
|
(event) =>
|
||||||
@click="
|
emit('applyFilter', {
|
||||||
(event) =>
|
event,
|
||||||
emit('applyFilter', {
|
idx,
|
||||||
event,
|
column,
|
||||||
idx,
|
item,
|
||||||
column,
|
firstColumn: columns[0],
|
||||||
item,
|
})
|
||||||
firstColumn: columns[0],
|
"
|
||||||
})
|
>
|
||||||
"
|
{{ label }}
|
||||||
/>
|
</div>
|
||||||
</div>
|
</template>
|
||||||
<div v-else-if="column.type === 'Check'">
|
</ListRowItem>
|
||||||
<FormControl
|
|
||||||
type="checkbox"
|
|
||||||
:modelValue="item"
|
|
||||||
:disabled="true"
|
|
||||||
class="text-gray-900"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
v-else
|
|
||||||
class="truncate text-base"
|
|
||||||
@click="
|
|
||||||
(event) =>
|
|
||||||
emit('applyFilter', {
|
|
||||||
event,
|
|
||||||
idx,
|
|
||||||
column,
|
|
||||||
item,
|
|
||||||
firstColumn: columns[0],
|
|
||||||
})
|
|
||||||
"
|
|
||||||
>
|
|
||||||
{{ label }}
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
</ListRowItem>
|
|
||||||
</ListRow>
|
|
||||||
</ListRows>
|
</ListRows>
|
||||||
<ListSelectBanner>
|
<ListSelectBanner>
|
||||||
<template #actions="{ selections, unselectAll }">
|
<template #actions="{ selections, unselectAll }">
|
||||||
@ -199,13 +190,12 @@ import MultipleAvatar from '@/components/MultipleAvatar.vue'
|
|||||||
import IndicatorIcon from '@/components/Icons/IndicatorIcon.vue'
|
import IndicatorIcon from '@/components/Icons/IndicatorIcon.vue'
|
||||||
import PhoneIcon from '@/components/Icons/PhoneIcon.vue'
|
import PhoneIcon from '@/components/Icons/PhoneIcon.vue'
|
||||||
import ListBulkActions from '@/components/ListBulkActions.vue'
|
import ListBulkActions from '@/components/ListBulkActions.vue'
|
||||||
|
import ListRows from '@/components/ListViews/ListRows.vue'
|
||||||
import {
|
import {
|
||||||
Avatar,
|
Avatar,
|
||||||
ListView,
|
ListView,
|
||||||
ListHeader,
|
ListHeader,
|
||||||
ListHeaderItem,
|
ListHeaderItem,
|
||||||
ListRows,
|
|
||||||
ListRow,
|
|
||||||
ListRowItem,
|
ListRowItem,
|
||||||
ListSelectBanner,
|
ListSelectBanner,
|
||||||
ListFooter,
|
ListFooter,
|
||||||
|
|||||||
@ -29,18 +29,71 @@
|
|||||||
</Button>
|
</Button>
|
||||||
</ListHeaderItem>
|
</ListHeaderItem>
|
||||||
</ListHeader>
|
</ListHeader>
|
||||||
<ListRows id="list-rows">
|
<ListRows :rows="rows" v-slot="{ idx, column, item }">
|
||||||
<ListRow
|
<div v-if="column.key === '_assign'" class="flex items-center">
|
||||||
class="mx-5"
|
<MultipleAvatar
|
||||||
v-for="row in rows"
|
:avatars="item"
|
||||||
:key="row.name"
|
size="sm"
|
||||||
v-slot="{ idx, column, item }"
|
@click="
|
||||||
:row="row"
|
(event) =>
|
||||||
>
|
emit('applyFilter', {
|
||||||
<div v-if="column.key === '_assign'" class="flex items-center">
|
event,
|
||||||
<MultipleAvatar
|
idx,
|
||||||
:avatars="item"
|
column,
|
||||||
size="sm"
|
item,
|
||||||
|
firstColumn: columns[0],
|
||||||
|
})
|
||||||
|
"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<ListRowItem v-else :item="item">
|
||||||
|
<template #prefix>
|
||||||
|
<div v-if="column.key === 'status'">
|
||||||
|
<IndicatorIcon :class="item.color" />
|
||||||
|
</div>
|
||||||
|
<div v-else-if="column.key === 'lead_name'">
|
||||||
|
<Avatar
|
||||||
|
v-if="item.label"
|
||||||
|
class="flex items-center"
|
||||||
|
:image="item.image"
|
||||||
|
:label="item.image_label"
|
||||||
|
size="sm"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div v-else-if="column.key === 'organization'">
|
||||||
|
<Avatar
|
||||||
|
v-if="item.label"
|
||||||
|
class="flex items-center"
|
||||||
|
:image="item.logo"
|
||||||
|
:label="item.label"
|
||||||
|
size="sm"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div v-else-if="column.key === 'lead_owner'">
|
||||||
|
<Avatar
|
||||||
|
v-if="item.full_name"
|
||||||
|
class="flex items-center"
|
||||||
|
:image="item.user_image"
|
||||||
|
:label="item.full_name"
|
||||||
|
size="sm"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div v-else-if="column.key === 'mobile_no'">
|
||||||
|
<PhoneIcon class="h-4 w-4" />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<template #default="{ label }">
|
||||||
|
<div
|
||||||
|
v-if="
|
||||||
|
[
|
||||||
|
'modified',
|
||||||
|
'creation',
|
||||||
|
'first_response_time',
|
||||||
|
'first_responded_on',
|
||||||
|
'response_by',
|
||||||
|
].includes(column.key)
|
||||||
|
"
|
||||||
|
class="truncate text-base"
|
||||||
@click="
|
@click="
|
||||||
(event) =>
|
(event) =>
|
||||||
emit('applyFilter', {
|
emit('applyFilter', {
|
||||||
@ -51,56 +104,37 @@
|
|||||||
firstColumn: columns[0],
|
firstColumn: columns[0],
|
||||||
})
|
})
|
||||||
"
|
"
|
||||||
/>
|
>
|
||||||
</div>
|
<Tooltip :text="item.label">
|
||||||
<ListRowItem v-else :item="item">
|
<div>{{ item.timeAgo }}</div>
|
||||||
<template #prefix>
|
</Tooltip>
|
||||||
<div v-if="column.key === 'status'">
|
</div>
|
||||||
<IndicatorIcon :class="item.color" />
|
<div v-else-if="column.key === '_liked_by'">
|
||||||
</div>
|
<Button
|
||||||
<div v-else-if="column.key === 'lead_name'">
|
v-if="column.key == '_liked_by'"
|
||||||
<Avatar
|
variant="ghosted"
|
||||||
v-if="item.label"
|
:class="isLiked(item) ? 'fill-red-500' : 'fill-white'"
|
||||||
class="flex items-center"
|
@click.stop.prevent="
|
||||||
:image="item.image"
|
() =>
|
||||||
:label="item.image_label"
|
emit('likeDoc', {
|
||||||
size="sm"
|
name: row.name,
|
||||||
/>
|
liked: isLiked(item),
|
||||||
</div>
|
})
|
||||||
<div v-else-if="column.key === 'organization'">
|
|
||||||
<Avatar
|
|
||||||
v-if="item.label"
|
|
||||||
class="flex items-center"
|
|
||||||
:image="item.logo"
|
|
||||||
:label="item.label"
|
|
||||||
size="sm"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div v-else-if="column.key === 'lead_owner'">
|
|
||||||
<Avatar
|
|
||||||
v-if="item.full_name"
|
|
||||||
class="flex items-center"
|
|
||||||
:image="item.user_image"
|
|
||||||
:label="item.full_name"
|
|
||||||
size="sm"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div v-else-if="column.key === 'mobile_no'">
|
|
||||||
<PhoneIcon class="h-4 w-4" />
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
<template #default="{ label }">
|
|
||||||
<div
|
|
||||||
v-if="
|
|
||||||
[
|
|
||||||
'modified',
|
|
||||||
'creation',
|
|
||||||
'first_response_time',
|
|
||||||
'first_responded_on',
|
|
||||||
'response_by',
|
|
||||||
].includes(column.key)
|
|
||||||
"
|
"
|
||||||
class="truncate text-base"
|
>
|
||||||
|
<HeartIcon class="h-4 w-4" />
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
v-else-if="column.key === 'sla_status'"
|
||||||
|
class="truncate text-base"
|
||||||
|
>
|
||||||
|
<Badge
|
||||||
|
v-if="item.value"
|
||||||
|
:variant="'subtle'"
|
||||||
|
:theme="item.color"
|
||||||
|
size="md"
|
||||||
|
:label="item.value"
|
||||||
@click="
|
@click="
|
||||||
(event) =>
|
(event) =>
|
||||||
emit('applyFilter', {
|
emit('applyFilter', {
|
||||||
@ -111,73 +145,34 @@
|
|||||||
firstColumn: columns[0],
|
firstColumn: columns[0],
|
||||||
})
|
})
|
||||||
"
|
"
|
||||||
>
|
/>
|
||||||
<Tooltip :text="item.label">
|
</div>
|
||||||
<div>{{ item.timeAgo }}</div>
|
<div v-else-if="column.type === 'Check'">
|
||||||
</Tooltip>
|
<FormControl
|
||||||
</div>
|
type="checkbox"
|
||||||
<div v-else-if="column.key === '_liked_by'">
|
:modelValue="item"
|
||||||
<Button
|
:disabled="true"
|
||||||
v-if="column.key == '_liked_by'"
|
class="text-gray-900"
|
||||||
variant="ghosted"
|
/>
|
||||||
:class="isLiked(item) ? 'fill-red-500' : 'fill-white'"
|
</div>
|
||||||
@click.stop.prevent="
|
<div
|
||||||
() =>
|
v-else
|
||||||
emit('likeDoc', { name: row.name, liked: isLiked(item) })
|
class="truncate text-base"
|
||||||
"
|
@click="
|
||||||
>
|
(event) =>
|
||||||
<HeartIcon class="h-4 w-4" />
|
emit('applyFilter', {
|
||||||
</Button>
|
event,
|
||||||
</div>
|
idx,
|
||||||
<div
|
column,
|
||||||
v-else-if="column.key === 'sla_status'"
|
item,
|
||||||
class="truncate text-base"
|
firstColumn: columns[0],
|
||||||
>
|
})
|
||||||
<Badge
|
"
|
||||||
v-if="item.value"
|
>
|
||||||
:variant="'subtle'"
|
{{ label }}
|
||||||
:theme="item.color"
|
</div>
|
||||||
size="md"
|
</template>
|
||||||
:label="item.value"
|
</ListRowItem>
|
||||||
@click="
|
|
||||||
(event) =>
|
|
||||||
emit('applyFilter', {
|
|
||||||
event,
|
|
||||||
idx,
|
|
||||||
column,
|
|
||||||
item,
|
|
||||||
firstColumn: columns[0],
|
|
||||||
})
|
|
||||||
"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div v-else-if="column.type === 'Check'">
|
|
||||||
<FormControl
|
|
||||||
type="checkbox"
|
|
||||||
:modelValue="item"
|
|
||||||
:disabled="true"
|
|
||||||
class="text-gray-900"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
v-else
|
|
||||||
class="truncate text-base"
|
|
||||||
@click="
|
|
||||||
(event) =>
|
|
||||||
emit('applyFilter', {
|
|
||||||
event,
|
|
||||||
idx,
|
|
||||||
column,
|
|
||||||
item,
|
|
||||||
firstColumn: columns[0],
|
|
||||||
})
|
|
||||||
"
|
|
||||||
>
|
|
||||||
{{ label }}
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
</ListRowItem>
|
|
||||||
</ListRow>
|
|
||||||
</ListRows>
|
</ListRows>
|
||||||
<ListSelectBanner>
|
<ListSelectBanner>
|
||||||
<template #actions="{ selections, unselectAll }">
|
<template #actions="{ selections, unselectAll }">
|
||||||
@ -208,13 +203,12 @@ import IndicatorIcon from '@/components/Icons/IndicatorIcon.vue'
|
|||||||
import PhoneIcon from '@/components/Icons/PhoneIcon.vue'
|
import PhoneIcon from '@/components/Icons/PhoneIcon.vue'
|
||||||
import MultipleAvatar from '@/components/MultipleAvatar.vue'
|
import MultipleAvatar from '@/components/MultipleAvatar.vue'
|
||||||
import ListBulkActions from '@/components/ListBulkActions.vue'
|
import ListBulkActions from '@/components/ListBulkActions.vue'
|
||||||
|
import ListRows from '@/components/ListViews/ListRows.vue'
|
||||||
import {
|
import {
|
||||||
Avatar,
|
Avatar,
|
||||||
ListView,
|
ListView,
|
||||||
ListHeader,
|
ListHeader,
|
||||||
ListHeaderItem,
|
ListHeaderItem,
|
||||||
ListRows,
|
|
||||||
ListRow,
|
|
||||||
ListSelectBanner,
|
ListSelectBanner,
|
||||||
ListRowItem,
|
ListRowItem,
|
||||||
ListFooter,
|
ListFooter,
|
||||||
|
|||||||
64
frontend/src/components/ListViews/ListRows.vue
Normal file
64
frontend/src/components/ListViews/ListRows.vue
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
<template>
|
||||||
|
<div class="mx-5 mt-2 h-full overflow-y-auto" v-if="showGroupedRows">
|
||||||
|
<div v-for="group in reactivieRows" :key="group.group">
|
||||||
|
<ListGroupHeader :group="group">
|
||||||
|
<div
|
||||||
|
class="my-2 flex items-center gap-2 text-base font-medium text-gray-800"
|
||||||
|
>
|
||||||
|
<div>{{ __('Status') }} -</div>
|
||||||
|
<div class="flex items-center gap-1">
|
||||||
|
<IndicatorIcon :class="group.color" />
|
||||||
|
<div>{{ group.group }}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</ListGroupHeader>
|
||||||
|
<ListGroupRows :group="group" id="list-rows">
|
||||||
|
<ListRow
|
||||||
|
v-for="row in group.rows"
|
||||||
|
:key="row.name"
|
||||||
|
v-slot="{ idx, column, item }"
|
||||||
|
:row="row"
|
||||||
|
>
|
||||||
|
<slot v-bind="{ idx, column, item }" />
|
||||||
|
</ListRow>
|
||||||
|
</ListGroupRows>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<ListRows class="mx-5" v-else id="list-rows">
|
||||||
|
<ListRow
|
||||||
|
v-for="row in reactivieRows"
|
||||||
|
:key="row.name"
|
||||||
|
v-slot="{ idx, column, item }"
|
||||||
|
:row="row"
|
||||||
|
>
|
||||||
|
<slot v-bind="{ idx, column, item }" />
|
||||||
|
</ListRow>
|
||||||
|
</ListRows>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import IndicatorIcon from '@/components/Icons/IndicatorIcon.vue'
|
||||||
|
import { ListRows, ListRow, ListGroupHeader, ListGroupRows } from 'frappe-ui'
|
||||||
|
|
||||||
|
import { ref, computed, watch } from 'vue'
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
rows: {
|
||||||
|
type: Array,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
const reactivieRows = ref(props.rows)
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => props.rows,
|
||||||
|
(val) => (reactivieRows.value = val)
|
||||||
|
)
|
||||||
|
|
||||||
|
let showGroupedRows = computed(() => {
|
||||||
|
return props.rows.every(
|
||||||
|
(row) => row.group && row.rows && Array.isArray(row.rows)
|
||||||
|
)
|
||||||
|
})
|
||||||
|
</script>
|
||||||
@ -77,6 +77,7 @@ import {
|
|||||||
formatTime,
|
formatTime,
|
||||||
} from '@/utils'
|
} from '@/utils'
|
||||||
import { Breadcrumbs } from 'frappe-ui'
|
import { Breadcrumbs } from 'frappe-ui'
|
||||||
|
import { useRoute } from 'vue-router'
|
||||||
import { ref, computed } from 'vue'
|
import { ref, computed } from 'vue'
|
||||||
|
|
||||||
const breadcrumbs = [{ label: __('Deals'), route: { name: 'Deals' } }]
|
const breadcrumbs = [{ label: __('Deals'), route: { name: 'Deals' } }]
|
||||||
@ -85,6 +86,8 @@ const { getUser } = usersStore()
|
|||||||
const { getOrganization } = organizationsStore()
|
const { getOrganization } = organizationsStore()
|
||||||
const { getDealStatus } = statusesStore()
|
const { getDealStatus } = statusesStore()
|
||||||
|
|
||||||
|
const route = useRoute()
|
||||||
|
|
||||||
const dealsListView = ref(null)
|
const dealsListView = ref(null)
|
||||||
const showDealModal = ref(false)
|
const showDealModal = ref(false)
|
||||||
|
|
||||||
@ -98,7 +101,7 @@ const viewControls = ref(null)
|
|||||||
// Rows
|
// Rows
|
||||||
const rows = computed(() => {
|
const rows = computed(() => {
|
||||||
if (!deals.value?.data?.data) return []
|
if (!deals.value?.data?.data) return []
|
||||||
return deals.value.data.data.map((deal) => {
|
let listRows = deals.value.data.data.map((deal) => {
|
||||||
let _rows = {}
|
let _rows = {}
|
||||||
deals.value.data.rows.forEach((row) => {
|
deals.value.data.rows.forEach((row) => {
|
||||||
_rows[row] = deal[row]
|
_rows[row] = deal[row]
|
||||||
@ -174,5 +177,31 @@ const rows = computed(() => {
|
|||||||
})
|
})
|
||||||
return _rows
|
return _rows
|
||||||
})
|
})
|
||||||
|
|
||||||
|
if (route.params.viewType === 'group_by') {
|
||||||
|
return getGroupedByRows(listRows)
|
||||||
|
}
|
||||||
|
return listRows
|
||||||
})
|
})
|
||||||
|
|
||||||
|
function getGroupedByRows(listRows) {
|
||||||
|
let groupedRows = []
|
||||||
|
|
||||||
|
listRows.forEach((row) => {
|
||||||
|
if (!groupedRows.some((group) => group.group === row.status.label)) {
|
||||||
|
groupedRows.push({
|
||||||
|
group: row.status.label,
|
||||||
|
color: getDealStatus(row.status.label)?.iconColorClass,
|
||||||
|
collapsed: false,
|
||||||
|
rows: [],
|
||||||
|
})
|
||||||
|
}
|
||||||
|
groupedRows.filter((group) => {
|
||||||
|
if (group.group === row.status.label) {
|
||||||
|
group.rows.push(row)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
return groupedRows || listRows
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@ -78,7 +78,7 @@ import {
|
|||||||
createToast,
|
createToast,
|
||||||
} from '@/utils'
|
} from '@/utils'
|
||||||
import { createResource, Breadcrumbs } from 'frappe-ui'
|
import { createResource, Breadcrumbs } from 'frappe-ui'
|
||||||
import { useRouter } from 'vue-router'
|
import { useRouter, useRoute } from 'vue-router'
|
||||||
import { ref, computed, reactive } from 'vue'
|
import { ref, computed, reactive } from 'vue'
|
||||||
|
|
||||||
const breadcrumbs = [{ label: __('Leads'), route: { name: 'Leads' } }]
|
const breadcrumbs = [{ label: __('Leads'), route: { name: 'Leads' } }]
|
||||||
@ -88,6 +88,7 @@ const { getOrganization } = organizationsStore()
|
|||||||
const { getLeadStatus } = statusesStore()
|
const { getLeadStatus } = statusesStore()
|
||||||
|
|
||||||
const router = useRouter()
|
const router = useRouter()
|
||||||
|
const route = useRoute()
|
||||||
|
|
||||||
const leadsListView = ref(null)
|
const leadsListView = ref(null)
|
||||||
const showLeadModal = ref(false)
|
const showLeadModal = ref(false)
|
||||||
@ -102,7 +103,7 @@ const viewControls = ref(null)
|
|||||||
// Rows
|
// Rows
|
||||||
const rows = computed(() => {
|
const rows = computed(() => {
|
||||||
if (!leads.value?.data?.data) return []
|
if (!leads.value?.data?.data) return []
|
||||||
return leads.value?.data.data.map((lead) => {
|
let listRows = leads.value?.data.data.map((lead) => {
|
||||||
let _rows = {}
|
let _rows = {}
|
||||||
leads.value?.data.rows.forEach((row) => {
|
leads.value?.data.rows.forEach((row) => {
|
||||||
_rows[row] = lead[row]
|
_rows[row] = lead[row]
|
||||||
@ -182,8 +183,33 @@ const rows = computed(() => {
|
|||||||
})
|
})
|
||||||
return _rows
|
return _rows
|
||||||
})
|
})
|
||||||
|
if (route.params.viewType === 'group_by') {
|
||||||
|
return getGroupedByRows(listRows)
|
||||||
|
}
|
||||||
|
return listRows
|
||||||
})
|
})
|
||||||
|
|
||||||
|
function getGroupedByRows(listRows) {
|
||||||
|
let groupedRows = []
|
||||||
|
|
||||||
|
listRows.forEach((row) => {
|
||||||
|
if (!groupedRows.some((group) => group.group === row.status.label)) {
|
||||||
|
groupedRows.push({
|
||||||
|
group: row.status.label,
|
||||||
|
color: getLeadStatus(row.status.label)?.iconColorClass,
|
||||||
|
collapsed: false,
|
||||||
|
rows: [],
|
||||||
|
})
|
||||||
|
}
|
||||||
|
groupedRows.filter((group) => {
|
||||||
|
if (group.group === row.status.label) {
|
||||||
|
group.rows.push(row)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
})
|
||||||
|
return groupedRows || listRows
|
||||||
|
}
|
||||||
|
|
||||||
let newLead = reactive({
|
let newLead = reactive({
|
||||||
salutation: '',
|
salutation: '',
|
||||||
first_name: '',
|
first_name: '',
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user