mirror of
https://github.com/solidtime-io/solidtime.git
synced 2026-10-13 16:23:18 +01:00
143 lines
4.9 KiB
Vue
143 lines
4.9 KiB
Vue
<script setup lang="ts">
|
||
import { Field, FieldDescription, FieldLabel } from '../field';
|
||
import BillableRateInput from '@/packages/ui/src/Input/BillableRateInput.vue';
|
||
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '..';
|
||
import {
|
||
Tooltip,
|
||
TooltipContent,
|
||
TooltipProvider,
|
||
TooltipTrigger,
|
||
} from '@/packages/ui/src/tooltip';
|
||
import { computed, onMounted, ref, watch } from 'vue';
|
||
import BillableIcon from '@/packages/ui/src/Icons/BillableIcon.vue';
|
||
import { useBillableRatesLock } from '../utils/useBillableRatesLock';
|
||
|
||
const props = defineProps<{
|
||
currency: string;
|
||
organizationBillableRate: number | null;
|
||
}>();
|
||
|
||
const { locked: billableRatesLocked } = useBillableRatesLock();
|
||
|
||
type RateType = 'default-rate' | 'custom-rate';
|
||
|
||
const billableDefault = ref<'billable' | 'non-billable'>('non-billable');
|
||
const rateType = ref<RateType>('default-rate');
|
||
const originallyBillable = ref(false);
|
||
const billableFlagLocked = computed(() => billableRatesLocked.value && !originallyBillable.value);
|
||
|
||
const billableRate = defineModel<number | null>('billableRate');
|
||
const isBillable = defineModel<boolean>('isBillable');
|
||
|
||
onMounted(() => {
|
||
originallyBillable.value = isBillable.value === true;
|
||
if (isBillable.value === true) {
|
||
billableDefault.value = 'billable';
|
||
rateType.value = billableRate.value ? 'custom-rate' : 'default-rate';
|
||
}
|
||
});
|
||
|
||
watch(billableDefault, () => {
|
||
if (billableDefault.value === 'non-billable') {
|
||
isBillable.value = false;
|
||
} else {
|
||
isBillable.value = true;
|
||
}
|
||
});
|
||
|
||
watch(rateType, () => {
|
||
if (rateType.value === 'default-rate') {
|
||
billableRate.value = null;
|
||
} else if (rateType.value === 'custom-rate') {
|
||
billableDefault.value = 'billable';
|
||
isBillable.value = true;
|
||
if (!billableRate.value) {
|
||
billableRate.value = props.organizationBillableRate ?? null;
|
||
}
|
||
}
|
||
});
|
||
|
||
const displayedRate = computed({
|
||
get() {
|
||
if (rateType.value === 'default-rate') {
|
||
return props.organizationBillableRate ?? null;
|
||
}
|
||
return billableRate.value;
|
||
},
|
||
set(value: number | null) {
|
||
if (rateType.value === 'custom-rate') {
|
||
billableRate.value = value;
|
||
}
|
||
},
|
||
});
|
||
|
||
const billableDescription = computed(() => {
|
||
if (billableFlagLocked.value) {
|
||
return 'Your organization’s plan does not allow enabling billable projects.';
|
||
}
|
||
if (billableDefault.value === 'non-billable') {
|
||
return 'New time entries for this project will not be marked billable by default.';
|
||
}
|
||
return 'New time entries for this project will be marked billable by default.';
|
||
});
|
||
|
||
const emit = defineEmits(['submit']);
|
||
</script>
|
||
|
||
<template>
|
||
<Field>
|
||
<FieldLabel for="billable" :icon="BillableIcon">Billable Default</FieldLabel>
|
||
<Select v-model="billableDefault">
|
||
<SelectTrigger id="billable">
|
||
<SelectValue />
|
||
</SelectTrigger>
|
||
<SelectContent>
|
||
<SelectItem value="non-billable">Non-billable</SelectItem>
|
||
<SelectItem value="billable" :disabled="billableFlagLocked">Billable</SelectItem>
|
||
</SelectContent>
|
||
</Select>
|
||
<FieldDescription>{{ billableDescription }}</FieldDescription>
|
||
</Field>
|
||
<Field>
|
||
<FieldLabel :icon="BillableIcon" for="billableRateType">Billable Rate</FieldLabel>
|
||
<BillableRateInput
|
||
v-if="billableRatesLocked"
|
||
v-model="displayedRate"
|
||
:currency="currency"
|
||
name="billableRate" />
|
||
<div v-else class="grid grid-cols-1 sm:grid-cols-2 gap-2">
|
||
<Select v-model="rateType">
|
||
<SelectTrigger id="billableRateType">
|
||
<SelectValue />
|
||
</SelectTrigger>
|
||
<SelectContent>
|
||
<SelectItem value="default-rate">Default Rate</SelectItem>
|
||
<SelectItem value="custom-rate">Custom Rate</SelectItem>
|
||
</SelectContent>
|
||
</Select>
|
||
<TooltipProvider v-if="rateType === 'default-rate'">
|
||
<Tooltip>
|
||
<TooltipTrigger as-child>
|
||
<div>
|
||
<BillableRateInput
|
||
v-model="displayedRate"
|
||
:currency="currency"
|
||
disabled
|
||
name="billableRate" />
|
||
</div>
|
||
</TooltipTrigger>
|
||
<TooltipContent> Uses the default rate of the organization </TooltipContent>
|
||
</Tooltip>
|
||
</TooltipProvider>
|
||
<BillableRateInput
|
||
v-else
|
||
v-model="displayedRate"
|
||
:currency="currency"
|
||
name="billableRate"
|
||
@keydown.enter="emit('submit')" />
|
||
</div>
|
||
</Field>
|
||
</template>
|
||
|
||
<style scoped></style>
|