@@ -10,6 +10,8 @@ import { router } from '@inertiajs/vue3'
10
10
import InertiaLink from ' @/Shared/InertiaLink.vue'
11
11
import { useGlobalProps } from ' @/Composables/useGlobalProps'
12
12
import AppLayout from ' @/Shared/Layout/AppLayout.vue'
13
+ import { useStorage } from ' @vueuse/core'
14
+ import Draggable from ' vuedraggable'
13
15
14
16
const props = defineProps ({
15
17
users: Object ,
@@ -20,7 +22,10 @@ const props = defineProps({
20
22
21
23
const { auth } = useGlobalProps ()
22
24
23
- let activeElement = ref (undefined )
25
+ const highlighted = useStorage (` calendar-highlight:${ auth .value .user .id } ` , [])
26
+ const order = useStorage (` calendar-order:${ auth .value .user .id } ` , props .users .data .map (user => user .id ))
27
+
28
+ const usersInOrder = ref ([... props .users .data ].sort ((a , b ) => order .value .indexOf (a .id ) > order .value .indexOf (b .id ) ? 1 : - 1 ))
24
29
25
30
const currentDate = DateTime .now ()
26
31
@@ -34,6 +39,10 @@ watch(selectedMonth, (value, oldValue) => {
34
39
router .visit (` /calendar/${ value .toFormat (' LL-yyyy' )} ` )
35
40
})
36
41
42
+ watch (usersInOrder, (value ) => {
43
+ order .value = value .map (item => item .id )
44
+ })
45
+
37
46
function previousMonth () {
38
47
selectedMonth .value = selectedMonth .value .minus ({ month: 1 })
39
48
}
@@ -46,26 +55,23 @@ function currentMonth() {
46
55
selectedMonth .value = currentDate
47
56
}
48
57
49
- function isActiveDay (key ) {
50
- return activeElement .value === key
51
- }
52
-
53
- function setActiveDay (key ) {
54
- if (activeElement .value === undefined )
55
- activeElement .value = key
56
- }
57
-
58
- function unsetActiveDay () {
59
- activeElement .value = undefined
60
- }
61
-
62
58
function linkParameters (user , day ) {
63
59
return auth .value .can .createRequestsOnBehalfOfEmployee ? { user: user .id , from_date: day .date } : { from_date: day .date }
64
60
}
65
61
66
62
function linkVacationRequest (user ) {
67
63
return auth .value .user .id === user .id || auth .value .can .manageRequestsAsTechnicalApprover || auth .value .can .manageRequestsAsAdministrativeApprover
68
64
}
65
+
66
+ function toggleHighlight (id ) {
67
+ if (highlighted .value .includes (id)) {
68
+ highlighted .value = highlighted .value .filter (item => item !== id)
69
+
70
+ return
71
+ }
72
+
73
+ highlighted .value .push (id)
74
+ }
69
75
< / script>
70
76
71
77
< template>
@@ -145,7 +151,7 @@ function linkVacationRequest(user) {
145
151
< tr>
146
152
< th class = " py-2 w-64 text-lg font-semibold text-gray-800 border border-gray-300" >
147
153
< div class = " flex justify-center items-center capitalize" >
148
- {{ selectedMonth .toLocaleString ({ month: ' long' , year: ' numeric' }) }}
154
+ {{ selectedMonth .toLocaleString ({month: ' long' , year: ' numeric' }) }}
149
155
< / div>
150
156
< / th>
151
157
< th
@@ -164,62 +170,73 @@ function linkVacationRequest(user) {
164
170
< / th>
165
171
< / tr>
166
172
< / thead>
167
- < tbody>
168
- < tr
169
- v- for = " user in users.data"
170
- : key= " user.id"
171
- : class = " [user.isActive ? '' : 'bg-gray-100']"
172
- >
173
- < th class = " p-2 border border-gray-300" >
174
- < UserProfileLink
175
- : user= " user"
173
+ < Draggable
174
+ v- model= " usersInOrder"
175
+ tag= " tbody"
176
+ ghost- class = " opacity-50"
177
+ handle= " .handle"
178
+ : animation= " 200"
179
+ : component- data= " {tag: 'div', type: 'transition-group'}"
180
+ : item- key= " ((item) => usersInOrder.indexOf(item))"
181
+ >
182
+ < template #item= " { element }" >
183
+ < tr
184
+ : class = " [!element.isActive && 'bg-gray-100', element.isActive && highlighted.includes(element.id) && 'bg-green-600/5']"
185
+ >
186
+ < th
187
+ : class = " ['p-2 border border-gray-300 text-left', highlighted.includes(element.id) && 'bg-green-600/5']"
188
+ @click= " toggleHighlight(element.id)"
176
189
>
177
- < div class = " flex justify-start items-center" >
178
- < span class = " inline-flex justify-center items-center size-8 rounded-full" >
179
- < img : src= " user.avatar" >
180
- < / span>
181
- < div class = " ml-3" >
182
- < div class = " text-sm font-medium text-gray-900 truncate" >
183
- {{ user .name }}
190
+ < UserProfileLink
191
+ class = " inline-flex"
192
+ : user= " element"
193
+ >
194
+ < div class = " flex justify-start items-center" >
195
+ < span class = " inline-flex justify-center items-center size-8 rounded-full handle cursor-move" >
196
+ < img : src= " element.avatar" >
197
+ < / span>
198
+ < div class = " ml-3" >
199
+ < div class = " text-sm font-medium text-gray-900 truncate" >
200
+ {{ element .name }}
201
+ < / div>
184
202
< / div>
185
203
< / div>
186
- < / div>
187
- < / UserProfileLink>
188
- < / th>
189
- < td
190
- v- for = " day in calendar"
191
- : key= " day.dayOfMonth"
192
- : class = " { 'bg-blumilk-25': day.isToday, 'bg-red-100': day.isWeekend || day.isHoliday }"
193
- class = " border border-gray-300"
194
- @mouseleave= " unsetActiveDay"
195
- @mouseover= " setActiveDay(user.id + '+' + day.date)"
196
- >
197
- < div
198
- v- if = " user.id in day.vacations"
199
- class = " flex justify-center items-center"
204
+ < / UserProfileLink>
205
+ < / th>
206
+ < td
207
+ v- for = " day in calendar"
208
+ : key= " day.dayOfMonth"
209
+ : class = " { 'bg-blumilk-25': day.isToday, 'bg-red-100': day.isWeekend || day.isHoliday }"
210
+ class = " border border-gray-300 group"
200
211
>
201
- < CalendarDay
202
- : see- vacation- details= " linkVacationRequest(user)"
203
- : vacation= " day.vacations[user.id]"
204
- / >
205
- < / div>
206
- < template
207
- v- else - if = " isActiveDay(user.id + '+' + day.date) && !day.isWeekend && !day.isHoliday && (auth.user.id === user.id || auth.can.createRequestsOnBehalfOfEmployee)"
208
- >
209
- < InertiaLink
210
- : data= " linkParameters(user, day)"
211
- href= " /vacation/requests/create"
212
+ < div
213
+ v- if = " element.id in day.vacations"
214
+ class = " flex justify-center items-center"
212
215
>
213
- < div class = " flex justify-center items-center" >
214
- < VacationTypeCalendarIcon
215
- type= " create"
216
- / >
217
- < / div>
218
- < / InertiaLink>
219
- < / template>
220
- < / td>
221
- < / tr>
222
- < / tbody>
216
+ < CalendarDay
217
+ : see- vacation- details= " linkVacationRequest(element)"
218
+ : vacation= " day.vacations[element.id]"
219
+ / >
220
+ < / div>
221
+ < template
222
+ v- else - if = " !day.isWeekend && !day.isHoliday && (auth.user.id === element.id || auth.can.createRequestsOnBehalfOfEmployee)"
223
+ >
224
+ < InertiaLink
225
+ : data= " linkParameters(element, day)"
226
+ href= " /vacation/requests/create"
227
+ class = " hidden group-hover:block"
228
+ >
229
+ < div class = " flex justify-center items-center" >
230
+ < VacationTypeCalendarIcon
231
+ type= " create"
232
+ / >
233
+ < / div>
234
+ < / InertiaLink>
235
+ < / template>
236
+ < / td>
237
+ < / tr>
238
+ < / template>
239
+ < / Draggable>
223
240
< / table>
224
241
< / div>
225
242
< / div>
0 commit comments