add clearable option to calendardateinput, fix format, add paid_date

This commit is contained in:
Gregor Vostrak
2025-07-08 14:43:42 +02:00
parent 50e279d466
commit 16baafa50d
2 changed files with 47 additions and 14 deletions

View File

@@ -6,8 +6,8 @@ import {
} from '@/Components/ui/popover'; } from '@/Components/ui/popover';
import { Button } from '@/Components/ui/button'; import { Button } from '@/Components/ui/button';
import { Calendar } from '@/Components/ui/calendar'; import { Calendar } from '@/Components/ui/calendar';
import { CalendarIcon } from 'lucide-vue-next'; import { CalendarIcon, XIcon } from 'lucide-vue-next';
import { formatDateLocalized } from '@/packages/ui/src/utils/time'; import { formatDate } from '@/packages/ui/src/utils/time';
import { parseDate } from '@internationalized/date'; import { parseDate } from '@internationalized/date';
import { computed, inject, type ComputedRef } from 'vue'; import { computed, inject, type ComputedRef } from 'vue';
import { type Organization } from '@/packages/api/src'; import { type Organization } from '@/packages/api/src';
@@ -17,6 +17,10 @@ const emit = defineEmits<{
blur: []; blur: [];
}>(); }>();
defineProps<{
clearable?: boolean;
}>();
const handleChange = (date: string) => { const handleChange = (date: string) => {
model.value = date; model.value = date;
}; };
@@ -25,6 +29,11 @@ const handleBlur = () => {
emit('blur'); emit('blur');
}; };
const handleClear = (event: Event) => {
event.stopPropagation();
model.value = null;
};
const date = computed(() => { const date = computed(() => {
return model.value ? parseDate(model.value) : undefined; return model.value ? parseDate(model.value) : undefined;
}); });
@@ -44,7 +53,17 @@ const organization = inject<ComputedRef<Organization>>('organization');
]" ]"
> >
<CalendarIcon class="mr-2 h-4 w-4" /> <CalendarIcon class="mr-2 h-4 w-4" />
{{ model ? formatDateLocalized(model, organization?.date_format) : 'Pick a date' }} <span class="flex-1">
{{ model ? formatDate(model, organization?.date_format) : 'Pick a date' }}
</span>
<button
v-if="clearable && model"
class="ml-2 hover:bg-muted rounded p-1 transition-colors"
type="button"
@click="handleClear"
>
<XIcon class="h-4 w-4" />
</button>
</Button> </Button>
</PopoverTrigger> </PopoverTrigger>
<PopoverContent class="w-auto p-0"> <PopoverContent class="w-auto p-0">

View File

