1
0
forked from test/crm

fix: maintain scroll position in ListRows component

This commit is contained in:
Shariq Ansari 2024-12-23 15:31:35 +05:30
parent 3dc45c3c8c
commit d1efa543db
8 changed files with 472 additions and 446 deletions

View File

@ -11,7 +11,10 @@
row-key="name" row-key="name"
v-bind="$attrs" v-bind="$attrs"
> >
<ListHeader class="sm:mx-5 mx-3" @columnWidthUpdated="emit('columnWidthUpdated')"> <ListHeader
class="sm:mx-5 mx-3"
@columnWidthUpdated="emit('columnWidthUpdated')"
>
<ListHeaderItem <ListHeaderItem
v-for="column in columns" v-for="column in columns"
:key="column.key" :key="column.key"
@ -29,32 +32,52 @@
</Button> </Button>
</ListHeaderItem> </ListHeaderItem>
</ListHeader> </ListHeader>
<ListRows class="mx-3 sm:mx-5" id="list-rows"> <ListRows
<ListRow class="mx-3 sm:mx-5"
v-for="row in rows" :rows="rows"
:key="row.name" v-slot="{ idx, column, item }"
v-slot="{ idx, column, item }" doctype="CRM Call Log"
:row="row" >
> <ListRowItem :item="item">
<ListRowItem :item="item"> <template #prefix>
<template #prefix> <div v-if="['caller', 'receiver'].includes(column.key)">
<div v-if="['caller', 'receiver'].includes(column.key)"> <Avatar
<Avatar v-if="item.label"
v-if="item.label" class="flex items-center"
class="flex items-center" :image="item.image"
:image="item.image" :label="item.label"
:label="item.label" size="sm"
size="sm" />
/> </div>
</div> <div v-else-if="['type', 'duration'].includes(column.key)">
<div v-else-if="['type', 'duration'].includes(column.key)"> <FeatherIcon :name="item.icon" class="h-3 w-3" />
<FeatherIcon :name="item.icon" class="h-3 w-3" /> </div>
</div> </template>
</template> <template #default="{ label }">
<template #default="{ label }"> <div
<div v-if="['modified', 'creation'].includes(column.key)"
v-if="['modified', 'creation'].includes(column.key)" class="truncate text-base"
class="truncate text-base" @click="
(event) =>
emit('applyFilter', {
event,
idx,
column,
item,
firstColumn: columns[0],
})
"
>
<Tooltip :text="item.label">
<div>{{ item.timeAgo }}</div>
</Tooltip>
</div>
<div v-else-if="column.key === 'status'" class="truncate text-base">
<Badge
:variant="'subtle'"
:theme="item.color"
size="md"
:label="__(item.label)"
@click=" @click="
(event) => (event) =>
emit('applyFilter', { emit('applyFilter', {
@ -65,69 +88,46 @@
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 === 'status'" class="truncate text-base"> :modelValue="item"
<Badge :disabled="true"
:variant="'subtle'" class="text-ink-gray-9"
:theme="item.color" />
size="md" </div>
:label="__(item.label)" <div v-else-if="column.key === '_liked_by'">
@click=" <Button
(event) => v-if="column.key == '_liked_by'"
emit('applyFilter', { variant="ghosted"
event, :class="isLiked(item) ? 'fill-red-500' : 'fill-white'"
idx, @click.stop.prevent="
column, () => emit('likeDoc', { name: row.name, liked: isLiked(item) })
item,
firstColumn: columns[0],
})
"
/>
</div>
<div v-else-if="column.type === 'Check'">
<FormControl
type="checkbox"
:modelValue="item"
:disabled="true"
class="text-ink-gray-9"
/>
</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>
<div
v-else
class="truncate text-base"
@click="
(event) =>
emit('applyFilter', {
event,
idx,
column,
item,
firstColumn: columns[0],
})
" "
> >
{{ label }} <HeartIcon class="h-4 w-4" />
</div> </Button>
</template> </div>
</ListRowItem> <div
</ListRow> v-else
class="truncate text-base"
@click="
(event) =>
emit('applyFilter', {
event,
idx,
column,
item,
firstColumn: columns[0],
})
"
>
{{ label }}
</div>
</template>
</ListRowItem>
</ListRows> </ListRows>
<ListSelectBanner> <ListSelectBanner>
<template #actions="{ selections, unselectAll }"> <template #actions="{ selections, unselectAll }">
@ -161,13 +161,12 @@
<script setup> <script setup>
import HeartIcon from '@/components/Icons/HeartIcon.vue' import HeartIcon from '@/components/Icons/HeartIcon.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,
@ -232,7 +231,7 @@ const listBulkActionsRef = ref(null)
defineExpose({ defineExpose({
customListActions: computed( customListActions: computed(
() => listBulkActionsRef.value?.customListActions () => listBulkActionsRef.value?.customListActions,
), ),
}) })
</script> </script>

View File

@ -36,96 +36,93 @@
</Button> </Button>
</ListHeaderItem> </ListHeaderItem>
</ListHeader> </ListHeader>
<ListRows class="mx-3 sm:mx-5" id="list-rows"> <ListRows
<ListRow class="mx-3 sm:mx-5"
v-for="row in rows" :rows="rows"
:key="row.name" v-slot="{ idx, column, item }"
v-slot="{ idx, column, item }" doctype="Contact"
:row="row" >
> <ListRowItem :item="item">
<ListRowItem :item="item"> <template #prefix>
<template #prefix> <div v-if="column.key === 'full_name'">
<div v-if="column.key === 'full_name'"> <Avatar
<Avatar v-if="item.label"
v-if="item.label" class="flex items-center"
class="flex items-center" :image="item.image"
:image="item.image" :label="item.image_label"
:label="item.image_label" size="sm"
size="sm" />
/> </div>
</div> <div v-else-if="column.key === 'company_name'">
<div v-else-if="column.key === 'company_name'"> <Avatar
<Avatar v-if="item.label"
v-if="item.label" class="flex items-center"
class="flex items-center" :image="item.logo"
:image="item.logo" :label="item.label"
:label="item.label" size="sm"
size="sm" />
/> </div>
</div> <div v-else-if="column.key === 'mobile_no'">
<div v-else-if="column.key === 'mobile_no'"> <PhoneIcon class="h-4 w-4" />
<PhoneIcon class="h-4 w-4" /> </div>
</div> </template>
</template> <template #default="{ label }">
<template #default="{ label }"> <div
<div v-if="['modified', 'creation'].includes(column.key)"
v-if="['modified', 'creation'].includes(column.key)" class="truncate text-base"
class="truncate text-base" @click="
@click=" (event) =>
(event) => emit('applyFilter', {
emit('applyFilter', { event,
event, idx,
idx, column,
column, item,
item, firstColumn: columns[0],
firstColumn: columns[0], })
}) "
>
<Tooltip :text="item.label">
<div>{{ item.timeAgo }}</div>
</Tooltip>
</div>
<div v-else-if="column.type === 'Check'">
<FormControl
type="checkbox"
:modelValue="item"
:disabled="true"
class="text-ink-gray-9"
/>
</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) })
" "
> >
<Tooltip :text="item.label"> <HeartIcon class="h-4 w-4" />
<div>{{ item.timeAgo }}</div> </Button>
</Tooltip> </div>
</div> <div
<div v-else-if="column.type === 'Check'"> v-else
<FormControl class="truncate text-base"
type="checkbox" @click="
:modelValue="item" (event) =>
:disabled="true" emit('applyFilter', {
class="text-ink-gray-9" event,
/> idx,
</div> column,
<div v-else-if="column.key === '_liked_by'"> item,
<Button firstColumn: columns[0],
v-if="column.key == '_liked_by'" })
variant="ghosted" "
:class="isLiked(item) ? 'fill-red-500' : 'fill-white'" >
@click.stop.prevent=" {{ label }}
() => </div>
emit('likeDoc', { name: row.name, liked: isLiked(item) }) </template>
" </ListRowItem>
>
<HeartIcon class="h-4 w-4" />
</Button>
</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 }">
@ -160,13 +157,12 @@
import HeartIcon from '@/components/Icons/HeartIcon.vue' import HeartIcon from '@/components/Icons/HeartIcon.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,
ListSelectBanner, ListSelectBanner,
ListRowItem, ListRowItem,
ListFooter, ListFooter,

