crm/frontend/src/pages/Notes.vue
2023-08-26 20:09:25 +05:30

156 lines
3.7 KiB
Vue

<template>
<LayoutHeader>
<template #left-header>
<Breadcrumbs :items="[{ label: list.title }]" />
</template>
<template #right-header>
<Button variant="solid" label="Create" @click="createNote">
<template #prefix><FeatherIcon name="plus" class="h-4" /></template>
</Button>
</template>
</LayoutHeader>
<div class="border-b"></div>
<div v-if="notes.data?.length" class="grid grid-cols-3 gap-4 p-5">
<div
v-for="note in notes.data"
class="group flex flex-col justify-between gap-2 px-5 py-4 border rounded-lg h-52 shadow-sm hover:bg-gray-50 cursor-pointer"
@click="editNote(note)"
>
<div class="flex items-center justify-between">
<div class="text-lg font-medium truncate">
{{ note.title }}
</div>
<Dropdown
:options="[
{
icon: 'trash-2',
label: 'Delete',
onClick: () => deleteNote(note.name),
},
]"
@click.stop
>
<Button
icon="more-horizontal"
variant="ghosted"
class="hover:bg-white"
/>
</Dropdown>
</div>
<div
class="flex-1 text-base leading-5 text-gray-700 overflow-hidden"
v-html="note.content"
/>
<div class="flex items-center justify-between gap-2">
<div class="flex items-center gap-2">
<UserAvatar :user="note.owner" size="xs" />
<div class="text-sm text-gray-800">
{{ note.owner }}
</div>
</div>
<div class="text-sm text-gray-700">
{{ timeAgo(note.modified) }}
</div>
</div>
</div>
</div>
<div
v-else
class="flex-1 p-5 flex items-center justify-center font-medium text-xl text-gray-500"
>
<div class="flex flex-col items-center gap-2">
<NoteIcon class="w-10 h-10 text-gray-500" />
<span>No notes</span>
</div>
</div>
<NoteModal
v-model="showNoteModal"
:note="currentNote"
@updateNote="updateNote"
/>
</template>
<script setup>
import LayoutHeader from '@/components/LayoutHeader.vue'
import Breadcrumbs from '@/components/Breadcrumbs.vue'
import UserAvatar from '@/components/UserAvatar.vue'
import NoteIcon from '@/components/Icons/NoteIcon.vue'
import NoteModal from '@/components/NoteModal.vue'
import { timeAgo } from '@/utils'
import {
FeatherIcon,
Button,
createListResource,
TextEditor,
TextInput,
call,
Dropdown,
} from 'frappe-ui'
import { ref } from 'vue'
const list = {
title: 'Notes',
plural_label: 'Notes',
singular_label: 'Note',
}
const showNoteModal = ref(false)
const currentNote = ref(null)
const notes = createListResource({
type: 'list',
doctype: 'CRM Note',
cache: 'Notes',
fields: ['name', 'title', 'content', 'owner', 'modified'],
filters: {},
orderBy: 'modified desc',
pageLength: 20,
auto: true,
})
function createNote() {
currentNote.value = {
title: '',
content: '',
}
showNoteModal.value = true
}
function editNote(note) {
currentNote.value = note
showNoteModal.value = true
}
async function updateNote(note) {
if (note.name) {
let d = await call('frappe.client.set_value', {
doctype: 'CRM Note',
name: note.name,
fieldname: note,
})
if (d.name) {
notes.reload()
}
} else {
let d = await call('frappe.client.insert', {
doc: {
doctype: 'CRM Note',
title: note.title,
content: note.content,
},
})
if (d.name) {
notes.reload()
}
}
}
async function deleteNote(name) {
await call('frappe.client.delete', {
doctype: 'CRM Note',
name,
})
notes.reload()
}
</script>