fix: added created/modified time stamp
also added scroll to details and activities section
This commit is contained in:
parent
f49f6d7b84
commit
4580d3ca9b
@ -67,122 +67,141 @@
|
||||
:style="{ left: `${indicatorLeftValue}px` }"
|
||||
/>
|
||||
</TabList>
|
||||
<TabPanels class="flex h-full">
|
||||
<TabPanel class="flex-1" v-for="tab in tabs" :key="tab.label">
|
||||
<TabPanels class="flex h-full overflow-hidden">
|
||||
<TabPanel
|
||||
class="flex-1 overflow-y-auto"
|
||||
v-for="tab in tabs"
|
||||
:key="tab.label"
|
||||
>
|
||||
<Activities :activities="tab.content" />
|
||||
</TabPanel>
|
||||
<div class="flex flex-col gap-6.5 border-l p-3 w-[390px]">
|
||||
<div
|
||||
v-for="section in detailSections"
|
||||
:key="section.label"
|
||||
class="flex flex-col"
|
||||
>
|
||||
<Toggler :is-opened="section.opened" v-slot="{ opened, toggle }">
|
||||
<div
|
||||
class="flex items-center gap-1 text-base font-semibold leading-5 px-3 cursor-pointer"
|
||||
@click="toggle()"
|
||||
>
|
||||
{{ section.label }}
|
||||
<FeatherIcon
|
||||
:name="opened ? 'chevron-up' : 'chevron-down'"
|
||||
class="h-4 text-gray-600"
|
||||
/>
|
||||
</div>
|
||||
<transition
|
||||
enter-active-class="duration-300 ease-in"
|
||||
leave-active-class="duration-300 ease-[cubic-bezier(0, 1, 0.5, 1)]"
|
||||
enter-to-class="max-h-[200px] overflow-hidden"
|
||||
leave-from-class="max-h-[200px] overflow-hidden"
|
||||
enter-from-class="max-h-0 overflow-hidden"
|
||||
leave-to-class="max-h-0 overflow-hidden"
|
||||
>
|
||||
<div v-if="opened" class="flex flex-col gap-3">
|
||||
<div
|
||||
v-for="field in section.fields"
|
||||
:key="field.label"
|
||||
class="flex items-center px-3 gap-2 text-base leading-5 first:mt-4.5"
|
||||
>
|
||||
<div class="text-gray-600 w-[106px]">{{ field.label }}</div>
|
||||
<div class="flex-1 w-full">
|
||||
<FormControl
|
||||
v-if="field.type === 'select'"
|
||||
type="select"
|
||||
:options="field.options"
|
||||
v-model="lead.doc[field.name]"
|
||||
>
|
||||
<template #prefix>
|
||||
<IndicatorIcon
|
||||
:class="indicatorColor[lead.doc[field.name]]"
|
||||
/>
|
||||
</template>
|
||||
</FormControl>
|
||||
<FormControl
|
||||
v-else-if="field.type === 'email'"
|
||||
type="email"
|
||||
v-model="lead.doc[field.name]"
|
||||
/>
|
||||
<Autocomplete
|
||||
v-else-if="field.type === 'link'"
|
||||
:options="activeAgents"
|
||||
:value="getUser(lead.doc[field.name]).full_name"
|
||||
@change="
|
||||
(option) => (lead.doc[field.name] = option.email)
|
||||
"
|
||||
placeholder="Lead owner"
|
||||
>
|
||||
<template #prefix>
|
||||
<Avatar
|
||||
class="mr-2"
|
||||
:image="getUser(lead.doc[field.name]).user_image"
|
||||
:label="getUser(lead.doc[field.name]).full_name"
|
||||
size="sm"
|
||||
/>
|
||||
</template>
|
||||
<template #item-prefix="{ option }">
|
||||
<Avatar
|
||||
class="mr-2"
|
||||
:image="getUser(option.email).user_image"
|
||||
:label="getUser(option.email).full_name"
|
||||
size="sm"
|
||||
/>
|
||||
</template>
|
||||
</Autocomplete>
|
||||
<Dropdown
|
||||
v-else-if="field.type === 'dropdown'"
|
||||
:options="statusDropdownOptions"
|
||||
class="w-full flex-1"
|
||||
>
|
||||
<template #default="{ open }">
|
||||
<Button
|
||||
:label="lead.doc[field.name]"
|
||||
class="justify-between w-full"
|
||||
>
|
||||
<template #prefix>
|
||||
<IndicatorIcon
|
||||
:class="indicatorColor[lead.doc[field.name]]"
|
||||
/>
|
||||
</template>
|
||||
<template #default>{{
|
||||
lead.doc[field.name]
|
||||
}}</template>
|
||||
<template #suffix
|
||||
><FeatherIcon
|
||||
:name="open ? 'chevron-up' : 'chevron-down'"
|
||||
class="h-4"
|
||||
/></template>
|
||||
</Button>
|
||||
</template>
|
||||
</Dropdown>
|
||||
<FormControl
|
||||
v-else
|
||||
type="text"
|
||||
v-model="lead.doc[field.name]"
|
||||
/>
|
||||
<div
|
||||
class="flex flex-col justify-between border-l w-[390px] overflow-hidden"
|
||||
>
|
||||
<div class="flex flex-col gap-6.5 p-3 overflow-y-auto">
|
||||
<div
|
||||
v-for="section in detailSections"
|
||||
:key="section.label"
|
||||
class="flex flex-col"
|
||||
>
|
||||
<Toggler :is-opened="section.opened" v-slot="{ opened, toggle }">
|
||||
<div
|
||||
class="flex items-center gap-1 text-base font-semibold leading-5 px-3 cursor-pointer"
|
||||
@click="toggle()"
|
||||
>
|
||||
{{ section.label }}
|
||||
<FeatherIcon
|
||||
:name="opened ? 'chevron-up' : 'chevron-down'"
|
||||
class="h-4 text-gray-600"
|
||||
/>
|
||||
</div>
|
||||
<transition
|
||||
enter-active-class="duration-300 ease-in"
|
||||
leave-active-class="duration-300 ease-[cubic-bezier(0, 1, 0.5, 1)]"
|
||||
enter-to-class="max-h-[200px] overflow-hidden"
|
||||
leave-from-class="max-h-[200px] overflow-hidden"
|
||||
enter-from-class="max-h-0 overflow-hidden"
|
||||
leave-to-class="max-h-0 overflow-hidden"
|
||||
>
|
||||
<div v-if="opened" class="flex flex-col gap-3">
|
||||
<div
|
||||
v-for="field in section.fields"
|
||||
:key="field.label"
|
||||
class="flex items-center px-3 gap-2 text-base leading-5 first:mt-4.5"
|
||||
>
|
||||
<div class="text-gray-600 w-[106px]">{{ field.label }}</div>
|
||||
<div class="flex-1 w-full">
|
||||
<FormControl
|
||||
v-if="field.type === 'select'"
|
||||
type="select"
|
||||
:options="field.options"
|
||||
v-model="lead.doc[field.name]"
|
||||
>
|
||||
<template #prefix>
|
||||
<IndicatorIcon
|
||||
:class="indicatorColor[lead.doc[field.name]]"
|
||||
/>
|
||||
</template>
|
||||
</FormControl>
|
||||
<FormControl
|
||||
v-else-if="field.type === 'email'"
|
||||
type="email"
|
||||
v-model="lead.doc[field.name]"
|
||||
/>
|
||||
<Autocomplete
|
||||
v-else-if="field.type === 'link'"
|
||||
:options="activeAgents"
|
||||
:value="getUser(lead.doc[field.name]).full_name"
|
||||
@change="
|
||||
(option) => (lead.doc[field.name] = option.email)
|
||||
"
|
||||
placeholder="Lead owner"
|
||||
>
|
||||
<template #prefix>
|
||||
<Avatar
|
||||
class="mr-2"
|
||||
:image="getUser(lead.doc[field.name]).user_image"
|
||||
:label="getUser(lead.doc[field.name]).full_name"
|
||||
size="sm"
|
||||
/>
|
||||
</template>
|
||||
<template #item-prefix="{ option }">
|
||||
<Avatar
|
||||
class="mr-2"
|
||||
:image="getUser(option.email).user_image"
|
||||
:label="getUser(option.email).full_name"
|
||||
size="sm"
|
||||
/>
|
||||
</template>
|
||||
</Autocomplete>
|
||||
<Dropdown
|
||||
v-else-if="field.type === 'dropdown'"
|
||||
:options="statusDropdownOptions"
|
||||
class="w-full flex-1"
|
||||
>
|
||||
<template #default="{ open }">
|
||||
<Button
|
||||
:label="lead.doc[field.name]"
|
||||
class="justify-between w-full"
|
||||
>
|
||||
<template #prefix>
|
||||
<IndicatorIcon
|
||||
:class="indicatorColor[lead.doc[field.name]]"
|
||||
/>
|
||||
</template>
|
||||
<template #default>{{
|
||||
lead.doc[field.name]
|
||||
}}</template>
|
||||
<template #suffix
|
||||
><FeatherIcon
|
||||
:name="open ? 'chevron-up' : 'chevron-down'"
|
||||
class="h-4"
|
||||
/></template>
|
||||
</Button>
|
||||
</template>
|
||||
</Dropdown>
|
||||
<FormControl
|
||||
v-else
|
||||
type="text"
|
||||
v-model="lead.doc[field.name]"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</transition>
|
||||
</Toggler>
|
||||
</transition>
|
||||
</Toggler>
|
||||
</div>
|
||||
</div>
|
||||
<div class="text-sm px-6 p-3 leading-5 cursor-pointer">
|
||||
<span class="text-gray-600">Created </span>
|
||||
<span :title="dateFormat(lead.doc.creation)">
|
||||
{{ timeAgo(lead.doc.creation) }}
|
||||
</span>
|
||||
<span> · </span>
|
||||
<span class="text-gray-600">Updated </span>
|
||||
<span :title="dateFormat(lead.doc.modified)">
|
||||
{{ timeAgo(lead.doc.modified) }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</TabPanels>
|
||||
@ -209,6 +228,7 @@ import {
|
||||
} from 'frappe-ui'
|
||||
import { TransitionPresets, useTransition } from '@vueuse/core'
|
||||
import { usersStore } from '@/stores/users'
|
||||
import { dateFormat, timeAgo } from '@/utils'
|
||||
import { ref, computed, h } from 'vue'
|
||||
import Breadcrumbs from '@/components/Breadcrumbs.vue'
|
||||
|
||||
|
||||
10
frontend/src/utils.js
Normal file
10
frontend/src/utils.js
Normal file
@ -0,0 +1,10 @@
|
||||
import { useDateFormat, useTimeAgo } from '@vueuse/core'
|
||||
|
||||
export function dateFormat(date, format) {
|
||||
const _format = format || 'DD-MM-YYYY HH:mm:ss'
|
||||
return useDateFormat(date, _format).value
|
||||
}
|
||||
|
||||
export function timeAgo(date) {
|
||||
return useTimeAgo(date).value
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user