View File

@ -36,7 +36,11 @@
</Button> </Button>
</ListHeaderItem> </ListHeaderItem>
</ListHeader> </ListHeader>
<ListRows :rows="rows" v-slot="{ idx, column, item, row }"> <ListRows
:rows="rows"
v-slot="{ idx, column, item, row }"
doctype="CRM Deal"
>
<div v-if="column.key === '_assign'" class="flex items-center"> <div v-if="column.key === '_assign'" class="flex items-center">
<MultipleAvatar <MultipleAvatar
:avatars="item" :avatars="item"

View File

@ -10,7 +10,10 @@
}" }"
row-key="name" row-key="name"
> >
<ListHeader class="sm:mx-5 mx-3" @columnWidthUpdated="emit('columnWidthUpdated')"> <ListHeader
class="sm:mx-5 mx-3"
@columnWidthUpdated="emit('columnWidthUpdated')"
>
<ListHeaderItem <ListHeaderItem
v-for="column in columns" v-for="column in columns"
:key="column.key" :key="column.key"
@ -28,21 +31,41 @@
</Button> </Button>
</ListHeaderItem> </ListHeaderItem>
</ListHeader> </ListHeader>
<ListRows class="mx-3 sm:mx-5" id="list-rows"> <ListRows
<ListRow class="mx-3 sm:mx-5"
v-for="row in rows" :rows="rows"
:key="row.name" v-slot="{ idx, column, item }"
v-slot="{ idx, column, item }" doctype="Email Template"
:row="row" >
> <ListRowItem :item="item">
<ListRowItem :item="item"> <!-- <template #prefix>
<!-- <template #prefix>
</template> --> </template> -->
<template #default="{ label }"> <template #default="{ label }">
<div <div
v-if="['modified', 'creation'].includes(column.key)" v-if="['modified', 'creation'].includes(column.key)"
class="truncate text-base" class="truncate text-base"
@click="
(event) =>
emit('applyFilter', {
event,
idx,
column,
item,
firstColumn: columns[0],
})
"
>
<Tooltip :text="item.label">
<div>{{ item.timeAgo }}</div>
</Tooltip>
</div>
<div v-else-if="column.key === 'status'" class="truncate text-base">
<Badge
:variant="'subtle'"
:theme="item.color"
size="md"
:label="item.label"
@click=" @click="
(event) => (event) =>
emit('applyFilter', { emit('applyFilter', {
@ -53,69 +76,46 @@
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 === 'status'" class="truncate text-base"> :modelValue="item"
<Badge :disabled="true"
:variant="'subtle'" class="text-ink-gray-9"
:theme="item.color" />
size="md" </div>
:label="item.label" <div v-else-if="column.key === '_liked_by'">
@click=" <Button
(event) => v-if="column.key == '_liked_by'"
emit('applyFilter', { variant="ghosted"
event, :class="isLiked(item) ? 'fill-red-500' : 'fill-white'"
idx, @click.stop.prevent="
column, () => emit('likeDoc', { name: row.name, liked: isLiked(item) })
item,
firstColumn: columns[0],
})
"
/>
</div>
<div v-else-if="column.type === 'Check'">
<FormControl
type="checkbox"
:modelValue="item"
:disabled="true"
class="text-ink-gray-9"
/>
</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>
<div
v-else
class="truncate text-base"
@click="
(event) =>
emit('applyFilter', {
event,
idx,
column,
item,
firstColumn: columns[0],
})
" "
> >
{{ label }} <HeartIcon class="h-4 w-4" />
</div> </Button>
</template> </div>
</ListRowItem> <div
</ListRow> v-else
class="truncate text-base"
@click="
(event) =>
emit('applyFilter', {
event,
idx,
column,
item,
firstColumn: columns[0],
})
"
>
{{ label }}
</div>
</template>
</ListRowItem>
</ListRows> </ListRows>
<ListSelectBanner> <ListSelectBanner>
<template #actions="{ selections, unselectAll }"> <template #actions="{ selections, unselectAll }">
@ -148,12 +148,11 @@
<script setup> <script setup>
import HeartIcon from '@/components/Icons/HeartIcon.vue' import HeartIcon from '@/components/Icons/HeartIcon.vue'
import ListBulkActions from '@/components/ListBulkActions.vue' import ListBulkActions from '@/components/ListBulkActions.vue'
import ListRows from '@/components/ListViews/ListRows.vue'
import { import {
ListView, ListView,
ListHeader, ListHeader,
ListHeaderItem, ListHeaderItem,
ListRows,
ListRow,
ListSelectBanner, ListSelectBanner,
ListRowItem, ListRowItem,
ListFooter, ListFooter,
@ -219,7 +218,7 @@ const listBulkActionsRef = ref(null)
defineExpose({ defineExpose({
customListActions: computed( customListActions: computed(
() => listBulkActionsRef.value?.customListActions () => listBulkActionsRef.value?.customListActions,
), ),
}) })
</script> </script>

View File

@ -36,7 +36,11 @@
</Button> </Button>
</ListHeaderItem> </ListHeaderItem>
</ListHeader> </ListHeader>
<ListRows :rows="rows" v-slot="{ idx, column, item, row }"> <ListRows
:rows="rows"
v-slot="{ idx, column, item, row }"
doctype="CRM Lead"
>
<div v-if="column.key === '_assign'" class="flex items-center"> <div v-if="column.key === '_assign'" class="flex items-center">
<MultipleAvatar <MultipleAvatar
:avatars="item" :avatars="item"

View File

@ -15,7 +15,7 @@
</div> </div>
</div> </div>
</ListGroupHeader> </ListGroupHeader>
<ListGroupRows :group="group" id="list-rows"> <ListGroupRows :group="group">
<ListRow <ListRow
v-for="row in group.rows" v-for="row in group.rows"
:key="row.name" :key="row.name"
@ -27,7 +27,12 @@
</ListGroupRows> </ListGroupRows>
</div> </div>
</div> </div>
<ListRows class="mx-3 sm:mx-5" v-else id="list-rows"> <ListRows
v-else
ref="scrollContainer"
class="mx-3 sm:mx-5"
@scroll="handleScroll"
>
<ListRow <ListRow
v-for="row in reactivieRows" v-for="row in reactivieRows"
:key="row.name" :key="row.name"
@ -40,27 +45,53 @@
</template> </template>
<script setup> <script setup>
import { useStorage } from '@vueuse/core'
import { ListRows, ListRow, ListGroupHeader, ListGroupRows } from 'frappe-ui' import { ListRows, ListRow, ListGroupHeader, ListGroupRows } from 'frappe-ui'
import { ref, computed, watch, onBeforeUnmount, onMounted } from 'vue'
import { ref, computed, watch } from 'vue'
const props = defineProps({ const props = defineProps({
rows: { rows: {
type: Array, type: Array,
required: true, required: true,
}, },
doctype: {
type: String,
default: 'CRM Lead',
},
}) })
const reactivieRows = ref(props.rows) const reactivieRows = ref(props.rows)
watch( watch(
() => props.rows, () => props.rows,
(val) => (reactivieRows.value = val) (val) => (reactivieRows.value = val),
) )
let showGroupedRows = computed(() => { let showGroupedRows = computed(() => {
return props.rows.every( return props.rows.every(
(row) => row.group && row.rows && Array.isArray(row.rows) (row) => row.group && row.rows && Array.isArray(row.rows),
) )
}) })
const scrollPosition = useStorage(`scrollPosition${props.doctype}`, 0)
const scrollContainer = ref(null)
const handleScroll = () => {
if (scrollContainer.value) {
scrollPosition.value = scrollContainer.value.$el.scrollTop
}
}
onBeforeUnmount(() => {
if (scrollContainer.value) {
scrollContainer.value.$el.removeEventListener('scroll', handleScroll)
}
})
onMounted(() => {
if (scrollContainer.value) {
scrollContainer.value.$el.addEventListener('scroll', handleScroll)
scrollContainer.value.$el.scrollTop = scrollPosition.value
}
})
</script> </script>

View File

@ -14,7 +14,10 @@
}" }"
row-key="name" row-key="name"
> >
<ListHeader class="sm:mx-5 mx-3" @columnWidthUpdated="emit('columnWidthUpdated')"> <ListHeader
class="sm:mx-5 mx-3"
@columnWidthUpdated="emit('columnWidthUpdated')"
>
<ListHeaderItem <ListHeaderItem
v-for="column in columns" v-for="column in columns"
:key="column.key" :key="column.key"
@ -32,84 +35,81 @@
</Button> </Button>
</ListHeaderItem> </ListHeaderItem>
</ListHeader> </ListHeader>
<ListRows class="mx-3 sm:mx-5" id="list-rows"> <ListRows
<ListRow class="mx-3 sm:mx-5"
v-for="row in rows" :rows="rows"
:key="row.name" v-slot="{ idx, column, item }"
v-slot="{ idx, column, item }" doctype="CRM Organization"
:row="row" >
> <ListRowItem :item="item">
<ListRowItem :item="item"> <template #prefix>
<template #prefix> <div v-if="column.key === 'organization_name'">
<div v-if="column.key === 'organization_name'"> <Avatar
<Avatar v-if="item.label"
v-if="item.label" class="flex items-center"
class="flex items-center" :image="item.logo"
:image="item.logo" :label="item.label"
:label="item.label" size="sm"
size="sm" />
/> </div>
</div> </template>
</template> <template #default="{ label }">
<template #default="{ label }"> <div
<div v-if="['modified', 'creation'].includes(column.key)"
v-if="['modified', 'creation'].includes(column.key)" class="truncate text-base"
class="truncate text-base" @click="
@click=" (event) =>
(event) => emit('applyFilter', {
emit('applyFilter', { event,
event, idx,
idx, column,
column, item,
item, firstColumn: columns[0],
firstColumn: columns[0], })
}) "
>
<Tooltip :text="item.label">
<div>{{ item.timeAgo }}</div>
</Tooltip>
</div>
<div v-else-if="column.type === 'Check'">
<FormControl
type="checkbox"
:modelValue="item"
:disabled="true"
class="text-ink-gray-9"
/>
</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) })
" "
> >
<Tooltip :text="item.label"> <HeartIcon class="h-4 w-4" />
<div>{{ item.timeAgo }}</div> </Button>
</Tooltip> </div>
</div> <div
<div v-else-if="column.type === 'Check'"> v-else
<FormControl class="truncate text-base"
type="checkbox" @click="
:modelValue="item" (event) =>
:disabled="true" emit('applyFilter', {
class="text-ink-gray-9" event,
/> idx,
</div> column,
<div v-else-if="column.key === '_liked_by'"> item,
<Button firstColumn: columns[0],
v-if="column.key == '_liked_by'" })
variant="ghosted" "
:class="isLiked(item) ? 'fill-red-500' : 'fill-white'" >
@click.stop.prevent=" {{ label }}
() => </div>
emit('likeDoc', { name: row.name, liked: isLiked(item) }) </template>
" </ListRowItem>
>
<HeartIcon class="h-4 w-4" />
</Button>
</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 }">
@ -142,13 +142,12 @@
<script setup> <script setup>
import HeartIcon from '@/components/Icons/HeartIcon.vue' import HeartIcon from '@/components/Icons/HeartIcon.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,
@ -216,7 +215,7 @@ const listBulkActionsRef = ref(null)
defineExpose({ defineExpose({
customListActions: computed( customListActions: computed(
() => listBulkActionsRef.value?.customListActions () => listBulkActionsRef.value?.customListActions,
), ),
}) })
</script> </script>

View File

@ -31,107 +31,102 @@
</Button> </Button>
</ListHeaderItem> </ListHeaderItem>
</ListHeader> </ListHeader>
<ListRows class="mx-3 sm:mx-5" id="list-rows"> <ListRows
<ListRow class="mx-3 sm:mx-5"
v-for="row in rows" :rows="rows"
:key="row.name" v-slot="{ idx, column, item }"
v-slot="{ idx, column, item }" doctype="CRM Task"
:row="row" >
> <div v-if="column.key === 'due_date'">
<div v-if="column.key === 'due_date'"> <Tooltip :text="item && formatDate(item, 'ddd, MMM D, YYYY | hh:mm a')">
<Tooltip <div class="flex items-center gap-2 truncate text-base">
:text="item && formatDate(item, 'ddd, MMM D, YYYY | hh:mm a')" <div><CalendarIcon /></div>
> <div v-if="item" class="truncate">
<div class="flex items-center gap-2 truncate text-base"> {{ formatDate(item, 'D MMM, hh:mm a') }}
<div><CalendarIcon /></div>
<div v-if="item" class="truncate">
{{ formatDate(item, 'D MMM, hh:mm a') }}
</div>
</div> </div>
</Tooltip> </div>
</div> </Tooltip>
<ListRowItem v-else :item="item"> </div>
<template #prefix> <ListRowItem v-else :item="item">
<div v-if="column.key === 'status'"> <template #prefix>
<TaskStatusIcon :status="item" /> <div v-if="column.key === 'status'">
</div> <TaskStatusIcon :status="item" />
<div v-else-if="column.key === 'priority'"> </div>
<TaskPriorityIcon :priority="item" /> <div v-else-if="column.key === 'priority'">
</div> <TaskPriorityIcon :priority="item" />
<div v-else-if="column.key === 'assigned_to'"> </div>
<Avatar <div v-else-if="column.key === 'assigned_to'">
v-if="item.full_name" <Avatar
class="flex items-center" v-if="item.full_name"
:image="item.user_image" class="flex items-center"
:label="item.full_name" :image="item.user_image"
size="sm" :label="item.full_name"
/> size="sm"
</div>
</template>
<template #default="{ label }">
<div
v-if="['modified', 'creation'].includes(column.key)"
class="truncate text-base"
@click="
(event) =>
emit('applyFilter', {
event,
idx,
column,
item,
firstColumn: columns[0],
})
"
>
<Tooltip :text="item.label">
<div>{{ item.timeAgo }}</div>
</Tooltip>
</div>
<div
v-else-if="column.type === 'Text Editor'"
v-html="item"
class="truncate text-base h-4 [&>p]:truncate"
/> />
<div v-else-if="column.type === 'Check'"> </div>
<FormControl </template>
type="checkbox" <template #default="{ label }">
:modelValue="item" <div
:disabled="true" v-if="['modified', 'creation'].includes(column.key)"
class="text-ink-gray-9" class="truncate text-base"
/> @click="
</div> (event) =>
<div v-else-if="column.key === '_liked_by'"> emit('applyFilter', {
<Button event,
v-if="column.key == '_liked_by'" idx,
variant="ghosted" column,
:class="isLiked(item) ? 'fill-red-500' : 'fill-white'" item,
@click.stop.prevent=" firstColumn: columns[0],
() => })
emit('likeDoc', { name: row.name, liked: isLiked(item) }) "
" >
> <Tooltip :text="item.label">
<HeartIcon class="h-4 w-4" /> <div>{{ item.timeAgo }}</div>
</Button> </Tooltip>
</div> </div>
<div <div
v-else v-else-if="column.type === 'Text Editor'"
class="truncate text-base" v-html="item"
@click=" class="truncate text-base h-4 [&>p]:truncate"
(event) => />
emit('applyFilter', { <div v-else-if="column.type === 'Check'">
event, <FormControl
idx, type="checkbox"
column, :modelValue="item"
item, :disabled="true"
firstColumn: columns[0], class="text-ink-gray-9"
}) />
</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) })
" "
> >
{{ label }} <HeartIcon class="h-4 w-4" />
</div> </Button>
</template> </div>
</ListRowItem> <div
</ListRow> v-else
class="truncate text-base"
@click="
(event) =>
emit('applyFilter', {
event,
idx,
column,
item,
firstColumn: columns[0],
})
"
>
{{ label }}
</div>
</template>
</ListRowItem>
</ListRows> </ListRows>
<ListSelectBanner> <ListSelectBanner>
<template #actions="{ selections, unselectAll }"> <template #actions="{ selections, unselectAll }">
@ -167,14 +162,13 @@ import TaskStatusIcon from '@/components/Icons/TaskStatusIcon.vue'
import TaskPriorityIcon from '@/components/Icons/TaskPriorityIcon.vue' import TaskPriorityIcon from '@/components/Icons/TaskPriorityIcon.vue'
import CalendarIcon from '@/components/Icons/CalendarIcon.vue' import CalendarIcon from '@/components/Icons/CalendarIcon.vue'
import ListBulkActions from '@/components/ListBulkActions.vue' import ListBulkActions from '@/components/ListBulkActions.vue'
import ListRows from '@/components/ListViews/ListRows.vue'
import { formatDate } from '@/utils' import { formatDate } from '@/utils'
import { import {
Avatar, Avatar,
ListView, ListView,
ListHeader, ListHeader,
ListHeaderItem, ListHeaderItem,
ListRows,
ListRow,
ListSelectBanner, ListSelectBanner,
ListRowItem, ListRowItem,
ListFooter, ListFooter,