@@ -67,6 +67,7 @@ const InvoiceResource = z
status: z.string(), status: z.string(),
date: z.string(), date: z.string(),
due_at: z.string(), due_at: z.string(),
paid_date: z.string(),
created_at: z.union([z.string(), z.null()]), created_at: z.union([z.string(), z.null()]),
updated_at: z.union([z.string(), z.null()]), updated_at: z.union([z.string(), z.null()]),
}) })
@@ -76,7 +77,7 @@ const InvoiceDiscountType = z.enum(['percentage', 'fixed']);
const InvoiceStoreRequest = z const InvoiceStoreRequest = z
.object({ .object({
due_at: z.union([z.string(), z.null()]).optional(), due_at: z.union([z.string(), z.null()]).optional(),
paid_at: z.union([z.string(), z.null()]).optional(), paid_date: z.union([z.string(), z.null()]).optional(),
seller_name: z.string(), seller_name: z.string(),
seller_vatin: z.union([z.string(), z.null()]).optional(), seller_vatin: z.union([z.string(), z.null()]).optional(),
seller_address_line_1: z.union([z.string(), z.null()]).optional(), seller_address_line_1: z.union([z.string(), z.null()]).optional(),
@@ -102,8 +103,13 @@ const InvoiceStoreRequest = z
billing_period_end: z.union([z.string(), z.null()]).optional(), billing_period_end: z.union([z.string(), z.null()]).optional(),
reference: z.string(), reference: z.string(),
currency: z.string(), currency: z.string(),
tax_rate: z.number().int().optional(), tax_rate: z.number().int().gte(0).lte(2147483647).optional(),
discount_amount: z.number().int().optional(), discount_amount: z
.number()
.int()
.gte(0)
.lte(9223372036854776000)
.optional(),
discount_type: InvoiceDiscountType.optional(), discount_type: InvoiceDiscountType.optional(),
footer: z.union([z.string(), z.null()]).optional(), footer: z.union([z.string(), z.null()]).optional(),
notes: z.union([z.string(), z.null()]).optional(), notes: z.union([z.string(), z.null()]).optional(),
@@ -115,8 +121,12 @@ const InvoiceStoreRequest = z
.object({ .object({
name: z.string(), name: z.string(),
description: z.union([z.string(), z.null()]).optional(), description: z.union([z.string(), z.null()]).optional(),
unit_price: z.number().int().gte(0).lte(99999999), unit_price: z
quantity: z.number().gte(0), .number()
.int()
.gte(0)
.lte(9223372036854776000),
quantity: z.number().gte(0).lte(99999999),
}) })
.passthrough() .passthrough()
) )
@@ -161,7 +171,7 @@ const DetailedInvoiceResource = z
buyer_address_country: z.string(), buyer_address_country: z.string(),
buyer_phone: z.string(), buyer_phone: z.string(),
buyer_email: z.string(), buyer_email: z.string(),
paid_at: z.union([z.string(), z.null()]), paid_date: z.string(),
due_at: z.string(), due_at: z.string(),
discount_type: z.string(), discount_type: z.string(),
discount_amount: z.number().int(), discount_amount: z.number().int(),
@@ -185,7 +195,7 @@ const InvoiceUpdateRequest = z
.object({ .object({
status: InvoiceStatus, status: InvoiceStatus,
due_at: z.union([z.string(), z.null()]), due_at: z.union([z.string(), z.null()]),
paid_at: z.union([z.string(), z.null()]), paid_date: z.union([z.string(), z.null()]),
seller_name: z.string(), seller_name: z.string(),
seller_vatin: z.union([z.string(), z.null()]), seller_vatin: z.union([z.string(), z.null()]),
seller_address_line_1: z.union([z.string(), z.null()]), seller_address_line_1: z.union([z.string(), z.null()]),
@@ -211,8 +221,8 @@ const InvoiceUpdateRequest = z
billing_period_end: z.union([z.string(), z.null()]), billing_period_end: z.union([z.string(), z.null()]),
reference: z.string(), reference: z.string(),
currency: z.string(), currency: z.string(),
tax_rate: z.number().int(), tax_rate: z.number().int().gte(0).lte(2147483647),
discount_amount: z.number().int(), discount_amount: z.number().int().gte(0).lte(9223372036854776000),
discount_type: InvoiceDiscountType, discount_type: InvoiceDiscountType,
footer: z.union([z.string(), z.null()]), footer: z.union([z.string(), z.null()]),
notes: z.union([z.string(), z.null()]), notes: z.union([z.string(), z.null()]),
@@ -224,8 +234,12 @@ const InvoiceUpdateRequest = z
id: z.union([z.string(), z.null()]).optional(), id: z.union([z.string(), z.null()]).optional(),
name: z.string(), name: z.string(),
description: z.union([z.string(), z.null()]).optional(), description: z.union([z.string(), z.null()]).optional(),
unit_price: z.number().int().gte(0).lte(99999999), unit_price: z
quantity: z.number().gte(0), .number()
.int()
.gte(0)
.lte(9223372036854776000),
quantity: z.number().gte(0).lte(99999999),
}) })
.passthrough() .passthrough()
), ),