refactor(timesheet): Implement refactor of select and input fields from freeswitch-ui branch
This commit is contained in:
parent
1271d1eb61
commit
4ab271e66f
77
src/modules/shared/components/targo-input.vue
Normal file
77
src/modules/shared/components/targo-input.vue
Normal file
|
|
@ -0,0 +1,77 @@
|
||||||
|
<script
|
||||||
|
setup
|
||||||
|
lang="ts"
|
||||||
|
>
|
||||||
|
const model = defineModel<string | number | null | undefined>({ required: true });
|
||||||
|
const is_date_picker_open = defineModel<boolean>('isDatePickerOpen', {default: false});
|
||||||
|
|
||||||
|
defineProps<{
|
||||||
|
label?: string | undefined;
|
||||||
|
requiresDatePicker?: boolean | undefined;
|
||||||
|
maxLength?: number;
|
||||||
|
noTopPadding?: boolean;
|
||||||
|
backgroundColor?: 'bg-secondary' | 'bg-dark';
|
||||||
|
}>();
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div
|
||||||
|
class="col q-px-sm"
|
||||||
|
:class="noTopPadding ? '' : 'q-pt-md'"
|
||||||
|
>
|
||||||
|
<q-input
|
||||||
|
v-model="model"
|
||||||
|
dense
|
||||||
|
borderless
|
||||||
|
color="accent"
|
||||||
|
label-color="white"
|
||||||
|
stack-label
|
||||||
|
label-slot
|
||||||
|
no-error-icon
|
||||||
|
hide-bottom-space
|
||||||
|
:maxlength="maxLength"
|
||||||
|
class="q-px-md rounded-5 inset-shadow"
|
||||||
|
:class="$q.dark.isActive ? 'bg-primary' : (backgroundColor ?? 'bg-secondary')"
|
||||||
|
:style="`border: 1px solid var(${$q.dark.isActive ? '--q-secondary' : '--q-primary'});`"
|
||||||
|
>
|
||||||
|
<template #label>
|
||||||
|
<span
|
||||||
|
class="text-weight-bold text-uppercase q-px-md"
|
||||||
|
:class="$q.dark.isActive ? 'bg-secondary' : 'bg-primary'"
|
||||||
|
>
|
||||||
|
{{ label }}
|
||||||
|
</span>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<template #append v-if="requiresDatePicker">
|
||||||
|
<q-btn
|
||||||
|
flat
|
||||||
|
dense
|
||||||
|
size="lg"
|
||||||
|
icon="calendar_month"
|
||||||
|
color="accent"
|
||||||
|
@click="is_date_picker_open = true"
|
||||||
|
>
|
||||||
|
<q-dialog
|
||||||
|
v-model="is_date_picker_open"
|
||||||
|
backdrop-filter="none"
|
||||||
|
>
|
||||||
|
<q-date
|
||||||
|
v-model="model"
|
||||||
|
mask="YYYY-MM-DD"
|
||||||
|
color="accent"
|
||||||
|
@update:model-value="is_date_picker_open = false"
|
||||||
|
/>
|
||||||
|
</q-dialog>
|
||||||
|
</q-btn>
|
||||||
|
</template>
|
||||||
|
</q-input>
|
||||||
|
</div>
|
||||||
|
</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;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
54
src/modules/shared/components/targo-select.vue
Normal file
54
src/modules/shared/components/targo-select.vue
Normal file
|
|
@ -0,0 +1,54 @@
|
||||||
|
<script
|
||||||
|
setup
|
||||||
|
lang="ts"
|
||||||
|
>
|
||||||
|
const model = defineModel<string>({ required: true });
|
||||||
|
|
||||||
|
defineProps<{
|
||||||
|
label?: string | undefined;
|
||||||
|
options: string[];
|
||||||
|
}>();
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div class="col q-px-sm q-pt-md">
|
||||||
|
<q-select
|
||||||
|
v-model="model"
|
||||||
|
dense
|
||||||
|
borderless
|
||||||
|
color="accent"
|
||||||
|
label-color="white"
|
||||||
|
stack-label
|
||||||
|
label-slot
|
||||||
|
:options="options"
|
||||||
|
lazy-rules
|
||||||
|
no-error-icon
|
||||||
|
hide-bottom-space
|
||||||
|
options-selected-class="text-white text-bold bg-accent"
|
||||||
|
class="q-px-md rounded-5 inset-shadow"
|
||||||
|
:class="$q.dark.isActive ? 'bg-primary' : 'bg-secondary'"
|
||||||
|
popup-content-class="text-uppercase text-weight-medium rounded-5 shadow-12 z-top"
|
||||||
|
popup-content-style="border: 1px solid var(--q-primary)"
|
||||||
|
menu-anchor="bottom middle"
|
||||||
|
menu-self="top middle"
|
||||||
|
:menu-offset="[0, 5]"
|
||||||
|
:style="`border: 1px solid var(${$q.dark.isActive ? '--q-secondary' : '--q-primary'});`"
|
||||||
|
>
|
||||||
|
<template #label>
|
||||||
|
<span
|
||||||
|
class="text-weight-medium text-uppercase q-px-sm no-pointer-events"
|
||||||
|
:class="$q.dark.isActive ? 'bg-secondary' : 'bg-primary'"
|
||||||
|
>
|
||||||
|
{{ label }}
|
||||||
|
</span>
|
||||||
|
</template>
|
||||||
|
</q-select>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
:deep(.q-field--dense.q-field--float .q-field__label) {
|
||||||
|
transform: translate(-17px, -60%) scale(0.75) !important;
|
||||||
|
border-radius: 10px 10px 10px 0px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
@ -2,6 +2,8 @@
|
||||||
setup
|
setup
|
||||||
lang="ts"
|
lang="ts"
|
||||||
>
|
>
|
||||||
|
import TargoInput from 'src/modules/shared/components/targo-input.vue';
|
||||||
|
|
||||||
import { useI18n } from 'vue-i18n';
|
import { useI18n } from 'vue-i18n';
|
||||||
import { computed, onMounted, ref } from 'vue';
|
import { computed, onMounted, ref } from 'vue';
|
||||||
import { useUiStore } from 'src/stores/ui-store';
|
import { useUiStore } from 'src/stores/ui-store';
|
||||||
|
|
@ -90,79 +92,76 @@
|
||||||
@submit.prevent="requestExpenseCreationOrUpdate"
|
@submit.prevent="requestExpenseCreationOrUpdate"
|
||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class="row justify-between items-start rounded-5 q-pb-sm"
|
class="row justify-between rounded-5 q-pb-sm"
|
||||||
:class="expenseStore.mode === 'create' ? 'q-px-lg' : ''"
|
:class="expenseStore.mode === 'create' ? 'q-px-lg' : ''"
|
||||||
>
|
>
|
||||||
<!-- date selection input -->
|
<!-- date selection input -->
|
||||||
<div class="col q-px-xs">
|
<div class="row col items-center">
|
||||||
<q-input
|
<q-btn
|
||||||
v-model="expenseStore.current_expense.date"
|
push
|
||||||
dense
|
dense
|
||||||
standout
|
icon="event"
|
||||||
readonly
|
color="accent"
|
||||||
stack-label
|
class="col-auto"
|
||||||
color="primary"
|
@click="openDatePicker"
|
||||||
input-class="text-weight-medium"
|
/>
|
||||||
input-style="font-size: 1em;"
|
|
||||||
:label="$t('timesheet.expense.date')"
|
<q-dialog
|
||||||
|
v-model="isNavigatorOpen"
|
||||||
|
transition-show="jump-right"
|
||||||
|
transition-hide="jump-right"
|
||||||
|
class="z-top"
|
||||||
>
|
>
|
||||||
<template #prepend>
|
<q-date
|
||||||
<q-btn
|
v-model="expenseStore.current_expense.date"
|
||||||
push
|
mask="YYYY-MM-DD"
|
||||||
dense
|
event-color="accent"
|
||||||
icon="event"
|
:options="date => date >= period_start_date && date <= period_end_date"
|
||||||
color="accent"
|
@update:model-value="closeDatePicker"
|
||||||
class="q-mr-sm"
|
/>
|
||||||
@click="openDatePicker"
|
</q-dialog>
|
||||||
/>
|
|
||||||
|
|
||||||
<q-dialog
|
<TargoInput
|
||||||
v-model="isNavigatorOpen"
|
v-model="expenseStore.current_expense.date"
|
||||||
transition-show="jump-right"
|
no-top-padding
|
||||||
transition-hide="jump-right"
|
:label="$t('timesheet.expense.date')"
|
||||||
class="z-top"
|
background-color="bg-dark"
|
||||||
>
|
class="col"
|
||||||
<q-date
|
/>
|
||||||
v-model="expenseStore.current_expense.date"
|
|
||||||
mask="YYYY-MM-DD"
|
|
||||||
event-color="accent"
|
|
||||||
:options="date => date >= period_start_date && date <= period_end_date"
|
|
||||||
@update:model-value="closeDatePicker"
|
|
||||||
/>
|
|
||||||
</q-dialog>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<template #label>
|
|
||||||
<span class="text-weight-bold text-accent text-uppercase text-caption">
|
|
||||||
{{ $t('timesheet.expense.date') }}
|
|
||||||
</span>
|
|
||||||
</template>
|
|
||||||
</q-input>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- expenses type selection -->
|
<!-- expenses type selection -->
|
||||||
<div class="col q-px-xs">
|
<div class="col">
|
||||||
<q-select
|
<q-select
|
||||||
v-model="expenseSelected"
|
v-model="expenseSelected"
|
||||||
standout
|
|
||||||
dense
|
dense
|
||||||
:options="expenseOptions"
|
borderless
|
||||||
hide-dropdown-icon
|
color="accent"
|
||||||
|
label-color="white"
|
||||||
stack-label
|
stack-label
|
||||||
label-slot
|
label-slot
|
||||||
color="primary"
|
:options="expenseOptions"
|
||||||
:label="$t('timesheet.expense.type')"
|
hide-dropdown-icon
|
||||||
:menu-offset="[0, 10]"
|
lazy-rules
|
||||||
|
no-error-icon
|
||||||
|
hide-bottom-space
|
||||||
|
options-selected-class="text-white text-bold bg-accent"
|
||||||
|
class="q-px-md rounded-5 inset-shadow"
|
||||||
|
:class="$q.dark.isActive ? 'bg-primary' : 'bg-dark'"
|
||||||
|
popup-content-class="text-uppercase text-weight-medium rounded-5 shadow-12 z-top"
|
||||||
|
popup-content-style="border: 1px solid var(--q-primary);"
|
||||||
menu-anchor="bottom middle"
|
menu-anchor="bottom middle"
|
||||||
menu-self="top middle"
|
menu-self="top middle"
|
||||||
popup-content-class="text-uppercase text-weight-bold text-center rounded-5 z-top"
|
:menu-offset="[0, 5]"
|
||||||
options-selected-class="text-weight-bolder text-white bg-accent"
|
:style="`border: 1px solid var(${$q.dark.isActive ? '--q-secondary' : '--q-primary'});`"
|
||||||
popup-content-style="border: 2px solid var(--q-accent)"
|
|
||||||
:rules="[rules.typeRequired]"
|
:rules="[rules.typeRequired]"
|
||||||
@update:model-value="option => expenseStore.current_expense.type = option.value"
|
@update:model-value="option => expenseStore.current_expense.type = option.value"
|
||||||
>
|
>
|
||||||
<template #label>
|
<template #label>
|
||||||
<span class="text-weight-bold text-accent text-uppercase text-caption">
|
<span
|
||||||
|
class="text-weight-medium text-uppercase q-px-sm no-pointer-events"
|
||||||
|
:class="$q.dark.isActive ? 'bg-secondary' : 'bg-primary'"
|
||||||
|
>
|
||||||
{{ $t('timesheet.expense.type') }}
|
{{ $t('timesheet.expense.type') }}
|
||||||
</span>
|
</span>
|
||||||
</template>
|
</template>
|
||||||
|
|
@ -189,72 +188,32 @@
|
||||||
|
|
||||||
<!-- amount input -->
|
<!-- amount input -->
|
||||||
<div class="col q-px-xs">
|
<div class="col q-px-xs">
|
||||||
<q-input
|
<TargoInput
|
||||||
v-if="TYPES_WITH_AMOUNT_ONLY.includes(expenseStore.current_expense?.type ?? 'EXPENSES')"
|
v-if="TYPES_WITH_AMOUNT_ONLY.includes(expenseStore.current_expense?.type ?? 'EXPENSES')"
|
||||||
v-model.number="expenseStore.current_expense.amount"
|
v-model.number="expenseStore.current_expense.amount"
|
||||||
standout
|
no-top-padding
|
||||||
dense
|
background-color="bg-dark"
|
||||||
label-slot
|
:label="$t('timesheet.expense.amount')"
|
||||||
stack-label
|
/>
|
||||||
suffix="$"
|
|
||||||
type="number"
|
|
||||||
color="primary"
|
|
||||||
input-class="text-right text-weight-medium"
|
|
||||||
input-style="font-size: 1.3em;"
|
|
||||||
lazy-rules="ondemand"
|
|
||||||
:rules="[rules.amountRequired]"
|
|
||||||
>
|
|
||||||
<template #label>
|
|
||||||
<span class="text-weight-bold text-accent text-uppercase text-caption">
|
|
||||||
{{ $t('timesheet.expense.amount') }}
|
|
||||||
</span>
|
|
||||||
</template>
|
|
||||||
</q-input>
|
|
||||||
|
|
||||||
<q-input
|
<TargoInput
|
||||||
v-else
|
v-else
|
||||||
v-model="expenseStore.current_expense.mileage"
|
v-model="expenseStore.current_expense.mileage"
|
||||||
standout
|
no-top-padding
|
||||||
dense
|
background-color="bg-dark"
|
||||||
label-slot
|
:label="$t('timesheet.expense.mileage')"
|
||||||
stack-label
|
/>
|
||||||
suffix="km"
|
|
||||||
type="number"
|
|
||||||
input-class="text-right text-weight-medium"
|
|
||||||
input-style="font-size: 1.3em;"
|
|
||||||
color="primary"
|
|
||||||
lazy-rules="ondemand"
|
|
||||||
:rules="[rules.mileageRequired]"
|
|
||||||
>
|
|
||||||
<template #label>
|
|
||||||
<span class="text-weight-bold text-accent text-uppercase text-caption">
|
|
||||||
{{ $t('timesheet.expense.mileage') }}
|
|
||||||
</span>
|
|
||||||
</template>
|
|
||||||
</q-input>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- employee comment input -->
|
<!-- employee comment input -->
|
||||||
<div class="col q-px-xs">
|
<div class="col q-px-xs">
|
||||||
<q-input
|
<TargoInput
|
||||||
v-model="expenseStore.current_expense.comment"
|
v-model="expenseStore.current_expense.comment"
|
||||||
standout
|
no-top-padding
|
||||||
dense
|
background-color="bg-dark"
|
||||||
stack-label
|
:max-length="COMMENT_MAX_LENGTH"
|
||||||
label-slot
|
:label="$t('timesheet.expense.employee_comment')"
|
||||||
color="primary"
|
/>
|
||||||
input-class="text-weight-medium"
|
|
||||||
input-style="font-size: 1.3em;"
|
|
||||||
:maxlength="COMMENT_MAX_LENGTH"
|
|
||||||
lazy-rules="ondemand"
|
|
||||||
:rules="[rules.commentRequired]"
|
|
||||||
>
|
|
||||||
<template #label>
|
|
||||||
<span class="text-weight-bold text-accent text-uppercase text-caption">
|
|
||||||
{{ $t('timesheet.expense.employee_comment') }}
|
|
||||||
</span>
|
|
||||||
</template>
|
|
||||||
</q-input>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- import attach file section -->
|
<!-- import attach file section -->
|
||||||
|
|
@ -303,8 +262,12 @@
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style scoped>
|
<style
|
||||||
:deep(.q-field--standout.q-field--readonly .q-field__control::before) {
|
scoped
|
||||||
border: transparent;
|
lang="css"
|
||||||
|
>
|
||||||
|
:deep(.q-field--dense.q-field--float .q-field__label) {
|
||||||
|
transform: translate(-17px, -60%) scale(0.75) !important;
|
||||||
|
border-radius: 10px 10px 10px 0px;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
Loading…
Reference in New Issue
Block a user