feat(timesheet-approval): Add menu that contains shift options, approval-only feature
This commit is contained in:
parent
83dd3a4de4
commit
57946dbadd
|
|
@ -12,6 +12,7 @@
|
|||
noTopPadding?: boolean;
|
||||
backgroundColor?: 'bg-secondary' | 'bg-dark';
|
||||
appendContent?: string | number;
|
||||
autoFocus?: boolean;
|
||||
}>();
|
||||
|
||||
defineOptions({
|
||||
|
|
@ -28,6 +29,7 @@
|
|||
v-model="model"
|
||||
v-bind="$attrs"
|
||||
dense
|
||||
:autofocus="autoFocus"
|
||||
borderless
|
||||
color="accent"
|
||||
label-color="white"
|
||||
|
|
@ -89,8 +91,8 @@
|
|||
</template>
|
||||
|
||||
<style scoped>
|
||||
:deep(.q-field--dense.q-field--float .q-field__label) {
|
||||
transform: translate(-17px, -60%) scale(0.75);
|
||||
border-radius: 10px 10px 10px 0px;
|
||||
}
|
||||
:deep(.q-field--dense.q-field--float .q-field__label) {
|
||||
transform: translate(-17px, -60%) scale(0.75);
|
||||
border-radius: 10px 10px 10px 0px;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -0,0 +1,130 @@
|
|||
<script
|
||||
setup
|
||||
lang="ts"
|
||||
>
|
||||
import TargoInput from 'src/modules/shared/components/targo-input.vue';
|
||||
|
||||
import { computed, ref } from 'vue';
|
||||
import type { Shift } from 'src/modules/timesheets/models/shift.models';
|
||||
|
||||
const shift = defineModel<Shift>({ required: true });
|
||||
|
||||
defineEmits<{
|
||||
'clickToggleApproval': [void];
|
||||
'clickDelete': [void];
|
||||
}>();
|
||||
|
||||
const isCommentDialogOpen = ref(false);
|
||||
|
||||
const approvalOptionState = computed<{ icon: string, label: string }>(() => shift.value.is_approved ?
|
||||
{ icon: 'las la-unlock', label: 'shared.label.unlock' } :
|
||||
{ icon: 'las la-lock', label: 'shared.label.lock' }
|
||||
)
|
||||
|
||||
const hasComment = computed(() => shift.value.comment && shift.value.comment.length > 0)
|
||||
|
||||
const onClickViewComments = () => {
|
||||
isCommentDialogOpen.value = true;
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div class="row full-height flex-center">
|
||||
<q-dialog
|
||||
v-model="isCommentDialogOpen"
|
||||
full-width
|
||||
backdrop-filter="blur(4px)"
|
||||
>
|
||||
<div class="row flex-center full-width">
|
||||
<div class="col-xs-12 col-sm-10 col-md-8 col-lg-6">
|
||||
<TargoInput
|
||||
v-model="shift.comment"
|
||||
auto-focus
|
||||
:label="$t('timesheet.expense.employee_comment')"
|
||||
/>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</q-dialog>
|
||||
|
||||
<q-btn
|
||||
flat
|
||||
dense
|
||||
icon="more_vert"
|
||||
color="accent"
|
||||
class="col-auto q-px-md"
|
||||
>
|
||||
<q-badge
|
||||
v-if="hasComment"
|
||||
rounded
|
||||
floating
|
||||
color="negative"
|
||||
style="transform:translate(-10px, 0px)"
|
||||
/>
|
||||
|
||||
<q-menu
|
||||
auto-close
|
||||
transition-show="jump-down"
|
||||
transition-hide="jump-up"
|
||||
transition-duration="200"
|
||||
>
|
||||
|
||||
<q-list dense>
|
||||
<q-item
|
||||
clickable
|
||||
@click="$emit('clickToggleApproval')"
|
||||
>
|
||||
<q-item-section avatar>
|
||||
<q-avatar :icon="approvalOptionState.icon" />
|
||||
</q-item-section>
|
||||
|
||||
<q-item-section>
|
||||
{{ $t(approvalOptionState.label) }}
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
|
||||
<q-item
|
||||
clickable
|
||||
@click="onClickViewComments"
|
||||
>
|
||||
<q-item-section avatar>
|
||||
<q-avatar icon="las la-power-off" />
|
||||
</q-item-section>
|
||||
|
||||
<q-item-section>
|
||||
<div class="row items-center">
|
||||
<span class="col">{{ $t('timesheet.expense.employee_comment') }}</span>
|
||||
|
||||
<div class="col-auto q-pl-sm">
|
||||
<q-badge
|
||||
v-if="hasComment"
|
||||
rounded
|
||||
color="negative"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
|
||||
<q-separator />
|
||||
|
||||
<q-item
|
||||
clickable
|
||||
@click="$emit('clickDelete')"
|
||||
>
|
||||
<q-item-section avatar>
|
||||
<q-avatar
|
||||
icon="las la-trash"
|
||||
text-color="negative"
|
||||
/>
|
||||
</q-item-section>
|
||||
|
||||
<q-item-section>
|
||||
{{ $t('shared.label.remove') }}
|
||||
</q-item-section>
|
||||
</q-item>
|
||||
</q-list>
|
||||
</q-menu>
|
||||
</q-btn>
|
||||
</div>
|
||||
</template>
|
||||
|
|
@ -2,9 +2,11 @@
|
|||
setup
|
||||
lang="ts"
|
||||
>
|
||||
import DetailsDialogShiftMenu from 'src/modules/timesheet-approval/components/details-dialog-shift-menu.vue';
|
||||
|
||||
import { useI18n } from 'vue-i18n';
|
||||
import { computed, inject, onMounted, ref } from 'vue';
|
||||
import { QSelect, QInput, useQuasar, type QSelectProps, QPopupProxy } from 'quasar';
|
||||
import { QSelect, QInput, useQuasar, type QSelectProps } from 'quasar';
|
||||
import { useUiStore } from 'src/stores/ui-store';
|
||||
import { useAuthStore } from 'src/stores/auth-store';
|
||||
import { getCurrentDailyMinutesWorked, getShiftOptions, getTimeStringFromMinutes, SHIFT_OPTIONS } from 'src/modules/timesheets/utils/shift.util';
|
||||
|
|
@ -51,7 +53,6 @@
|
|||
const shiftErrorMessage = ref<string | undefined>();
|
||||
const is_showing_delete_confirm = ref(false);
|
||||
const isShowingPredefinedTime = ref(shift.value.type === 'HOLIDAY');
|
||||
const popupProxyRef = ref<QPopupProxy | null>(null);
|
||||
const predefinedHoursString = ref('');
|
||||
const predefinedHoursBgColor = ref(`bg-${shiftTypeSelected.value?.icon_color ?? ''}`);
|
||||
|
||||
|
|
@ -59,12 +60,6 @@
|
|||
|
||||
const hasPTO = computed(() => currentShifts.some(shift => SHIFT_TYPES_WITH_PREDEFINED_TIMES.includes(shift.type)));
|
||||
|
||||
const rightClickMenuIcon = computed(() => shift.value.is_approved ? 'lock_open' : 'lock');
|
||||
|
||||
const rightClickMenuLabel = computed(() => shift.value.is_approved ?
|
||||
t('timesheet_approvals.tooltip.unapprove') :
|
||||
t('timesheet_approvals.tooltip.approve'));
|
||||
|
||||
const timeInputProps = computed(() => ({
|
||||
dense: true,
|
||||
borderless: shift.value.is_approved && isTimesheetApproved,
|
||||
|
|
@ -136,12 +131,9 @@
|
|||
is_showing_delete_confirm.value = state;
|
||||
}
|
||||
|
||||
const onRightClickApprove = () => {
|
||||
const onclickToogleApproval = () => {
|
||||
if (authStore.user?.user_module_access.includes('timesheets_approval'))
|
||||
shift.value.is_approved = !shift.value.is_approved;
|
||||
|
||||
if (popupProxyRef.value)
|
||||
popupProxyRef.value.hide();
|
||||
}
|
||||
|
||||
const onShiftTypeChange = (option: ShiftOption) => {
|
||||
|
|
@ -179,31 +171,6 @@
|
|||
|
||||
<template>
|
||||
<div class="row">
|
||||
<!-- right-click to approve shift only (if in approval mode) -->
|
||||
<q-popup-proxy
|
||||
v-if="mode === 'approval'"
|
||||
ref="popupProxyRef"
|
||||
context-menu
|
||||
class="rounded-5 q-px-md shadow-24 cursor-pointer"
|
||||
style="border: 3px solid var(--q-primary);"
|
||||
>
|
||||
<q-banner
|
||||
dense
|
||||
class="cursor-pointer q-px-lg"
|
||||
@click="onRightClickApprove"
|
||||
>
|
||||
<template v-slot:avatar>
|
||||
<q-icon
|
||||
:name="rightClickMenuIcon"
|
||||
color="accent"
|
||||
/>
|
||||
</template>
|
||||
<span class="text-weight-bold text-accent text-uppercase">
|
||||
{{ rightClickMenuLabel }}
|
||||
</span>
|
||||
</q-banner>
|
||||
</q-popup-proxy>
|
||||
|
||||
<!-- delete shift confirmation dialog -->
|
||||
<q-dialog
|
||||
v-model="is_showing_delete_confirm"
|
||||
|
|
@ -348,7 +315,10 @@
|
|||
</div>
|
||||
|
||||
<!-- Else show input fields for in-out timestamps -->
|
||||
<div v-else class="col row items-start text-uppercase rounded-5 q-pa-xs">
|
||||
<div
|
||||
v-else
|
||||
class="col row items-start text-uppercase rounded-5 q-pa-xs"
|
||||
>
|
||||
<q-input
|
||||
ref="start_time"
|
||||
v-model="shift.start_time"
|
||||
|
|
@ -384,8 +354,8 @@
|
|||
</div>
|
||||
|
||||
<div
|
||||
class="row full-height"
|
||||
:class="$q.platform.is.mobile ? 'col-12' : 'col-auto flex-center'"
|
||||
v-if="mode === 'normal'"
|
||||
class="row col-auto flex-center full-height"
|
||||
>
|
||||
<!-- comment button -->
|
||||
<q-btn
|
||||
|
|
@ -470,6 +440,17 @@
|
|||
@click="toggleIsShowingDeleteConfirm(true)"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div
|
||||
v-else
|
||||
class="col-auto"
|
||||
>
|
||||
<DetailsDialogShiftMenu
|
||||
v-model="shift"
|
||||
@click-toggle-approval="onclickToogleApproval"
|
||||
@click-delete="toggleIsShowingDeleteConfirm(true)"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user