feat: integrate DateMonthYearPicker into Calendar for improved date selection
This commit is contained in:
parent
957aa4e2e2
commit
4cb8789786
1
frontend/components.d.ts
vendored
1
frontend/components.d.ts
vendored
@ -86,6 +86,7 @@ declare module 'vue' {
|
|||||||
DashboardItem: typeof import('./src/components/Dashboard/DashboardItem.vue')['default']
|
DashboardItem: typeof import('./src/components/Dashboard/DashboardItem.vue')['default']
|
||||||
DataFields: typeof import('./src/components/Activities/DataFields.vue')['default']
|
DataFields: typeof import('./src/components/Activities/DataFields.vue')['default']
|
||||||
DataFieldsModal: typeof import('./src/components/Modals/DataFieldsModal.vue')['default']
|
DataFieldsModal: typeof import('./src/components/Modals/DataFieldsModal.vue')['default']
|
||||||
|
DateMonthYearPicker: typeof import('./src/components/Calendar/DateMonthYearPicker.vue')['default']
|
||||||
DealModal: typeof import('./src/components/Modals/DealModal.vue')['default']
|
DealModal: typeof import('./src/components/Modals/DealModal.vue')['default']
|
||||||
DealsIcon: typeof import('./src/components/Icons/DealsIcon.vue')['default']
|
DealsIcon: typeof import('./src/components/Icons/DealsIcon.vue')['default']
|
||||||
DealsListView: typeof import('./src/components/ListViews/DealsListView.vue')['default']
|
DealsListView: typeof import('./src/components/ListViews/DealsListView.vue')['default']
|
||||||
|
|||||||
@ -129,7 +129,7 @@
|
|||||||
@click="showAllParticipants = true"
|
@click="showAllParticipants = true"
|
||||||
/>
|
/>
|
||||||
<Button
|
<Button
|
||||||
v-else
|
v-else-if="showAllParticipants"
|
||||||
variant="ghost"
|
variant="ghost"
|
||||||
:label="__('Show less')"
|
:label="__('Show less')"
|
||||||
iconLeft="chevron-up"
|
iconLeft="chevron-up"
|
||||||
|
|||||||
@ -40,33 +40,51 @@
|
|||||||
>
|
>
|
||||||
<template
|
<template
|
||||||
#header="{
|
#header="{
|
||||||
currentMonthYear,
|
currentYear,
|
||||||
|
currentMonth,
|
||||||
enabledModes,
|
enabledModes,
|
||||||
activeView,
|
activeView,
|
||||||
decrement,
|
decrement,
|
||||||
increment,
|
increment,
|
||||||
updateActiveView,
|
updateActiveView,
|
||||||
|
setCalendarDate,
|
||||||
}"
|
}"
|
||||||
>
|
>
|
||||||
<div class="my-4 mx-5 flex justify-between">
|
<div class="my-4 mx-5 flex justify-between">
|
||||||
<!-- left side -->
|
<!-- left side -->
|
||||||
<!-- Year, Month -->
|
<!-- Month Year -->
|
||||||
<span class="text-lg font-medium text-ink-gray-8">
|
<div class="flex items-center">
|
||||||
{{ currentMonthYear }}
|
<DateMonthYearPicker
|
||||||
</span>
|
:modelValue="selectedMonthDate"
|
||||||
|
:formatter="(d) => dayjs(d).format('MMM YYYY')"
|
||||||
|
@update:modelValue="
|
||||||
|
(val) => onMonthYearChange(val, setCalendarDate)
|
||||||
|
"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
<!-- right side -->
|
<!-- right side -->
|
||||||
<!-- actions buttons for calendar -->
|
<!-- actions buttons for calendar -->
|
||||||
<div class="flex gap-x-1">
|
<div class="flex gap-x-1">
|
||||||
<!-- Increment and Decrement Button-->
|
<!-- Increment and Decrement Button -->
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
@click="decrement()"
|
@click="
|
||||||
|
() => {
|
||||||
|
decrement()
|
||||||
|
syncSelectedMonth(currentYear, currentMonth)
|
||||||
|
}
|
||||||
|
"
|
||||||
variant="ghost"
|
variant="ghost"
|
||||||
class="h-4 w-4"
|
class="h-4 w-4"
|
||||||
icon="chevron-left"
|
icon="chevron-left"
|
||||||
/>
|
/>
|
||||||
<Button
|
<Button
|
||||||
@click="increment()"
|
@click="
|
||||||
|
() => {
|
||||||
|
increment()
|
||||||
|
syncSelectedMonth(currentYear, currentMonth)
|
||||||
|
}
|
||||||
|
"
|
||||||
variant="ghost"
|
variant="ghost"
|
||||||
class="h-4 w-4"
|
class="h-4 w-4"
|
||||||
icon="chevron-right"
|
icon="chevron-right"
|
||||||
@ -118,6 +136,7 @@ import {
|
|||||||
CalendarActiveEvent as activeEvent,
|
CalendarActiveEvent as activeEvent,
|
||||||
call,
|
call,
|
||||||
} from 'frappe-ui'
|
} from 'frappe-ui'
|
||||||
|
import DateMonthYearPicker from '@/components/Calendar/DateMonthYearPicker.vue'
|
||||||
import { onMounted, ref } from 'vue'
|
import { onMounted, ref } from 'vue'
|
||||||
|
|
||||||
const { user } = sessionStore()
|
const { user } = sessionStore()
|
||||||
@ -125,6 +144,37 @@ const { $dialog } = globalStore()
|
|||||||
|
|
||||||
const calendar = ref(null)
|
const calendar = ref(null)
|
||||||
|
|
||||||
|
const selectedMonthDate = ref(dayjs().format('YYYY-MM-DD'))
|
||||||
|
|
||||||
|
function onMonthYearChange(val = '', setCalendarDate) {
|
||||||
|
const d = dayjs(val)
|
||||||
|
selectedMonthDate.value = d.format('YYYY-MM-DD')
|
||||||
|
|
||||||
|
if (setCalendarDate) {
|
||||||
|
setCalendarDate(selectedMonthDate.value)
|
||||||
|
} else if (calendar.value?.setCalendarDate) {
|
||||||
|
calendar.value.setCalendarDate(selectedMonthDate.value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function syncSelectedMonth(year, month) {
|
||||||
|
// Keep same day if possible; otherwise clamp to last day
|
||||||
|
if (typeof year === 'number' && typeof month === 'number') {
|
||||||
|
const currentDay = dayjs(selectedMonthDate.value).date()
|
||||||
|
|
||||||
|
let tentative = dayjs(
|
||||||
|
`${year}-${String(month + 1).padStart(2, '0')}-01`,
|
||||||
|
).date(currentDay)
|
||||||
|
|
||||||
|
if (tentative.month() !== month) {
|
||||||
|
// overflowed into next month, use last day of target month
|
||||||
|
tentative = tentative.startOf('month').month(month).endOf('month')
|
||||||
|
}
|
||||||
|
|
||||||
|
selectedMonthDate.value = tentative.format('YYYY-MM-DD')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const events = createListResource({
|
const events = createListResource({
|
||||||
doctype: 'Event',
|
doctype: 'Event',
|
||||||
cache: ['calendar', user],
|
cache: ['calendar', user],
|
||||||
@ -411,7 +461,6 @@ function getFromToTime(time) {
|
|||||||
return [fromTime, toTime]
|
return [fromTime, toTime]
|
||||||
}
|
}
|
||||||
|
|
||||||
// Helper: create Contact docs for participants missing reference_docname
|
|
||||||
async function ensureParticipantContacts(participants) {
|
async function ensureParticipantContacts(participants) {
|
||||||
if (!Array.isArray(participants) || !participants.length) return participants
|
if (!Array.isArray(participants) || !participants.length) return participants
|
||||||
const updated = []
|
const updated = []
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user