pimelon-ui 0.1.122 → 0.1.124

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -98,7 +98,7 @@ const props = defineProps({
98
98
  },
99
99
  docsLink: {
100
100
  type: String,
101
- default: 'https://docs.monakerp.com/crm',
101
+ default: 'https://docs.devel.monakerp.com/crm',
102
102
  },
103
103
  })
104
104
 
@@ -70,7 +70,7 @@ import { ref, computed, onMounted } from 'vue'
70
70
  const props = defineProps({
71
71
  docsLink: {
72
72
  type: String,
73
- default: 'https://docs.monakerp.com/crm',
73
+ default: 'https://docs.devel.monakerp.com/crm',
74
74
  },
75
75
  })
76
76
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pimelon-ui",
3
- "version": "0.1.122",
3
+ "version": "0.1.124",
4
4
  "description": "A set of components and utilities for rapid UI development",
5
5
  "main": "./src/index.js",
6
6
  "scripts": {
@@ -14,7 +14,9 @@
14
14
  <div class="mb-2 flex justify-between">
15
15
  <!-- left side -->
16
16
  <!-- Year, Month -->
17
- <span class="text-xl font-medium"> {{ currentMonthYear }}</span>
17
+ <span class="text-lg font-medium text-ink-gray-8">
18
+ {{ currentMonthYear }}
19
+ </span>
18
20
  <!-- right side -->
19
21
  <!-- actions buttons for calendar -->
20
22
  <div class="flex gap-x-1">
@@ -64,7 +66,14 @@
64
66
  :events="events"
65
67
  :current-date="selectedDay"
66
68
  :config="overrideConfig"
67
- />
69
+ >
70
+ <template #header="{ parseDateWithDay, currentDate, fullDay }">
71
+ <slot
72
+ name="daily-header"
73
+ v-bind="{ parseDateWithDay, currentDate, fullDay }"
74
+ />
75
+ </template>
76
+ </CalendarDaily>
68
77
 
69
78
  <NewEventModal
70
79
  v-if="showEventModal"
@@ -74,7 +83,7 @@
74
83
  </div>
75
84
  </template>
76
85
  <script setup>
77
- import { computed, onMounted, onUnmounted, provide, ref, watch } from 'vue'
86
+ import { computed, onMounted, onUnmounted, provide, ref } from 'vue'
78
87
  import { Button } from '../Button'
79
88
  import TabButtons from '../TabButtons.vue'
80
89
  import {
@@ -98,18 +107,6 @@ const props = defineProps({
98
107
  config: {
99
108
  type: Object,
100
109
  },
101
- create: {
102
- type: Function,
103
- required: false,
104
- },
105
- update: {
106
- type: Function,
107
- required: false,
108
- },
109
- delete: {
110
- type: Function,
111
- required: false,
112
- },
113
110
  onClick: {
114
111
  type: Function,
115
112
  required: false,
@@ -124,6 +121,8 @@ const props = defineProps({
124
121
  },
125
122
  })
126
123
 
124
+ const emit = defineEmits(['create', 'update', 'delete'])
125
+
127
126
  const defaultConfig = {
128
127
  scrollToHour: 15,
129
128
  disableModes: [],
@@ -134,6 +133,7 @@ const defaultConfig = {
134
133
  hourHeight: 50,
135
134
  enableShortcuts: true,
136
135
  showIcon: true,
136
+ timeFormat: '12h',
137
137
  }
138
138
 
139
139
  const overrideConfig = { ...defaultConfig, ...props.config }
@@ -174,19 +174,25 @@ provide('activeView', activeView)
174
174
  provide('config', overrideConfig)
175
175
 
176
176
  const parseEvents = computed(() => {
177
- return props.events.map((event) => {
178
- const { fromDate, toDate, ...rest } = event
179
- const date = parseDate(fromDate)
180
- const from_time = new Date(fromDate).toLocaleTimeString()
181
- const to_time = new Date(toDate).toLocaleTimeString()
182
- if (event.isFullDay) {
183
- return { ...rest, date }
184
- }
185
- return { ...rest, date, from_time, to_time }
186
- })
177
+ return (
178
+ props.events?.map((event) => {
179
+ const { fromDate, toDate, ...rest } = event
180
+ const date = parseDate(fromDate)
181
+ const from_time = new Date(fromDate).toLocaleTimeString()
182
+ const to_time = new Date(toDate).toLocaleTimeString()
183
+ if (event.isFullDay) {
184
+ return { ...rest, date }
185
+ }
186
+ return { ...rest, date, from_time, to_time }
187
+ }) || []
188
+ )
187
189
  })
188
190
  const events = ref(parseEvents.value)
189
191
 
192
+ function reloadEvents() {
193
+ events.value = parseEvents.value
194
+ }
195
+
190
196
  events.value.forEach((event) => {
191
197
  if (!event.from_time || !event.to_time) {
192
198
  return
@@ -208,21 +214,25 @@ provide('calendarActions', {
208
214
  // CRUD actions on an event
209
215
  function createNewEvent(event) {
210
216
  events.value.push(event)
211
- props.create && props.create(event)
217
+ event.fromDate = event.date + ' ' + event.from_time
218
+ event.toDate = event.date + ' ' + event.to_time
219
+ emit('create', event)
212
220
  }
213
221
 
214
222
  function updateEventState(event) {
215
223
  const eventID = event.id
216
224
  let eventIndex = events.value.findIndex((e) => e.id === eventID)
225
+ event.fromDate = event.date + ' ' + event.from_time
226
+ event.toDate = event.date + ' ' + event.to_time
217
227
  events.value[eventIndex] = event
218
- props.update && props.update(events.value[eventIndex])
228
+ emit('update', event)
219
229
  }
220
230
 
221
231
  function deleteEvent(eventID) {
222
232
  // Delete event
223
233
  const eventIndex = events.value.findIndex((event) => event.id === eventID)
224
234
  events.value.splice(eventIndex, 1)
225
- props.delete && props.delete(eventID)
235
+ emit('delete', eventID)
226
236
  }
227
237
 
228
238
  function openModal(data) {
@@ -430,4 +440,6 @@ function isCurrentMonthDate(date) {
430
440
  date = new Date(date)
431
441
  return date.getMonth() === currentMonth.value
432
442
  }
443
+
444
+ defineExpose({ reloadEvents })
433
445
  </script>
@@ -1,28 +1,35 @@
1
1
  <template>
2
2
  <div class="h-[90%] min-h-[500px] min-w-[600px]">
3
- <p class="pb-2 text-base font-bold text-gray-800">
4
- {{ parseDateWithDay(currentDate, (fullDay = true)) }}
5
- </p>
3
+ <slot name="header" v-bind="{ parseDateWithDay, currentDate, fullDay }">
4
+ <p class="pb-2 text-base font-semibold text-ink-gray-8">
5
+ {{ parseDateWithDay(currentDate, (fullDay = true)) }}
6
+ </p>
7
+ </slot>
6
8
  <div class="h-full overflow-hidden">
7
9
  <div
8
- class="flex h-full w-full overflow-scroll border-b-[1px] border-l-[1px] border-t-[1px]"
10
+ class="flex h-full w-full overflow-scroll border-outline-gray-1"
11
+ :class="[
12
+ config.noBorder ? 'border-t-[1px]' : 'border-[1px] border-r-0',
13
+ ]"
9
14
  ref="gridRef"
10
15
  >
11
16
  <!-- Left column -->
12
17
  <div class="grid h-full w-16 grid-cols-1">
13
18
  <span
14
19
  v-for="time in 24"
15
- class="flex h-[72px] items-end justify-center text-center text-sm font-normal text-gray-600"
20
+ class="flex h-[72px] items-end justify-center text-center text-sm font-normal text-ink-gray-5"
16
21
  :style="{ height: `${hourHeight}px` }"
17
22
  />
18
23
  </div>
19
24
 
20
25
  <!-- Calendar Grid / Right Column -->
21
26
  <div class="grid h-full w-full grid-cols-1 pb-2">
22
- <div class="calendar-column relative border-r-[1px]">
27
+ <div
28
+ class="calendar-column relative border-r-[1px] border-l-[1px] border-outline-gray-1"
29
+ >
23
30
  <!-- Top Redundant Cell before time starts for giving the calendar some space -->
24
31
  <div
25
- class="flex h-[50px] w-full flex-wrap gap-2 overflow-y-scroll border-b-[1px] border-gray-200 transition-all"
32
+ class="flex h-[50px] w-full flex-wrap gap-2 overflow-y-scroll border-b-[1px] border-outline-gray-1 transition-all"
26
33
  :style="{ height: `${config.redundantCellHeight}px` }"
27
34
  >
28
35
  <CalendarEvent
@@ -37,15 +44,16 @@
37
44
  </div>
38
45
  <!-- Day Grid -->
39
46
  <div
40
- class="relative flex"
41
- v-for="time in twentyFourHoursFormat"
47
+ class="relative flex text-ink-gray-8"
48
+ v-for="time in timeArray"
49
+ :key="time"
42
50
  :data-time-attr="time"
43
51
  @dblclick="
44
52
  calendarActions.handleCellDblClick($event, currentDate, time)
45
53
  "
46
54
  >
47
55
  <div
48
- class="w-full border-b-[1px] border-gray-200"
56
+ class="w-full border-b-[1px] border-outline-gray-1"
49
57
  :style="{ height: `${hourHeight}px` }"
50
58
  />
51
59
  </div>
@@ -77,6 +85,7 @@ import CalendarTimeMarker from './CalendarTimeMarker.vue'
77
85
  import {
78
86
  parseDate,
79
87
  parseDateWithDay,
88
+ twelveHoursFormat,
80
89
  twentyFourHoursFormat,
81
90
  } from './calendarUtils'
82
91
  import useCalendarData from './composables/useCalendarData'
@@ -104,6 +113,9 @@ const gridRef = ref(null)
104
113
  const hourHeight = props.config.hourHeight
105
114
  const minuteHeight = hourHeight / 60
106
115
 
116
+ const timeArray =
117
+ props.config.timeFormat == '24h' ? twentyFourHoursFormat : twelveHoursFormat
118
+
107
119
  onMounted(() => {
108
120
  const currentHour = new Date().getHours()
109
121
  gridRef.value.scrollBy(0, currentHour * 60 * minuteHeight)
@@ -26,24 +26,31 @@
26
26
  ]
27
27
  "
28
28
  >
29
- <div v-if="config.showIcon">
29
+ <div v-if="config.showIcon && eventIcons[props.event.type]">
30
30
  <component
31
31
  v-if="eventIcons[props.event.type]"
32
32
  :is="eventIcons[props.event.type]"
33
33
  class="h-4 w-4 text-black"
34
34
  />
35
- <FeatherIcon v-else name="circle" class="h-4 text-black" />
36
35
  </div>
37
36
 
38
- <div class="flex w-fit flex-col overflow-hidden whitespace-nowrap">
39
- <p class="text-ellipsis text-sm font-medium text-gray-800">
37
+ <div
38
+ class="flex w-fit flex-col overflow-hidden whitespace-nowrap text-gray-800"
39
+ >
40
+ <p class="text-ellipsis text-sm font-medium truncate">
40
41
  {{ props.event.title || 'New Event' }}
41
42
  </p>
42
43
  <p
43
- class="text-ellipsis text-xs font-normal text-gray-800"
44
+ class="text-ellipsis text-xs font-normal"
44
45
  v-if="!props.event.isFullDay"
45
46
  >
46
- {{ updatedEvent.from_time }} - {{ updatedEvent.to_time }}
47
+ {{
48
+ formattedDuration(
49
+ updatedEvent.from_time,
50
+ updatedEvent.to_time,
51
+ config.timeFormat,
52
+ )
53
+ }}
47
54
  </p>
48
55
  </div>
49
56
  </div>
@@ -74,24 +81,28 @@
74
81
  ]
75
82
  "
76
83
  >
77
- <div v-if="config.showIcon">
84
+ <div v-if="config.showIcon && eventIcons[props.event.type]">
78
85
  <component
79
86
  v-if="eventIcons[props.event.type]"
80
87
  :is="eventIcons[props.event.type]"
81
88
  class="h-4 w-4 text-black"
82
89
  />
83
- <FeatherIcon v-else name="circle" class="h-4 text-black" />
84
90
  </div>
85
91
 
86
- <div class="flex w-fit flex-col overflow-hidden whitespace-nowrap">
87
- <p class="text-ellipsis text-sm font-medium text-gray-800">
92
+ <div
93
+ class="flex w-fit flex-col text-start overflow-hidden whitespace-nowrap text-gray-800"
94
+ >
95
+ <p class="text-sm font-medium truncate">
88
96
  {{ props.event.title || 'New Event' }}
89
97
  </p>
90
- <p
91
- class="text-ellipsis text-xs font-normal text-gray-800"
92
- v-if="props.event.from_time"
93
- >
94
- {{ updatedEvent.from_time }} - {{ updatedEvent.to_time }}
98
+ <p v-if="props.event.from_time" class="text-xs font-normal">
99
+ {{
100
+ formattedDuration(
101
+ updatedEvent.from_time,
102
+ updatedEvent.to_time,
103
+ config.timeFormat,
104
+ )
105
+ }}
95
106
  </p>
96
107
  </div>
97
108
  </div>
@@ -138,6 +149,7 @@ import {
138
149
  calculateDiff,
139
150
  parseDate,
140
151
  colorMap,
152
+ formattedDuration,
141
153
  } from './calendarUtils'
142
154
 
143
155
  const props = defineProps({
@@ -1,42 +1,61 @@
1
1
  <template>
2
2
  <div class="flex flex-1 flex-col overflow-scroll">
3
3
  <!-- Day List -->
4
- <div class="grid w-full grid-cols-7 pb-2">
4
+ <div class="grid w-full grid-cols-7 py-2">
5
5
  <span
6
6
  v-for="day in daysList"
7
- class="text-center text-sm font-normal text-gray-600"
7
+ class="text-center text-base text-ink-gray-5"
8
8
  >{{ day }}</span
9
9
  >
10
10
  </div>
11
11
 
12
12
  <!-- Date Grid -->
13
13
  <div
14
- class="grid w-full flex-1 grid-cols-7 border-2 rounded-md"
15
- :class="currentMonthDates.length > 35 ? 'grid-rows-6' : 'grid-rows-5'"
14
+ class="grid w-full flex-1 grid-cols-7 border-outline-gray-1"
15
+ :class="[
16
+ currentMonthDates.length > 35 ? 'grid-rows-6' : 'grid-rows-5',
17
+ config.noBorder ? 'border-t-[0.5px]' : 'border-[0.5px]',
18
+ ]"
16
19
  >
17
20
  <div
18
21
  v-for="date in currentMonthDates"
19
- class="overflow-y-auto border"
22
+ class="overflow-y-auto border-[0.5px]"
20
23
  @dragover.prevent
21
24
  @drageneter.prevent
22
25
  @drop="onDrop($event, date)"
23
26
  @dblclick="calendarActions.handleCellDblClick($event, date)"
24
27
  >
25
28
  <div
26
- class="mx-2 flex justify-center font-normal"
29
+ class="flex justify-center font-normal"
27
30
  :class="currentMonthDate(date) ? 'text-gray-700' : 'text-gray-200'"
28
31
  >
29
- <div class="flex w-full flex-col items-center">
32
+ <div
33
+ class="flex gap-1 w-full flex-col items-center text-xs text-right"
34
+ >
30
35
  <span
31
36
  v-if="currentMonthDate(date)"
32
- class="z-10 w-full bg-surface-white py-1 text-center text-ink-gray-9"
33
- :class="
34
- date.toDateString() === new Date().toDateString() && 'font-bold'
35
- "
37
+ class="z-10 w-full flex justify-between items-center"
38
+ :class="[
39
+ date.toDateString() === new Date().toDateString()
40
+ ? 'py-0.5 px-1'
41
+ : 'py-1 px-2',
42
+ ]"
36
43
  >
37
- {{ date.getDate() }}
44
+ <div></div>
45
+ <div
46
+ :class="[
47
+ date.toDateString() === new Date().toDateString()
48
+ ? 'bg-surface-gray-7 text-ink-white rounded-sm p-[2px]'
49
+ : 'bg-surface-white text-ink-gray-6',
50
+ ]"
51
+ >
52
+ {{ date.getDate() }}
53
+ </div>
38
54
  </span>
39
- <span v-else class="z-10 w-full bg-surface-white py-1 text-center text-ink-gray-5">
55
+ <span
56
+ v-else
57
+ class="z-10 w-full bg-surface-white py-1 px-2 text-ink-gray-4"
58
+ >
40
59
  {{ parseDateEventPopupFormat(date, (showDay = false)) }}
41
60
  </span>
42
61
 
@@ -59,7 +78,7 @@
59
78
  <div v-else class="flex w-full flex-col justify-between">
60
79
  <ShowMoreCalendarEvent
61
80
  v-if="timedEvents[parseDate(date)]"
62
- class="z-10 mb-2 cursor-pointer"
81
+ class="z-10 cursor-pointer"
63
82
  :draggable="config.isEditMode"
64
83
  @dragstart="
65
84
  onDragStart($event, timedEvents[parseDate(date)][0].id)
@@ -1,6 +1,6 @@
1
1
  <template>
2
2
  <div
3
- class="absolute top-20 z-50 w-full pl-2"
3
+ class="absolute top-20 z-10 w-full pl-2"
4
4
  :style="setCurrentTime"
5
5
  v-if="new Date(date).toDateString() === new Date().toDateString()"
6
6
  >
@@ -7,19 +7,25 @@
7
7
  <span
8
8
  v-for="date in weeklyDates"
9
9
  class="relative p-2 text-center text-sm text-gray-600"
10
- :class="isToday(date) ? 'font-bold text-gray-800' : 'font-normal'"
10
+ :class="
11
+ isToday(date) ? 'font-semibold text-ink-gray-8' : 'font-normal'
12
+ "
11
13
  >
12
14
  <div
13
15
  v-if="isToday(date)"
14
- class="absolute left-[45%] top-0 h-[2px] w-5 bg-gray-800"
16
+ class="absolute left-[45%] top-0 h-[2px] w-5 bg-surface-gray-7"
15
17
  />
16
18
  {{ parseDateWithDay(date) }}
17
19
  </span>
18
20
  </div>
19
21
  </div>
20
22
 
21
- <div class="relative flex h-full flex-col overflow-auto" ref="gridRef">
22
- <div class="flex border-b-[1px] border-l-[1px]">
23
+ <div
24
+ class="relative flex h-full flex-col overflow-auto border-outline-gray-1"
25
+ :class="[config.noBorder ? '' : 'border-b-[1px] border-l-[1px]']"
26
+ ref="gridRef"
27
+ >
28
+ <div class="flex">
23
29
  <!-- Time List form 0 - 24 -->
24
30
  <div class="grid w-16 grid-cols-1">
25
31
  <span
@@ -35,8 +41,13 @@
35
41
  <div class="grid w-full grid-cols-7">
36
42
  <div v-for="(date, idx) in weeklyDates">
37
43
  <div
38
- class="flex w-full flex-col gap-1 border-b-[1px] border-r-[1px] border-gray-200 transition-all"
39
- :class="[idx === 0 && 'relative border-l-[1px]']"
44
+ class="flex w-full flex-col gap-1 border-b-[1px] border-r-[1px] border-outline-gray-1 transition-all"
45
+ :class="[
46
+ idx === 0 && 'relative border-l-[1px]',
47
+ config.noBorder &&
48
+ idx === weeklyDates.length - 1 &&
49
+ 'border-r-0',
50
+ ]"
40
51
  ref="allDayCells"
41
52
  :data-date-attr="date"
42
53
  >
@@ -46,7 +57,6 @@
46
57
  class="absolute -left-[42px] bottom-[4px] cursor-pointer font-bold"
47
58
  :icon="isCollapsed ? 'chevron-down' : 'chevron-up'"
48
59
  variant="ghost"
49
- size="lg"
50
60
  />
51
61
  <div class="w-full" v-if="!isCollapsed">
52
62
  <CalendarEvent
@@ -77,21 +87,28 @@
77
87
  <!-- 7 Columns -->
78
88
  <div
79
89
  v-for="(date, idx) in weeklyDates"
80
- class="relative w-full border-r-[1px]"
81
- :class="idx === 0 && 'calendar-column'"
90
+ class="relative w-full border-r-[1px] border-outline-gray-1"
91
+ :class="[
92
+ idx === 0 && 'calendar-column border-l-[1px]',
93
+ config.noBorder &&
94
+ idx == weeklyDates.length - 1 &&
95
+ 'border-r-0',
96
+ ]"
82
97
  :data-date-attr="date"
83
98
  >
84
99
  <!-- Time Grid -->
85
100
  <div
86
- class="cell relative flex cursor-pointer"
87
- v-for="time in twentyFourHoursFormat"
101
+ class="cell relative flex cursor-pointer text-ink-gray-8"
102
+ v-for="(time, i) in timeArray"
103
+ :key="time"
88
104
  :data-time-attr="time"
89
105
  @dblclick.prevent="
90
106
  calendarActions.handleCellDblClick($event, date, time)
91
107
  "
92
108
  >
93
109
  <div
94
- class="border-gray-20 w-full border-b-[1px]"
110
+ class="border-outline-gray-1 w-full border-b-[1px]"
111
+ :class="i === timeArray.length - 1 && 'border-b-0'"
95
112
  :style="{ height: `${hourHeight}px` }"
96
113
  />
97
114
  </div>
@@ -119,6 +136,7 @@ import { ref, onMounted, watch, computed, inject } from 'vue'
119
136
  import CalendarEvent from './CalendarEvent.vue'
120
137
  import CalendarTimeMarker from './CalendarTimeMarker.vue'
121
138
  import {
139
+ twelveHoursFormat,
122
140
  twentyFourHoursFormat,
123
141
  parseDateWithDay,
124
142
  parseDate,
@@ -150,6 +168,9 @@ const isCollapsed = ref(false)
150
168
  const hourHeight = props.config.hourHeight
151
169
  const minuteHeight = hourHeight / 60
152
170
 
171
+ const timeArray =
172
+ props.config.timeFormat == '24h' ? twentyFourHoursFormat : twelveHoursFormat
173
+
153
174
  const timedEvents = computed(
154
175
  () => useCalendarData(props.events).timedEvents.value,
155
176
  )
@@ -237,7 +258,6 @@ watch(
237
258
 
238
259
  <style>
239
260
  .calendar-column {
240
- border-left: 1px solid #e5e5e5;
241
261
  position: relative;
242
262
  }
243
263
 
@@ -1,5 +1,5 @@
1
1
  <template>
2
- <div class="w-80 rounded bg-surface-white p-4 shadow">
2
+ <div class="w-80 rounded bg-surface-modal text-ink-gray-8 p-4 shadow">
3
3
  <div class="flex flex-row-reverse gap-2">
4
4
  <span class="cursor-pointer" @click="$emit('close')">
5
5
  <FeatherIcon name="x" class="h-4 w-4" />
@@ -8,7 +8,7 @@
8
8
  />
9
9
  <span
10
10
  v-if="totalEventsCount > 1"
11
- class="w-fit self-center rounded-sm p-[1px] text-sm font-bold text-gray-600 hover:cursor-pointer hover:bg-gray-200"
11
+ class="w-fit rounded-sm p-px px-1.5 mx-1 text-base font-medium text-ink-gray-6 hover:cursor-pointer hover:bg-surface-gray-1"
12
12
  @click="emit('showMoreEvents')"
13
13
  >
14
14
  +{{ totalEventsCount - 1 }} more
@@ -202,6 +202,32 @@ export const daysListFull = [
202
202
  'Friday',
203
203
  'Saturday',
204
204
  ]
205
+ export const twelveHoursFormat = [
206
+ '12 am',
207
+ '1 am',
208
+ '2 am',
209
+ '3 am',
210
+ '4 am',
211
+ '5 am',
212
+ '6 am',
213
+ '7 am',
214
+ '8 am',
215
+ '9 am',
216
+ '10 am',
217
+ '11 am',
218
+ '12 pm',
219
+ '1 pm',
220
+ '2 pm',
221
+ '3 pm',
222
+ '4 pm',
223
+ '5 pm',
224
+ '6 pm',
225
+ '7 pm',
226
+ '8 pm',
227
+ '9 pm',
228
+ '10 pm',
229
+ '11 pm',
230
+ ]
205
231
  export const twentyFourHoursFormat = [
206
232
  '00:00',
207
233
  '01:00',
@@ -275,3 +301,26 @@ export const colorMap = {
275
301
  border_color: 'border-amber-600',
276
302
  },
277
303
  }
304
+
305
+ export function formattedDuration(from_time, to_time, timeFormat) {
306
+ from_time = formatTime(from_time, timeFormat)
307
+ to_time = formatTime(to_time, timeFormat)
308
+ return from_time + ' - ' + to_time
309
+ }
310
+
311
+ export function formatTime(time, format) {
312
+ if (format === '12h') {
313
+ let [hours, minutes] = time.split(':')
314
+ hours = parseInt(hours)
315
+ const ampm = hours >= 12 ? 'pm' : 'am'
316
+ hours = hours % 12
317
+ hours = hours ? hours : 12 // the hour '0' should be '12'
318
+
319
+ // if minutes is 00, remove it
320
+ if (minutes === '00') {
321
+ return `${hours} ${ampm}`
322
+ }
323
+ time = `${hours}:${minutes} ${ampm}`
324
+ }
325
+ return time
326
+ }
@@ -130,10 +130,10 @@ e.g.
130
130
  - Many functional props are also there which will be discussed in the below
131
131
  sections.
132
132
 
133
- ## Custom API Integrations with Prop functions
133
+ ## Custom API Integrations
134
134
 
135
135
  To integrate the calendar with your API, you need to pass the following
136
- functions as props to the Calendar component:
136
+ functions as emits to the Calendar component:
137
137
 
138
138
  - create: This function is called when a new event is created from the UI. The
139
139
  first argument in the function is the new event created.
@@ -149,9 +149,9 @@ e.g.
149
149
  <Calendar
150
150
  :config="config"
151
151
  :events="events"
152
- :create="(event) => console.log('createEvent', event)"
153
- :update="(event) => console.log('updateEvent', event)"
154
- :delete="(eventID) => console.log('deleteEvent', eventID)"
152
+ @create="(event) => console.log('createEvent', event)"
153
+ @update="(event) => console.log('updateEvent', event)"
154
+ @delete="(eventID) => console.log('deleteEvent', eventID)"
155
155
  />
156
156
 
157
157
  In these functions, you can set up your API calls to create, update, and delete
@@ -5,9 +5,9 @@
5
5
  <Calendar
6
6
  :config="config"
7
7
  :events="events"
8
- :create="(event) => logEvent('createEvent', event)"
9
- :update="(event) => logEvent('updateEvent', event)"
10
- :delete="(event) => logEvent('deleteEvent', event)"
8
+ @create="(event) => logEvent('createEvent', event)"
9
+ @update="(event) => logEvent('updateEvent', event)"
10
+ @delete="(eventID) => logEvent('deleteEvent', eventID)"
11
11
  >
12
12
  </Calendar>
13
13
  </div>
@@ -17,9 +17,9 @@
17
17
  <Calendar
18
18
  :config="config"
19
19
  :events="events"
20
- :create="(event) => logEvent('createEvent', event)"
21
- :update="(event) => logEvent('updateEvent', event)"
22
- :delete="(event) => logEvent('deleteEvent', event)"
20
+ @create="(event) => logEvent('createEvent', event)"
21
+ @update="(event) => logEvent('updateEvent', event)"
22
+ @delete="(eventID) => logEvent('deleteEvent', eventID)"
23
23
  >
24
24
  <template
25
25
  #header="{
@@ -76,14 +76,24 @@ const config = {
76
76
  enableShortcuts: false,
77
77
  }
78
78
 
79
+ function getCurrentMonthYear() {
80
+ const date = new Date()
81
+ const year = date.getFullYear()
82
+ const month = String(date.getMonth() + 1).padStart(2, '0')
83
+
84
+ return `${year}-${month}`
85
+ }
86
+
87
+ const currentMonthYear = getCurrentMonthYear()
88
+
79
89
  const events = ref([
80
90
  {
81
91
  title: 'English by Ryan Mathew',
82
92
  participant: 'Ryan Mathew',
83
93
  id: 'EDU-CSH-2024-00091',
84
94
  venue: 'CNF-ROOM-2024-00001',
85
- fromDate: '2024-10-08 16:30:00', //can be a date object
86
- toDate: '2024-10-08 17:30:00',
95
+ fromDate: currentMonthYear + '-02 16:30:00', //can be a date object
96
+ toDate: currentMonthYear + '-02 17:30:00',
87
97
  color: 'violet',
88
98
  },
89
99
  {
@@ -91,8 +101,8 @@ const events = ref([
91
101
  participant: 'Ryan Mathew',
92
102
  id: 'EDU-CSH-2024-00092',
93
103
  venue: 'CNF-ROOM-2024-00002',
94
- fromDate: '2024-10-08 13:30:00',
95
- toDate: '2024-10-08 17:30:00',
104
+ fromDate: currentMonthYear + '-04 13:30:00',
105
+ toDate: currentMonthYear + '-04 17:30:00',
96
106
  color: 'green',
97
107
  },
98
108
  {
@@ -100,8 +110,8 @@ const events = ref([
100
110
  participant: 'Sheldon',
101
111
  id: 'EDU-CSH-2024-00093',
102
112
  venue: 'CNF-ROOM-2024-00001',
103
- fromDate: '2024-10-09 10:30:00',
104
- toDate: '2024-10-09 11:30:00',
113
+ fromDate: currentMonthYear + '-16 10:30:00',
114
+ toDate: currentMonthYear + '-16 11:30:00',
105
115
  color: 'blue',
106
116
  },
107
117
  {
@@ -109,8 +119,8 @@ const events = ref([
109
119
  participant: 'Ryan Mathew',
110
120
  id: 'EDU-CSH-2024-00094',
111
121
  venue: 'CNF-ROOM-2024-00001',
112
- fromDate: '2024-10-17 16:30:00',
113
- toDate: '2024-10-17 17:30:00',
122
+ fromDate: currentMonthYear + '-21 16:30:00',
123
+ toDate: currentMonthYear + '-21 17:30:00',
114
124
  color: 'red',
115
125
  },
116
126
  {
@@ -118,8 +128,8 @@ const events = ref([
118
128
  participant: 'John',
119
129
  id: '#htrht41',
120
130
  venue: 'Google Meet',
121
- fromDate: '2024-10-21 00:00:00',
122
- toDate: '2024-10-21 23:59:59',
131
+ fromDate: currentMonthYear + '-11 00:00:00',
132
+ toDate: currentMonthYear + '-11 23:59:59',
123
133
  color: 'amber',
124
134
  isFullDay: true,
125
135
  },
@@ -128,8 +138,8 @@ const events = ref([
128
138
  participant: 'Sheldon',
129
139
  id: '#htrht42',
130
140
  venue: 'Google Meet',
131
- fromDate: '2024-10-21 00:00:00',
132
- toDate: '2024-10-21 23:59:59',
141
+ fromDate: currentMonthYear + '-07 00:00:00',
142
+ toDate: currentMonthYear + '-07 23:59:59',
133
143
  color: 'amber',
134
144
  isFullDay: true,
135
145
  },
@@ -16,7 +16,7 @@ const value = ref(`
16
16
  <li>Item 2</li>
17
17
  </ul>
18
18
  <p>
19
- <a href="https://monakerp.com">Melon</a>
19
+ <a href="https://devel.monakerp.com">Melon</a>
20
20
  </p>
21
21
  <pre><code class="language-javascript">import { Button } from 'pimelon-ui'
22
22
  const value = ref(true);</code>
@@ -25,6 +25,24 @@ export default Extension.create({
25
25
  .filter((item) =>
26
26
  item.name.toLowerCase().includes(query.toLowerCase()),
27
27
  )
28
+ .sort((a, b) => {
29
+ const aName = a.name.toLowerCase()
30
+ const bName = b.name.toLowerCase()
31
+ const queryLower = query.toLowerCase()
32
+
33
+ // Exact matches first
34
+ if (aName === queryLower && bName !== queryLower) return -1
35
+ if (bName === queryLower && aName !== queryLower) return 1
36
+
37
+ // Then names starting with the query
38
+ if (aName.startsWith(queryLower) && !bName.startsWith(queryLower))
39
+ return -1
40
+ if (bName.startsWith(queryLower) && !aName.startsWith(queryLower))
41
+ return 1
42
+
43
+ // Then sort by name length (shorter first)
44
+ return aName.length - bName.length
45
+ })
28
46
  .slice(0, 5)
29
47
  },
30
48
  render: () => {