@neutron.co.id/operasional-interfaces 1.17.13-beta.1 → 1.17.13
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.
- package/build/@office/common/providers/api/apiUrl.d.ts +3 -0
- package/build/@office/common/providers/api/apiUrl.mjs +43 -0
- package/build/@office/common/providers/api/index.d.ts +1 -0
- package/build/@office/common/providers/api/index.mjs +1 -0
- package/build/@office/common/providers/index.d.ts +1 -0
- package/build/@office/common/providers/index.mjs +1 -0
- package/build/@office/models/personalia/attendance/AttendanceDelegate.vue +99 -14
- package/build/@office/models/personalia/attendance/AttendanceManager.vue +129 -15
- package/build/@office/models/personalia/attendance/AttendanceSingle/AttendanceSingle.vue +3 -1
- package/build/@office/models/personalia/attendance/AttendanceStaff.vue +184 -45
- package/build/@office/models/personalia/attendance/AttendanceSupervisor.vue +163 -36
- package/build/@office/models/personalia/leaveConflict/LeaveConflictCollection/LeaveConflictCollection.vue +1 -1
- package/build/@office/models/personalia/leaveConflict/LeaveConflictSingle/LeaveConflictSingle.vue +2 -2
- package/build/@office/models/personalia/leaveQuota/LeaveQuotaSingle/LeaveQuotaSingle.vue +27 -3
- package/build/@office/models/personalia/leaveStaff/LeaveStaffSingle/LeaveStaffSingle.vue +2 -2
- package/build/@office/models/personalia/shift/ShiftAdministrator.vue +1 -33
- package/build/@office/models/personalia/shift/ShiftSupervisor.vue +0 -1
- package/build/@office/models/personalia/shiftStaff/ShiftStaffCollectionBranch.vue +1 -1
- package/build/@office/models/personalia/shiftStaff/ShiftStaffCollectionStaff.vue +2 -1
- package/build/@office/models/personalia/shiftStaff/ShiftStaffWrapper/ShiftStaffDisplay.vue +4 -2
- package/build/@office/models/personalia/shiftStaff/ShiftStaffWrapper/ShiftStaffWrapper.vue +9 -13
- package/build/@package/@office/common/providers/api/apiUrl.d.ts +3 -0
- package/build/@package/@office/common/providers/api/index.d.ts +1 -0
- package/build/@package/@office/common/providers/index.d.ts +1 -0
- package/build/mock/index.cjs +1484 -1043
- package/build/mock/index.mjs +1484 -1043
- package/build/mock/style.css +16 -16
- package/build/module.json +1 -1
- package/build/nuxt.json +1 -1
- package/package.json +5 -5
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
|
-
import { GraphUtil, NeonSingle, useSingle } from '@neon.id/context'
|
|
2
|
+
import { GraphUtil, NeonSingle, useSingle, useAppStore } from '@neon.id/context'
|
|
3
3
|
import { NeonCheck, NeonField, NeonForm } from '@neon.id/form'
|
|
4
4
|
import {
|
|
5
5
|
NeonAlert,
|
|
@@ -7,10 +7,11 @@ import {
|
|
|
7
7
|
NeonDivider,
|
|
8
8
|
useToastStore,
|
|
9
9
|
NeonCopy,
|
|
10
|
+
NeonImage,
|
|
10
11
|
} from '@neon.id/interfaces'
|
|
11
12
|
import { OfficeRelation, OfficeTab, OfficeTabs } from '@neon.id/office'
|
|
12
13
|
import { Query } from '@neon.id/query'
|
|
13
|
-
import { computed, ref, watch } from 'vue'
|
|
14
|
+
import { computed, ref, watch, watchEffect } from 'vue'
|
|
14
15
|
import { PromiseUtil } from '@neon.id/utils/promise'
|
|
15
16
|
import {
|
|
16
17
|
AttendanceModel,
|
|
@@ -18,9 +19,11 @@ import {
|
|
|
18
19
|
type Schema,
|
|
19
20
|
} from '@neutron.co.id/personalia-models'
|
|
20
21
|
import { DateUtil } from '../../../common/utils/util.date'
|
|
21
|
-
import { NeonTime, useOperasional } from '../../../common'
|
|
22
|
+
import { NeonTime, useOperasional, apiUrl } from '../../../common'
|
|
22
23
|
import { AttendanceNoteTab } from './sections'
|
|
23
24
|
import { useClientHandle } from '@urql/vue'
|
|
25
|
+
import { ofetch } from 'ofetch'
|
|
26
|
+
import { useAuthStore } from '@neon.id/identitas-interfaces'
|
|
24
27
|
|
|
25
28
|
const {
|
|
26
29
|
fields,
|
|
@@ -38,6 +41,14 @@ const {
|
|
|
38
41
|
executeOne,
|
|
39
42
|
} = useSingle<Schema.Attendance, TPersonaliaAttendanceModel>()
|
|
40
43
|
|
|
44
|
+
const appStore = useAppStore()
|
|
45
|
+
|
|
46
|
+
const officeAppUrl = computed(() => {
|
|
47
|
+
const url = apiUrl()
|
|
48
|
+
return url.action
|
|
49
|
+
// return 'http://127.0.0.1:7020'
|
|
50
|
+
})
|
|
51
|
+
|
|
41
52
|
const key = ref(0)
|
|
42
53
|
const responseState = ref()
|
|
43
54
|
const toast = useToastStore()
|
|
@@ -156,6 +167,10 @@ function getNotified() {
|
|
|
156
167
|
}
|
|
157
168
|
|
|
158
169
|
async function generateAttendance() {
|
|
170
|
+
// console.log('show', showLeaveQuota.value)
|
|
171
|
+
// console.log('initial values', initialValues.value)
|
|
172
|
+
// console.log('values', values.value)
|
|
173
|
+
// console.log('leaveStffId', leaveStaffId.value)
|
|
159
174
|
const responseGenerateAttendance = await client
|
|
160
175
|
.mutation(GraphUtil.executeOne(AttendanceModel, {}), {
|
|
161
176
|
action: 'generateAttendance',
|
|
@@ -164,7 +179,7 @@ async function generateAttendance() {
|
|
|
164
179
|
// Attendance input.
|
|
165
180
|
status: values.value.status,
|
|
166
181
|
submitStaffId: values.value.submitStaffId,
|
|
167
|
-
|
|
182
|
+
typeId: values.value.type?.id,
|
|
168
183
|
decideStaffId: values.value.decideStaffId,
|
|
169
184
|
delegateStaffIds: values.value.delegateStaffIds,
|
|
170
185
|
monitoringStaffIds: values.value.monitoringStaffIds,
|
|
@@ -173,6 +188,9 @@ async function generateAttendance() {
|
|
|
173
188
|
startedAt: values.value.startedAt,
|
|
174
189
|
endedAt: values.value.endedAt,
|
|
175
190
|
delegateNotes: values.value.delegateNotes,
|
|
191
|
+
leaveQuota: quotaTaken.value,
|
|
192
|
+
isQuota: showLeaveQuota.value,
|
|
193
|
+
leaveStaffId: leaveStaffId.value,
|
|
176
194
|
},
|
|
177
195
|
})
|
|
178
196
|
.toPromise()
|
|
@@ -180,6 +198,94 @@ async function generateAttendance() {
|
|
|
180
198
|
const wrapper = responseGenerateAttendance.data?.executeAttendance
|
|
181
199
|
responseState.value = wrapper?.info?.state
|
|
182
200
|
}
|
|
201
|
+
const type = ref('')
|
|
202
|
+
const showLeaveQuota = ref(true)
|
|
203
|
+
const authStore = useAuthStore()
|
|
204
|
+
const createdBy = authStore.userId
|
|
205
|
+
const quota = ref(0)
|
|
206
|
+
const maxDuration = ref(0)
|
|
207
|
+
const quotaTaken = ref(0)
|
|
208
|
+
const leaveStaffId = ref('')
|
|
209
|
+
|
|
210
|
+
function checkDurationLeave() {
|
|
211
|
+
if (!values.value.startedAt || !values.value.endedAt) {
|
|
212
|
+
return true
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
const startedAt = new Date(values.value.startedAt)
|
|
216
|
+
const endedAt = new Date(values.value.endedAt)
|
|
217
|
+
|
|
218
|
+
const durationMilliseconds = endedAt.getTime() - startedAt.getTime()
|
|
219
|
+
|
|
220
|
+
const days = Math.floor(durationMilliseconds / (1000 * 60 * 60 * 24)) + 1
|
|
221
|
+
quotaTaken.value = days
|
|
222
|
+
|
|
223
|
+
if (days > maxDuration.value) return false
|
|
224
|
+
|
|
225
|
+
return true
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
watch(
|
|
229
|
+
() => values.value,
|
|
230
|
+
async (newType) => {
|
|
231
|
+
if (values.value.attendanceTypeId) {
|
|
232
|
+
checkDurationLeave()
|
|
233
|
+
const response = await ofetch(`${officeAppUrl.value}/getAttendanceType`, {
|
|
234
|
+
method: 'POST',
|
|
235
|
+
headers: {
|
|
236
|
+
'X-Neon-Key': 'CH7JLKT6MW',
|
|
237
|
+
},
|
|
238
|
+
body: {
|
|
239
|
+
id: values.value.attendanceTypeId,
|
|
240
|
+
},
|
|
241
|
+
})
|
|
242
|
+
type.value = response.data[0].code
|
|
243
|
+
showLeaveQuota.value = response.data[0].showLeaveQuota
|
|
244
|
+
// quota.value = response.data[0].leaveQuota
|
|
245
|
+
maxDuration.value = response.data[0].maxDurationDays
|
|
246
|
+
}
|
|
247
|
+
},
|
|
248
|
+
{ immediate: true },
|
|
249
|
+
)
|
|
250
|
+
|
|
251
|
+
const isLeaveStaff = ref(false)
|
|
252
|
+
|
|
253
|
+
watch(
|
|
254
|
+
() => [values.value.startedAt, values.value.endedAt],
|
|
255
|
+
async (newType) => {
|
|
256
|
+
if (values.value.startedAt && values.value.endedAt) {
|
|
257
|
+
const leaveStaff = await ofetch(`${officeAppUrl.value}/getLeaveQuota`, {
|
|
258
|
+
method: 'POST',
|
|
259
|
+
headers: {
|
|
260
|
+
'X-Neon-Key': 'CH7JLKT6MW',
|
|
261
|
+
},
|
|
262
|
+
body: {
|
|
263
|
+
id: values.value.attendanceTypeId,
|
|
264
|
+
staffId: staffId,
|
|
265
|
+
startedAt: values.value.startedAt,
|
|
266
|
+
endedAt: values.value.endedAt,
|
|
267
|
+
},
|
|
268
|
+
})
|
|
269
|
+
|
|
270
|
+
if (leaveStaff.code !== 200) {
|
|
271
|
+
quota.value = 0
|
|
272
|
+
isLeaveStaff.value = false
|
|
273
|
+
return
|
|
274
|
+
}
|
|
275
|
+
// console.log('leaveStaff', leaveStaff)
|
|
276
|
+
|
|
277
|
+
quota.value = leaveStaff.data.quota
|
|
278
|
+
maxDuration.value = leaveStaff.data.quota
|
|
279
|
+
leaveStaffId.value = leaveStaff.data.leaveStaff.id
|
|
280
|
+
|
|
281
|
+
if (leaveStaff?.code === 200 && leaveStaff?.data?.quota > 0) {
|
|
282
|
+
isLeaveStaff.value = true
|
|
283
|
+
} else {
|
|
284
|
+
isLeaveStaff.value = false
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
},
|
|
288
|
+
)
|
|
183
289
|
|
|
184
290
|
async function generate() {
|
|
185
291
|
await generateAttendance()
|
|
@@ -187,6 +293,24 @@ async function generate() {
|
|
|
187
293
|
await syncOne()
|
|
188
294
|
}
|
|
189
295
|
|
|
296
|
+
const showDurationAlert = ref(false)
|
|
297
|
+
async function saveData() {
|
|
298
|
+
const result = await checkDurationLeave()
|
|
299
|
+
// console.log('showLeaveQuota', showLeaveQuota.value)
|
|
300
|
+
|
|
301
|
+
if (
|
|
302
|
+
(result === true && isLeaveStaff.value === true) ||
|
|
303
|
+
showLeaveQuota.value === false
|
|
304
|
+
) {
|
|
305
|
+
showDurationAlert.value = false
|
|
306
|
+
console.log('save')
|
|
307
|
+
await saveOne()
|
|
308
|
+
} else {
|
|
309
|
+
showDurationAlert.value = true
|
|
310
|
+
console.log('error')
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
|
|
190
314
|
//copy link for catatan
|
|
191
315
|
const copy = ref({
|
|
192
316
|
copyDelegate: `${window.location.origin}/penugasan/staff-attendances/?peek=neu:personalia:attendance:${id.value}:single-staff-view:s`,
|
|
@@ -204,8 +328,15 @@ const copy = ref({
|
|
|
204
328
|
:is-changed="isChanged"
|
|
205
329
|
use-unsaved
|
|
206
330
|
@cancel="discardChanges"
|
|
207
|
-
@submit="
|
|
331
|
+
@submit="saveData"
|
|
208
332
|
>
|
|
333
|
+
<NeonStat
|
|
334
|
+
v-if="showLeaveQuota"
|
|
335
|
+
class="w-36 mb-2"
|
|
336
|
+
label="Cuti Pribadi"
|
|
337
|
+
icon="person-to-door"
|
|
338
|
+
>{{ quota }} hari</NeonStat
|
|
339
|
+
>
|
|
209
340
|
<NeonAlert
|
|
210
341
|
v-if="conflictAtt == true"
|
|
211
342
|
icon="circle-info"
|
|
@@ -213,6 +344,13 @@ const copy = ref({
|
|
|
213
344
|
description="Untuk hari ini kamu sudah ada absensi yang diajukan, silahkan cari absensi yang telah diajukan dan ajukan kembali untuk pergantiannya."
|
|
214
345
|
color="#F7CF6D"
|
|
215
346
|
/>
|
|
347
|
+
<NeonAlert
|
|
348
|
+
v-if="showDurationAlert == true"
|
|
349
|
+
icon="circle-info"
|
|
350
|
+
label="Durasi Melebihi Batas!."
|
|
351
|
+
description="Durasi cuti yang diajukan melebihi batas maksimum yang telah ditentukan. Mohon sesuaikan kembali permohonan cuti sesuai dengan ketentuan yang berlaku"
|
|
352
|
+
color="#F7CF6D"
|
|
353
|
+
/>
|
|
216
354
|
<div v-if="!isNew && conflictAtt == false" class="flex flex-wrap">
|
|
217
355
|
<div class="mt-2">
|
|
218
356
|
<NeonField>
|
|
@@ -275,7 +413,6 @@ const copy = ref({
|
|
|
275
413
|
"
|
|
276
414
|
@update:model-value="onStartedAtUpdate"
|
|
277
415
|
/>
|
|
278
|
-
|
|
279
416
|
<OfficeRelation
|
|
280
417
|
v-model="values"
|
|
281
418
|
:field="fields.type"
|
|
@@ -284,6 +421,13 @@ const copy = ref({
|
|
|
284
421
|
values.status == 'approved' ||
|
|
285
422
|
values.status == 'rejected'
|
|
286
423
|
"
|
|
424
|
+
:query="
|
|
425
|
+
Query.define({
|
|
426
|
+
filter: {
|
|
427
|
+
showAttendanceType: true,
|
|
428
|
+
},
|
|
429
|
+
})
|
|
430
|
+
"
|
|
287
431
|
/>
|
|
288
432
|
|
|
289
433
|
<OfficeRelation
|
|
@@ -301,10 +445,10 @@ const copy = ref({
|
|
|
301
445
|
<NeonFields class="flex-1"> -->
|
|
302
446
|
<OfficeRelation
|
|
303
447
|
v-if="
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
448
|
+
type == 'cuti' ||
|
|
449
|
+
type == 'dayOff' ||
|
|
450
|
+
type == 'sakit' ||
|
|
451
|
+
type == 'izin'
|
|
308
452
|
"
|
|
309
453
|
v-model="values"
|
|
310
454
|
:field="fields.delegateStaffs"
|
|
@@ -314,15 +458,16 @@ const copy = ref({
|
|
|
314
458
|
values.status == 'rejected'
|
|
315
459
|
"
|
|
316
460
|
/>
|
|
461
|
+
<NeonField v-model="values.image" v-bind="fields.image" />
|
|
317
462
|
<!-- </NeonFields>
|
|
318
463
|
</div> -->
|
|
319
464
|
<!-- <div class="ml-2 flex items-end pb-1">
|
|
320
465
|
<NeonCopy
|
|
321
466
|
v-if="
|
|
322
|
-
values.type
|
|
323
|
-
values.type
|
|
324
|
-
values.type
|
|
325
|
-
values.type
|
|
467
|
+
values.type == 'leave' ||
|
|
468
|
+
values.type == 'dayOff' ||
|
|
469
|
+
values.type == 'sick' ||
|
|
470
|
+
values.type == 'permission' ||
|
|
326
471
|
values.isNotes == true
|
|
327
472
|
"
|
|
328
473
|
:size="'sm'"
|
|
@@ -332,10 +477,10 @@ const copy = ref({
|
|
|
332
477
|
</div> -->
|
|
333
478
|
<!-- <NeonField
|
|
334
479
|
v-if="
|
|
335
|
-
values.type
|
|
336
|
-
values.type
|
|
337
|
-
values.type
|
|
338
|
-
values.type
|
|
480
|
+
values.type == 'leave' ||
|
|
481
|
+
values.type == 'dayOff' ||
|
|
482
|
+
values.type == 'sick' ||
|
|
483
|
+
values.type == 'permission'
|
|
339
484
|
"
|
|
340
485
|
v-model="values.isNotes"
|
|
341
486
|
v-bind="fields.isNotes"
|
|
@@ -348,10 +493,10 @@ const copy = ref({
|
|
|
348
493
|
<!-- <template #input>
|
|
349
494
|
<NeonCheck
|
|
350
495
|
v-if="
|
|
351
|
-
values.type
|
|
352
|
-
values.type
|
|
353
|
-
values.type
|
|
354
|
-
values.type
|
|
496
|
+
values.type == 'leave' ||
|
|
497
|
+
values.type == 'dayOff' ||
|
|
498
|
+
values.type == 'sick' ||
|
|
499
|
+
values.type == 'permission'
|
|
355
500
|
"
|
|
356
501
|
v-model="values.isNotes"
|
|
357
502
|
label="Catatan"
|
|
@@ -360,7 +505,6 @@ const copy = ref({
|
|
|
360
505
|
/>
|
|
361
506
|
</template> -->
|
|
362
507
|
<!-- </NeonField> -->
|
|
363
|
-
|
|
364
508
|
<NeonField
|
|
365
509
|
v-if="isNew || isReady"
|
|
366
510
|
v-model="values.notes"
|
|
@@ -368,35 +512,33 @@ const copy = ref({
|
|
|
368
512
|
/>
|
|
369
513
|
<NeonField
|
|
370
514
|
v-if="
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
515
|
+
type == 'cuti' ||
|
|
516
|
+
type == 'dayOff' ||
|
|
517
|
+
type == 'sakit' ||
|
|
518
|
+
type == 'izin'
|
|
375
519
|
"
|
|
376
520
|
v-model="values.delegateNotes"
|
|
377
521
|
v-bind="fields.delegateNotes"
|
|
378
522
|
/>
|
|
379
523
|
|
|
380
|
-
<NeonDivider
|
|
524
|
+
<NeonDivider
|
|
525
|
+
v-if="values.attendanceTypeId"
|
|
526
|
+
is-dashed
|
|
527
|
+
label="Keterangan"
|
|
528
|
+
/>
|
|
381
529
|
|
|
382
530
|
<NeonField
|
|
383
531
|
v-if="
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
532
|
+
type == 'dayOff' ||
|
|
533
|
+
type == 'sakit' ||
|
|
534
|
+
type == 'izin' ||
|
|
535
|
+
type == 'cuti'
|
|
388
536
|
"
|
|
389
537
|
v-model="values.submittedAt"
|
|
390
538
|
v-bind="fields.submittedAt"
|
|
391
539
|
is-disabled
|
|
392
540
|
/>
|
|
393
|
-
<div
|
|
394
|
-
v-if="
|
|
395
|
-
values.type?.code == 'sick' ||
|
|
396
|
-
values.type?.code == 'leave' ||
|
|
397
|
-
values.type?.code == 'permission'
|
|
398
|
-
"
|
|
399
|
-
>
|
|
541
|
+
<div v-if="type == 'sakit' || type == 'cuti' || type == 'izin'">
|
|
400
542
|
<NeonDivider
|
|
401
543
|
is-dashed
|
|
402
544
|
label="Tanggal ini digunakan hanya untuk Generate Absensi"
|
|
@@ -435,7 +577,7 @@ const copy = ref({
|
|
|
435
577
|
|
|
436
578
|
<!-- EARLY GO HOME -->
|
|
437
579
|
<div
|
|
438
|
-
v-if="
|
|
580
|
+
v-if="type == 'pulangLebihAwal'"
|
|
439
581
|
class="grid gap-2 sm:grid-cols-2"
|
|
440
582
|
>
|
|
441
583
|
<NeonField
|
|
@@ -493,7 +635,7 @@ const copy = ref({
|
|
|
493
635
|
|
|
494
636
|
<!-- COME TOO LATE -->
|
|
495
637
|
<div
|
|
496
|
-
v-if="
|
|
638
|
+
v-if="type == 'datangTerlambat'"
|
|
497
639
|
class="grid gap-2 sm:grid-cols-2"
|
|
498
640
|
>
|
|
499
641
|
<NeonField
|
|
@@ -550,10 +692,7 @@ const copy = ref({
|
|
|
550
692
|
</div>
|
|
551
693
|
|
|
552
694
|
<!-- TIMEOUT -->
|
|
553
|
-
<div
|
|
554
|
-
v-if="values.type?.code == 'timeout'"
|
|
555
|
-
class="grid gap-2 sm:grid-cols-2"
|
|
556
|
-
>
|
|
695
|
+
<div v-if="type == 'timeout'" class="grid gap-2 sm:grid-cols-2">
|
|
557
696
|
<NeonField
|
|
558
697
|
v-model="values.startedAt"
|
|
559
698
|
v-bind="{
|