chore: created lead/deal/contact listview component
This commit is contained in:
parent
5f92c5d3d7
commit
2d412d4e7f
23
frontend/src/components/ListViews/ContactsListView.vue
Normal file
23
frontend/src/components/ListViews/ContactsListView.vue
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
<template>
|
||||||
|
<ListView
|
||||||
|
class="px-5"
|
||||||
|
v-if="rows"
|
||||||
|
:columns="columns"
|
||||||
|
:rows="rows"
|
||||||
|
row-key="name"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
<script setup>
|
||||||
|
import { ListView } from 'frappe-ui'
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
rows: {
|
||||||
|
type: Array,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
columns: {
|
||||||
|
type: Array,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
</script>
|
||||||
79
frontend/src/components/ListViews/DealsListView.vue
Normal file
79
frontend/src/components/ListViews/DealsListView.vue
Normal file
@ -0,0 +1,79 @@
|
|||||||
|
<template>
|
||||||
|
<ListView
|
||||||
|
:columns="columns"
|
||||||
|
:rows="rows"
|
||||||
|
:options="{
|
||||||
|
getRowRoute: (row) => ({ name: 'Deal', params: { dealId: row.name } }),
|
||||||
|
}"
|
||||||
|
row-key="name"
|
||||||
|
>
|
||||||
|
<ListHeader class="mx-5" />
|
||||||
|
<ListRows>
|
||||||
|
<ListRow
|
||||||
|
class="mx-5"
|
||||||
|
v-for="row in rows"
|
||||||
|
:key="row.name"
|
||||||
|
v-slot="{ column, item }"
|
||||||
|
:row="row"
|
||||||
|
>
|
||||||
|
<ListRowItem :item="item">
|
||||||
|
<template #prefix>
|
||||||
|
<div v-if="column.key === 'deal_status'">
|
||||||
|
<IndicatorIcon :class="item.color" />
|
||||||
|
</div>
|
||||||
|
<div v-else-if="column.key === 'organization_name'">
|
||||||
|
<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>
|
||||||
|
<div v-if="column.key === 'modified'" class="truncate text-base">
|
||||||
|
{{ item.timeAgo }}
|
||||||
|
</div>
|
||||||
|
</ListRowItem>
|
||||||
|
</ListRow>
|
||||||
|
</ListRows>
|
||||||
|
<ListSelectBanner />
|
||||||
|
</ListView>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import IndicatorIcon from '@/components/Icons/IndicatorIcon.vue'
|
||||||
|
import PhoneIcon from '@/components/Icons/PhoneIcon.vue'
|
||||||
|
import {
|
||||||
|
Avatar,
|
||||||
|
ListView,
|
||||||
|
ListHeader,
|
||||||
|
ListRows,
|
||||||
|
ListRow,
|
||||||
|
ListRowItem,
|
||||||
|
ListSelectBanner,
|
||||||
|
} from 'frappe-ui'
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
rows: {
|
||||||
|
type: Array,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
columns: {
|
||||||
|
type: Array,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
</script>
|
||||||
88
frontend/src/components/ListViews/LeadsListView.vue
Normal file
88
frontend/src/components/ListViews/LeadsListView.vue
Normal file
@ -0,0 +1,88 @@
|
|||||||
|
<template>
|
||||||
|
<ListView
|
||||||
|
:columns="columns"
|
||||||
|
:rows="rows"
|
||||||
|
:options="{
|
||||||
|
getRowRoute: (row) => ({ name: 'Lead', params: { leadId: row.name } }),
|
||||||
|
}"
|
||||||
|
row-key="name"
|
||||||
|
>
|
||||||
|
<ListHeader class="mx-5" />
|
||||||
|
<ListRows>
|
||||||
|
<ListRow
|
||||||
|
class="mx-5"
|
||||||
|
v-for="row in rows"
|
||||||
|
:key="row.name"
|
||||||
|
v-slot="{ column, item }"
|
||||||
|
:row="row"
|
||||||
|
>
|
||||||
|
<ListRowItem :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_name'">
|
||||||
|
<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>
|
||||||
|
<div v-if="column.key === 'modified'" class="truncate text-base">
|
||||||
|
{{ item.timeAgo }}
|
||||||
|
</div>
|
||||||
|
</ListRowItem>
|
||||||
|
</ListRow>
|
||||||
|
</ListRows>
|
||||||
|
<ListSelectBanner />
|
||||||
|
</ListView>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import IndicatorIcon from '@/components/Icons/IndicatorIcon.vue'
|
||||||
|
import PhoneIcon from '@/components/Icons/PhoneIcon.vue'
|
||||||
|
import {
|
||||||
|
Avatar,
|
||||||
|
ListView,
|
||||||
|
ListHeader,
|
||||||
|
ListRows,
|
||||||
|
ListRow,
|
||||||
|
ListSelectBanner,
|
||||||
|
ListRowItem,
|
||||||
|
} from 'frappe-ui'
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
rows: {
|
||||||
|
type: Array,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
columns: {
|
||||||
|
type: Array,
|
||||||
|
required: true,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
</script>
|
||||||
@ -33,58 +33,7 @@
|
|||||||
<Button icon="more-horizontal" />
|
<Button icon="more-horizontal" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<ListView
|
<DealsListView :rows="rows" :columns="columns" />
|
||||||
:columns="columns"
|
|
||||||
:rows="rows"
|
|
||||||
:options="{
|
|
||||||
getRowRoute: (row) => ({ name: 'Deal', params: { dealId: row.name } }),
|
|
||||||
}"
|
|
||||||
row-key="name"
|
|
||||||
>
|
|
||||||
<ListHeader class="mx-5" />
|
|
||||||
<ListRows>
|
|
||||||
<ListRow
|
|
||||||
class="mx-5"
|
|
||||||
v-for="row in rows"
|
|
||||||
:key="row.name"
|
|
||||||
v-slot="{ column, item }"
|
|
||||||
:row="row"
|
|
||||||
>
|
|
||||||
<ListRowItem :item="item">
|
|
||||||
<template #prefix>
|
|
||||||
<div v-if="column.key === 'deal_status'">
|
|
||||||
<IndicatorIcon :class="item.color" />
|
|
||||||
</div>
|
|
||||||
<div v-else-if="column.key === 'organization_name'">
|
|
||||||
<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>
|
|
||||||
<div v-if="column.key === 'modified'" class="truncate text-base">
|
|
||||||
{{ item.timeAgo }}
|
|
||||||
</div>
|
|
||||||
</ListRowItem>
|
|
||||||
</ListRow>
|
|
||||||
</ListRows>
|
|
||||||
<ListSelectBanner />
|
|
||||||
</ListView>
|
|
||||||
<Dialog
|
<Dialog
|
||||||
v-model="showNewDialog"
|
v-model="showNewDialog"
|
||||||
:options="{
|
:options="{
|
||||||
@ -106,11 +55,10 @@
|
|||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import LayoutHeader from '@/components/LayoutHeader.vue'
|
import LayoutHeader from '@/components/LayoutHeader.vue'
|
||||||
|
import DealsListView from '@/components/ListViews/DealsListView.vue'
|
||||||
import NewDeal from '@/components/NewDeal.vue'
|
import NewDeal from '@/components/NewDeal.vue'
|
||||||
import SortBy from '@/components/SortBy.vue'
|
import SortBy from '@/components/SortBy.vue'
|
||||||
import Filter from '@/components/Filter.vue'
|
import Filter from '@/components/Filter.vue'
|
||||||
import IndicatorIcon from '@/components/Icons/IndicatorIcon.vue'
|
|
||||||
import PhoneIcon from '@/components/Icons/PhoneIcon.vue'
|
|
||||||
import { usersStore } from '@/stores/users'
|
import { usersStore } from '@/stores/users'
|
||||||
import { useOrderBy } from '@/composables/orderby'
|
import { useOrderBy } from '@/composables/orderby'
|
||||||
import { useFilter } from '@/composables/filter'
|
import { useFilter } from '@/composables/filter'
|
||||||
@ -123,7 +71,6 @@ import {
|
|||||||
formatNumberIntoCurrency,
|
formatNumberIntoCurrency,
|
||||||
} from '@/utils'
|
} from '@/utils'
|
||||||
import {
|
import {
|
||||||
Avatar,
|
|
||||||
FeatherIcon,
|
FeatherIcon,
|
||||||
Dialog,
|
Dialog,
|
||||||
Button,
|
Button,
|
||||||
@ -131,12 +78,6 @@ import {
|
|||||||
createListResource,
|
createListResource,
|
||||||
createResource,
|
createResource,
|
||||||
Breadcrumbs,
|
Breadcrumbs,
|
||||||
ListView,
|
|
||||||
ListHeader,
|
|
||||||
ListRows,
|
|
||||||
ListRow,
|
|
||||||
ListRowItem,
|
|
||||||
ListSelectBanner,
|
|
||||||
} from 'frappe-ui'
|
} from 'frappe-ui'
|
||||||
import { useRouter } from 'vue-router'
|
import { useRouter } from 'vue-router'
|
||||||
import { ref, computed, reactive, watch } from 'vue'
|
import { ref, computed, reactive, watch } from 'vue'
|
||||||
@ -238,7 +179,8 @@ const columns = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
const rows = computed(() => {
|
const rows = computed(() => {
|
||||||
return leads.data?.map((lead) => {
|
if (!leads.data) return []
|
||||||
|
return leads.data.map((lead) => {
|
||||||
return {
|
return {
|
||||||
name: lead.name,
|
name: lead.name,
|
||||||
organization_name: {
|
organization_name: {
|
||||||
|
|||||||
@ -32,67 +32,7 @@
|
|||||||
<Button icon="more-horizontal" />
|
<Button icon="more-horizontal" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<ListView
|
<LeadsListView :rows="rows" :columns="columns" />
|
||||||
:columns="columns"
|
|
||||||
:rows="rows"
|
|
||||||
:options="{
|
|
||||||
getRowRoute: (row) => ({ name: 'Lead', params: { leadId: row.name } }),
|
|
||||||
}"
|
|
||||||
row-key="name"
|
|
||||||
>
|
|
||||||
<ListHeader class="mx-5" />
|
|
||||||
<ListRows>
|
|
||||||
<ListRow
|
|
||||||
class="mx-5"
|
|
||||||
v-for="row in rows"
|
|
||||||
:key="row.name"
|
|
||||||
v-slot="{ column, item }"
|
|
||||||
:row="row"
|
|
||||||
>
|
|
||||||
<ListRowItem :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_name'">
|
|
||||||
<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>
|
|
||||||
<div v-if="column.key === 'modified'" class="truncate text-base">
|
|
||||||
{{ item.timeAgo }}
|
|
||||||
</div>
|
|
||||||
</ListRowItem>
|
|
||||||
</ListRow>
|
|
||||||
</ListRows>
|
|
||||||
<ListSelectBanner />
|
|
||||||
</ListView>
|
|
||||||
<Dialog
|
<Dialog
|
||||||
v-model="showNewDialog"
|
v-model="showNewDialog"
|
||||||
:options="{
|
:options="{
|
||||||
@ -114,18 +54,16 @@
|
|||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import LayoutHeader from '@/components/LayoutHeader.vue'
|
import LayoutHeader from '@/components/LayoutHeader.vue'
|
||||||
|
import LeadsListView from '@/components/ListViews/LeadsListView.vue'
|
||||||
import NewLead from '@/components/NewLead.vue'
|
import NewLead from '@/components/NewLead.vue'
|
||||||
import SortBy from '@/components/SortBy.vue'
|
import SortBy from '@/components/SortBy.vue'
|
||||||
import Filter from '@/components/Filter.vue'
|
import Filter from '@/components/Filter.vue'
|
||||||
import IndicatorIcon from '@/components/Icons/IndicatorIcon.vue'
|
|
||||||
import PhoneIcon from '@/components/Icons/PhoneIcon.vue'
|
|
||||||
import { usersStore } from '@/stores/users'
|
import { usersStore } from '@/stores/users'
|
||||||
import { useOrderBy } from '@/composables/orderby'
|
import { useOrderBy } from '@/composables/orderby'
|
||||||
import { useFilter } from '@/composables/filter'
|
import { useFilter } from '@/composables/filter'
|
||||||
import { useDebounceFn } from '@vueuse/core'
|
import { useDebounceFn } from '@vueuse/core'
|
||||||
import { leadStatuses, dateFormat, dateTooltipFormat, timeAgo } from '@/utils'
|
import { leadStatuses, dateFormat, dateTooltipFormat, timeAgo } from '@/utils'
|
||||||
import {
|
import {
|
||||||
Avatar,
|
|
||||||
FeatherIcon,
|
FeatherIcon,
|
||||||
Dialog,
|
Dialog,
|
||||||
Button,
|
Button,
|
||||||
@ -133,12 +71,6 @@ import {
|
|||||||
createListResource,
|
createListResource,
|
||||||
createResource,
|
createResource,
|
||||||
Breadcrumbs,
|
Breadcrumbs,
|
||||||
ListView,
|
|
||||||
ListHeader,
|
|
||||||
ListRows,
|
|
||||||
ListRow,
|
|
||||||
ListSelectBanner,
|
|
||||||
ListRowItem,
|
|
||||||
} from 'frappe-ui'
|
} from 'frappe-ui'
|
||||||
import { useRouter } from 'vue-router'
|
import { useRouter } from 'vue-router'
|
||||||
import { ref, computed, reactive, watch } from 'vue'
|
import { ref, computed, reactive, watch } from 'vue'
|
||||||
@ -246,7 +178,8 @@ const columns = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
const rows = computed(() => {
|
const rows = computed(() => {
|
||||||
return leads.data?.map((lead) => {
|
if (!leads.data) return []
|
||||||
|
return leads.data.map((lead) => {
|
||||||
return {
|
return {
|
||||||
name: lead.name,
|
name: lead.name,
|
||||||
lead_name: {
|
lead_name: {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user