@neutron.co.id/operasional-interfaces 1.17.11-beta.1 → 1.17.11
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/models/personalia/attendance/AttendanceDelegate.vue +102 -13
- package/build/@office/models/personalia/attendance/AttendanceManager.vue +133 -14
- package/build/@office/models/personalia/attendance/AttendanceSingle/AttendanceSingle.vue +3 -1
- package/build/@office/models/personalia/attendance/AttendanceStaff.vue +171 -44
- package/build/@office/models/personalia/attendance/AttendanceSupervisor.vue +151 -35
- package/build/@office/models/personalia/leaveConflict/LeaveConflictCollection/LeaveConflictCollection.vue +1 -1
- package/build/@office/models/personalia/leaveConflict/LeaveConflictSingle/LeaveConflictSingle.vue +10 -32
- package/build/@office/models/personalia/leaveQuota/LeaveQuotaSingle/LeaveQuotaSingle.vue +27 -3
- package/build/@office/models/personalia/leaveStaff/LeaveStaffSingle/LeaveStaffSingle.vue +10 -31
- 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/mock/index.cjs +1539 -1138
- package/build/mock/index.mjs +1539 -1138
- 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,
|
|
@@ -21,6 +21,7 @@ import { DateUtil } from '../../../common/utils/util.date'
|
|
|
21
21
|
import { NeonTime, useOperasional } from '../../../common'
|
|
22
22
|
import { AttendanceNoteTab } from './sections'
|
|
23
23
|
import { useClientHandle } from '@urql/vue'
|
|
24
|
+
import { ofetch } from 'ofetch'
|
|
24
25
|
|
|
25
26
|
const {
|
|
26
27
|
fields,
|
|
@@ -164,7 +165,7 @@ async function generateAttendance() {
|
|
|
164
165
|
// Attendance input.
|
|
165
166
|
status: values.value.status,
|
|
166
167
|
submitStaffId: values.value.submitStaffId,
|
|
167
|
-
|
|
168
|
+
typeId: values.value.type?.id,
|
|
168
169
|
decideStaffId: values.value.decideStaffId,
|
|
169
170
|
delegateStaffIds: values.value.delegateStaffIds,
|
|
170
171
|
monitoringStaffIds: values.value.monitoringStaffIds,
|
|
@@ -172,6 +173,7 @@ async function generateAttendance() {
|
|
|
172
173
|
submittedAt: values.value.submittedAt,
|
|
173
174
|
startedAt: values.value.startedAt,
|
|
174
175
|
endedAt: values.value.endedAt,
|
|
176
|
+
leaveQuota: quotaTaken.value,
|
|
175
177
|
},
|
|
176
178
|
})
|
|
177
179
|
.toPromise()
|
|
@@ -185,6 +187,86 @@ async function generate() {
|
|
|
185
187
|
await getNotified()
|
|
186
188
|
await syncOne()
|
|
187
189
|
}
|
|
190
|
+
|
|
191
|
+
const appStore = useAppStore()
|
|
192
|
+
const officeAppUrl = computed(() => {
|
|
193
|
+
if (appStore.appEnv === 'dev')
|
|
194
|
+
return 'https://dev.api.office.operasional.neutron.neon.id'
|
|
195
|
+
|
|
196
|
+
if (appStore.appEnv === 'prod')
|
|
197
|
+
return 'https://api.office.operasional.neutron.neon.id'
|
|
198
|
+
|
|
199
|
+
return 'http://127.0.0.1:7020'
|
|
200
|
+
})
|
|
201
|
+
|
|
202
|
+
const type = ref('')
|
|
203
|
+
const showLeaveQuota = ref(true)
|
|
204
|
+
// const authStore = useAuthStore()
|
|
205
|
+
// const createdBy = authStore.userId
|
|
206
|
+
const quota = ref(0)
|
|
207
|
+
const maxDuration = ref(0)
|
|
208
|
+
const quotaTaken = ref(0)
|
|
209
|
+
|
|
210
|
+
function checkDurationLeave() {
|
|
211
|
+
console.log('cek', values.value)
|
|
212
|
+
if (!values.value.startedAt || !values.value.endedAt) {
|
|
213
|
+
return true
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
const startedAt = new Date(values.value.startedAt)
|
|
217
|
+
const endedAt = new Date(values.value.endedAt)
|
|
218
|
+
|
|
219
|
+
const durationMilliseconds = endedAt.getTime() - startedAt.getTime()
|
|
220
|
+
|
|
221
|
+
const days = Math.floor(durationMilliseconds / (1000 * 60 * 60 * 24))
|
|
222
|
+
quotaTaken.value = days
|
|
223
|
+
console.log('days', days, maxDuration.value)
|
|
224
|
+
|
|
225
|
+
if (days > maxDuration.value) return false
|
|
226
|
+
|
|
227
|
+
return true
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
watch(
|
|
231
|
+
() => values.value,
|
|
232
|
+
async (newType) => {
|
|
233
|
+
console.log('new', newType)
|
|
234
|
+
console.log('new val', values.value)
|
|
235
|
+
console.log('type', values.value.type)
|
|
236
|
+
const response = await ofetch(`${officeAppUrl.value}/getAttendanceType`, {
|
|
237
|
+
method: 'POST',
|
|
238
|
+
headers: {
|
|
239
|
+
'X-Neon-Key': 'CH7JLKT6MW',
|
|
240
|
+
},
|
|
241
|
+
body: {
|
|
242
|
+
id: values.value.attendanceTypeId,
|
|
243
|
+
},
|
|
244
|
+
})
|
|
245
|
+
console.log(response)
|
|
246
|
+
type.value = response.data[0].code
|
|
247
|
+
showLeaveQuota.value = response.data[0].showLeaveQuota
|
|
248
|
+
quota.value = response.data[0].leaveQuota
|
|
249
|
+
maxDuration.value = response.data[0].maxDurationDays
|
|
250
|
+
},
|
|
251
|
+
)
|
|
252
|
+
|
|
253
|
+
const isLeaveStaff = ref(false)
|
|
254
|
+
|
|
255
|
+
const showDurationAlert = ref(false)
|
|
256
|
+
async function saveData() {
|
|
257
|
+
const result = await checkDurationLeave()
|
|
258
|
+
|
|
259
|
+
console.log('dur', result)
|
|
260
|
+
|
|
261
|
+
if (result == true && isLeaveStaff.value == true) {
|
|
262
|
+
showDurationAlert.value = false
|
|
263
|
+
console.log('save')
|
|
264
|
+
await saveOne()
|
|
265
|
+
} else {
|
|
266
|
+
showDurationAlert.value = true
|
|
267
|
+
console.log('error')
|
|
268
|
+
}
|
|
269
|
+
}
|
|
188
270
|
</script>
|
|
189
271
|
|
|
190
272
|
<template>
|
|
@@ -198,14 +280,21 @@ async function generate() {
|
|
|
198
280
|
:is-changed="isChanged"
|
|
199
281
|
use-unsaved
|
|
200
282
|
@cancel="discardChanges"
|
|
201
|
-
@submit="
|
|
283
|
+
@submit="saveData"
|
|
202
284
|
>
|
|
285
|
+
<NeonAlert
|
|
286
|
+
v-if="showDurationAlert == true"
|
|
287
|
+
icon="circle-info"
|
|
288
|
+
label="Durasi Melebihi Batas!."
|
|
289
|
+
description="Durasi cuti yang diajukan melebihi batas maksimum yang telah ditentukan. Mohon sesuaikan kembali permohonan cuti sesuai dengan ketentuan yang berlaku"
|
|
290
|
+
color="#F7CF6D"
|
|
291
|
+
/>
|
|
203
292
|
<OfficeRelation
|
|
204
293
|
v-if="
|
|
205
|
-
values.type?.code == '
|
|
294
|
+
values.type?.code == 'cuti' ||
|
|
206
295
|
values.type?.code == 'dayOff' ||
|
|
207
296
|
values.type?.code == 'sick' ||
|
|
208
|
-
values.type?.code == '
|
|
297
|
+
values.type?.code == 'izin'
|
|
209
298
|
"
|
|
210
299
|
v-model="values"
|
|
211
300
|
:field="fields.delegateStaffs"
|
|
@@ -251,10 +340,10 @@ async function generate() {
|
|
|
251
340
|
/>
|
|
252
341
|
<!-- <OfficeRelation
|
|
253
342
|
v-if="
|
|
254
|
-
values.type
|
|
255
|
-
values.type
|
|
256
|
-
values.type
|
|
257
|
-
values.type
|
|
343
|
+
values.type == 'leave' ||
|
|
344
|
+
values.type == 'sick' ||
|
|
345
|
+
values.type == 'dayOff' ||
|
|
346
|
+
values.type == 'permission'
|
|
258
347
|
"
|
|
259
348
|
v-model="values"
|
|
260
349
|
:field="fields.monitoringStaffs"
|
|
@@ -264,10 +353,10 @@ async function generate() {
|
|
|
264
353
|
/> -->
|
|
265
354
|
<NeonField
|
|
266
355
|
v-if="
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
356
|
+
type == 'cuti' ||
|
|
357
|
+
type == 'dayOff' ||
|
|
358
|
+
type == 'sick' ||
|
|
359
|
+
type == 'izin'
|
|
271
360
|
"
|
|
272
361
|
v-model="values.delegateNotes"
|
|
273
362
|
v-bind="fields.delegateNotes"
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
|
-
import { NeonSingle, useSingle } from '@neon.id/context'
|
|
2
|
+
import { NeonSingle, useSingle, useAppStore } from '@neon.id/context'
|
|
3
3
|
import { NeonField, NeonForm } from '@neon.id/form'
|
|
4
4
|
import { NeonButton, NeonDivider } from '@neon.id/interfaces'
|
|
5
5
|
import { OfficeRelation, OfficeTab, OfficeTabs } from '@neon.id/office'
|
|
@@ -11,6 +11,7 @@ import type {
|
|
|
11
11
|
} from '@neutron.co.id/personalia-models'
|
|
12
12
|
import { DateUtil } from '../../..//common/utils/util.date'
|
|
13
13
|
import { useOperasional, NeonTime } from '../../../common'
|
|
14
|
+
import { ofetch } from 'ofetch'
|
|
14
15
|
|
|
15
16
|
const {
|
|
16
17
|
fields,
|
|
@@ -108,6 +109,108 @@ const rejectedAbsensi = async () => {
|
|
|
108
109
|
await executeOne('rejectedAttendance', { attendanceId: id.value })
|
|
109
110
|
await syncOne()
|
|
110
111
|
}
|
|
112
|
+
|
|
113
|
+
const appStore = useAppStore()
|
|
114
|
+
const officeAppUrl = computed(() => {
|
|
115
|
+
if (appStore.appEnv === 'dev')
|
|
116
|
+
return 'https://dev.api.office.operasional.neutron.neon.id'
|
|
117
|
+
|
|
118
|
+
if (appStore.appEnv === 'prod')
|
|
119
|
+
return 'https://api.office.operasional.neutron.neon.id'
|
|
120
|
+
|
|
121
|
+
return 'http://127.0.0.1:7020'
|
|
122
|
+
})
|
|
123
|
+
|
|
124
|
+
const type = ref('')
|
|
125
|
+
const showLeaveQuota = ref(true)
|
|
126
|
+
const quota = ref(0)
|
|
127
|
+
const maxDuration = ref(0)
|
|
128
|
+
const quotaTaken = ref(0)
|
|
129
|
+
|
|
130
|
+
function checkDurationLeave() {
|
|
131
|
+
if (!values.value.startedAt || !values.value.endedAt) {
|
|
132
|
+
return true
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
const startedAt = new Date(values.value.startedAt)
|
|
136
|
+
const endedAt = new Date(values.value.endedAt)
|
|
137
|
+
|
|
138
|
+
const durationMilliseconds = endedAt.getTime() - startedAt.getTime()
|
|
139
|
+
|
|
140
|
+
const days = Math.floor(durationMilliseconds / (1000 * 60 * 60 * 24)) + 1
|
|
141
|
+
quotaTaken.value = days
|
|
142
|
+
|
|
143
|
+
if (days > maxDuration.value) return false
|
|
144
|
+
|
|
145
|
+
return true
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
watch(
|
|
149
|
+
() => values.value,
|
|
150
|
+
async (newType) => {
|
|
151
|
+
checkDurationLeave()
|
|
152
|
+
const response = await ofetch(`${officeAppUrl.value}/getAttendanceType`, {
|
|
153
|
+
method: 'POST',
|
|
154
|
+
headers: {
|
|
155
|
+
'X-Neon-Key': 'CH7JLKT6MW',
|
|
156
|
+
},
|
|
157
|
+
body: {
|
|
158
|
+
id: values.value.attendanceTypeId,
|
|
159
|
+
},
|
|
160
|
+
})
|
|
161
|
+
type.value = response.data[0].code
|
|
162
|
+
showLeaveQuota.value = response.data[0].showLeaveQuota
|
|
163
|
+
quota.value = response.data[0].leaveQuota
|
|
164
|
+
maxDuration.value = response.data[0].maxDurationDays
|
|
165
|
+
},
|
|
166
|
+
)
|
|
167
|
+
|
|
168
|
+
const isLeaveStaff = ref(false)
|
|
169
|
+
|
|
170
|
+
watch(
|
|
171
|
+
() => [values.value.startedAt, values.value.endedAt],
|
|
172
|
+
async (newType) => {
|
|
173
|
+
if (values.value.startedAt && values.value.endedAt) {
|
|
174
|
+
const leaveStaff = await ofetch(`${officeAppUrl.value}/getLeaveQuota`, {
|
|
175
|
+
method: 'POST',
|
|
176
|
+
headers: {
|
|
177
|
+
'X-Neon-Key': 'CH7JLKT6MW',
|
|
178
|
+
},
|
|
179
|
+
body: {
|
|
180
|
+
id: values.value.attendanceTypeId,
|
|
181
|
+
staffId: initialValues.value.submitStaffId,
|
|
182
|
+
startedAt: values.value.startedAt,
|
|
183
|
+
endedAt: values.value.endedAt,
|
|
184
|
+
},
|
|
185
|
+
})
|
|
186
|
+
|
|
187
|
+
if (leaveStaff.code === 200 && leaveStaff.data.quota > 0) {
|
|
188
|
+
isLeaveStaff.value = true
|
|
189
|
+
quota.value = leaveStaff.data.quota
|
|
190
|
+
maxDuration.value = leaveStaff.data.quota
|
|
191
|
+
} else {
|
|
192
|
+
isLeaveStaff.value = false
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
},
|
|
196
|
+
)
|
|
197
|
+
|
|
198
|
+
const showDurationAlert = ref(false)
|
|
199
|
+
async function saveData() {
|
|
200
|
+
const result = await checkDurationLeave()
|
|
201
|
+
|
|
202
|
+
if (
|
|
203
|
+
(result === true && isLeaveStaff.value === true) ||
|
|
204
|
+
(type.value !== 'cuti' && type.value !== 'izin' && type.value !== 'sakit')
|
|
205
|
+
) {
|
|
206
|
+
showDurationAlert.value = false
|
|
207
|
+
console.log('save')
|
|
208
|
+
await saveOne()
|
|
209
|
+
} else {
|
|
210
|
+
showDurationAlert.value = true
|
|
211
|
+
console.log('error')
|
|
212
|
+
}
|
|
213
|
+
}
|
|
111
214
|
</script>
|
|
112
215
|
|
|
113
216
|
<template>
|
|
@@ -121,8 +224,22 @@ const rejectedAbsensi = async () => {
|
|
|
121
224
|
:is-changed="isChanged"
|
|
122
225
|
use-unsaved
|
|
123
226
|
@cancel="discardChanges"
|
|
124
|
-
@submit="
|
|
227
|
+
@submit="saveData"
|
|
125
228
|
>
|
|
229
|
+
<NeonStat
|
|
230
|
+
v-if="showLeaveQuota"
|
|
231
|
+
class="w-36 mb-2"
|
|
232
|
+
label="Cuti Pribadi"
|
|
233
|
+
icon="person-to-door"
|
|
234
|
+
>{{ quota }} hari</NeonStat
|
|
235
|
+
>
|
|
236
|
+
<NeonAlert
|
|
237
|
+
v-if="showDurationAlert == true"
|
|
238
|
+
icon="circle-info"
|
|
239
|
+
label="Durasi Melebihi Batas!."
|
|
240
|
+
description="Durasi cuti yang diajukan melebihi batas maksimum yang telah ditentukan. Mohon sesuaikan kembali permohonan cuti sesuai dengan ketentuan yang berlaku"
|
|
241
|
+
color="#F7CF6D"
|
|
242
|
+
/>
|
|
126
243
|
<div class="flex flex-wrap">
|
|
127
244
|
<div class="mt-2">
|
|
128
245
|
<NeonField>
|
|
@@ -197,13 +314,14 @@ const rejectedAbsensi = async () => {
|
|
|
197
314
|
/>
|
|
198
315
|
|
|
199
316
|
<OfficeRelation
|
|
200
|
-
v-if="
|
|
317
|
+
v-if="type === 'cuti'"
|
|
201
318
|
v-model="values"
|
|
202
319
|
:field="fields.delegateStaffs"
|
|
203
320
|
:is-disabled="
|
|
204
321
|
values.status == 'approved' || values.status == 'rejected'
|
|
205
322
|
"
|
|
206
323
|
/>
|
|
324
|
+
<NeonField v-model="values.image" v-bind="fields.image" />
|
|
207
325
|
|
|
208
326
|
<NeonField
|
|
209
327
|
v-if="isNew || isReady"
|
|
@@ -211,14 +329,18 @@ const rejectedAbsensi = async () => {
|
|
|
211
329
|
v-bind="fields.notes"
|
|
212
330
|
/>
|
|
213
331
|
|
|
214
|
-
<NeonDivider
|
|
332
|
+
<NeonDivider
|
|
333
|
+
v-if="values.attendanceTypeId"
|
|
334
|
+
is-dashed
|
|
335
|
+
label="Keterangan"
|
|
336
|
+
/>
|
|
215
337
|
|
|
216
338
|
<NeonField
|
|
217
339
|
v-if="
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
340
|
+
type == 'cuti' ||
|
|
341
|
+
type == 'dayOff' ||
|
|
342
|
+
type == 'sick' ||
|
|
343
|
+
type == 'izin'
|
|
222
344
|
"
|
|
223
345
|
v-model="values.submittedAt"
|
|
224
346
|
v-bind="fields.submittedAt"
|
|
@@ -227,7 +349,7 @@ const rejectedAbsensi = async () => {
|
|
|
227
349
|
|
|
228
350
|
<!-- EARLY GO HOME -->
|
|
229
351
|
<div
|
|
230
|
-
v-if="
|
|
352
|
+
v-if="type == 'pulangLebihAwal'"
|
|
231
353
|
class="grid gap-2 sm:grid-cols-2"
|
|
232
354
|
>
|
|
233
355
|
<NeonField
|
|
@@ -275,7 +397,7 @@ const rejectedAbsensi = async () => {
|
|
|
275
397
|
|
|
276
398
|
<!-- COME TOO LATE -->
|
|
277
399
|
<div
|
|
278
|
-
v-if="
|
|
400
|
+
v-if="type == 'datangTerlambat'"
|
|
279
401
|
class="grid gap-2 sm:grid-cols-2"
|
|
280
402
|
>
|
|
281
403
|
<NeonField
|
|
@@ -322,10 +444,7 @@ const rejectedAbsensi = async () => {
|
|
|
322
444
|
</div>
|
|
323
445
|
|
|
324
446
|
<!-- TIMEOUT -->
|
|
325
|
-
<div
|
|
326
|
-
v-if="values.type?.code == 'timeout'"
|
|
327
|
-
class="grid gap-2 sm:grid-cols-2"
|
|
328
|
-
>
|
|
447
|
+
<div v-if="type == 'timeout'" class="grid gap-2 sm:grid-cols-2">
|
|
329
448
|
<NeonField
|
|
330
449
|
v-model="values.startedAt"
|
|
331
450
|
v-bind="{
|
|
@@ -30,6 +30,8 @@ const diff = computed(() => {
|
|
|
30
30
|
return DateUtil.day(values.value.endedAt).diff(values.value.startedAt)
|
|
31
31
|
})
|
|
32
32
|
|
|
33
|
+
console.log('single', values.value)
|
|
34
|
+
|
|
33
35
|
const duration = computed(() => {
|
|
34
36
|
if (isNaN(diff.value)) return '-'
|
|
35
37
|
const duration = DateUtil.day.duration(diff.value)
|
|
@@ -91,7 +93,7 @@ function onStartedAtUpdate(date: any) {
|
|
|
91
93
|
@update:model-value="onStartedAtUpdate"
|
|
92
94
|
/>
|
|
93
95
|
|
|
94
|
-
<OfficeRelation v-model="values" :field="fields.type" />
|
|
96
|
+
<OfficeRelation v-model="values.type" :field="fields.type" />
|
|
95
97
|
|
|
96
98
|
<OfficeRelation v-model="values" :field="fields.decideStaff" />
|
|
97
99
|
|