mirror of
https://github.com/mauriceboe/TREK.git
synced 2026-10-18 21:16:47 +00:00
Add a note field to expenses (#1888)
Requested in discussion #1658: an expense carries an amount and a category, and everything else about it ends up crammed into the title. The column was already there. It just was not available, because the costs UI stores an itemized receipt in it as TICKETJSON:{...}, so an expense split by receipt could never carry a note - and saving one any other way wrote note=null, which quietly wiped whatever had been typed into the budget table. The receipt gets its own column and note goes back to being text. Old clients that still send the blob as a note are routed to the right column instead of clobbering the note. On desktop the row now has fixed columns, so the amount does not drift left when one row has a note and the next does not. The category moved to the card edge as a tab like the mobile card does, which is what frees the line the note sits on. Collapsed it is one line, and the same element grows in place when opened. The dialog is two columns now: what the expense was on the left, how it is shared on the right, grouped into panels the way the trip dialog does it. On the phone the eleven category pills became a dropdown, which is where the room for the note field came from, and a note on a card unfolds when you tap it.
This commit is contained in:
@@ -113,6 +113,8 @@ export const budgetItemSchema = z.object({
|
||||
persons: z.number().nullable().optional(),
|
||||
days: z.number().nullable().optional(),
|
||||
note: z.string().nullable().optional(),
|
||||
/** Itemized receipt behind a per-item split, as JSON. Its own column since #1658. */
|
||||
ticket_json: z.string().nullable().optional(),
|
||||
reservation_id: z.number().nullable().optional(),
|
||||
paid_by_user_id: z.number().nullable().optional(),
|
||||
expense_date: z.string().nullable().optional(),
|
||||
@@ -148,6 +150,7 @@ export const budgetCreateItemRequestSchema = z.object({
|
||||
persons: z.number().nullable().optional(),
|
||||
days: z.number().nullable().optional(),
|
||||
note: z.string().nullable().optional(),
|
||||
ticket_json: z.string().nullable().optional(),
|
||||
expense_date: z.string().nullable().optional(),
|
||||
// Link this expense to a reservation (e.g. created from a booking's
|
||||
// "add expense" flow). The server stores it on budget_items.reservation_id.
|
||||
@@ -168,6 +171,7 @@ export const budgetUpdateItemRequestSchema = z.object({
|
||||
persons: z.number().nullable().optional(),
|
||||
days: z.number().nullable().optional(),
|
||||
note: z.string().nullable().optional(),
|
||||
ticket_json: z.string().nullable().optional(),
|
||||
expense_date: z.string().nullable().optional(),
|
||||
});
|
||||
export type BudgetUpdateItemRequest = z.infer<typeof budgetUpdateItemRequestSchema>;
|
||||
|
||||
@@ -89,6 +89,11 @@ const budget: TranslationStrings = {
|
||||
'costs.undo': 'تراجع',
|
||||
'costs.whatFor': 'لأجل ماذا كان؟',
|
||||
'costs.namePlaceholder': 'مثل: عشاء، هدايا تذكارية، وقود…',
|
||||
'costs.note': 'ملاحظة',
|
||||
'costs.notePlaceholder': 'ما الذي شملته، ومن يدين بماذا…',
|
||||
'costs.addNote': 'إضافة ملاحظة',
|
||||
'costs.showNote': 'عرض الملاحظة',
|
||||
'costs.hideNote': 'إخفاء الملاحظة',
|
||||
'costs.totalAmount': 'المبلغ الإجمالي',
|
||||
'costs.currency': 'العملة',
|
||||
'costs.day': 'اليوم',
|
||||
|
||||
@@ -89,6 +89,11 @@ const budget: TranslationStrings = {
|
||||
'costs.undo': 'Desfazer',
|
||||
'costs.whatFor': 'Para que foi?',
|
||||
'costs.namePlaceholder': 'ex.: jantar, lembranças, gasolina…',
|
||||
'costs.note': 'Nota',
|
||||
'costs.notePlaceholder': 'O que incluía, quem deve o quê…',
|
||||
'costs.addNote': 'Adicionar nota',
|
||||
'costs.showNote': 'Mostrar nota',
|
||||
'costs.hideNote': 'Ocultar nota',
|
||||
'costs.totalAmount': 'Valor total',
|
||||
'costs.currency': 'Moeda',
|
||||
'costs.day': 'Dia',
|
||||
|
||||
@@ -87,6 +87,11 @@ const budget: TranslationStrings = {
|
||||
'costs.undo': 'Desfer',
|
||||
'costs.whatFor': 'Per a què ha estat?',
|
||||
'costs.namePlaceholder': 'p. ex. Sopar, records, benzina…',
|
||||
'costs.note': 'Nota',
|
||||
'costs.notePlaceholder': 'Què incloïa, qui deu què…',
|
||||
'costs.addNote': 'Afegeix una nota',
|
||||
'costs.showNote': 'Mostra la nota',
|
||||
'costs.hideNote': 'Amaga la nota',
|
||||
'costs.totalAmount': 'Import total',
|
||||
'costs.currency': 'Divisa',
|
||||
'costs.day': 'Dia',
|
||||
|
||||
@@ -89,6 +89,11 @@ const budget: TranslationStrings = {
|
||||
'costs.undo': 'Vrátit zpět',
|
||||
'costs.whatFor': 'Za co to bylo?',
|
||||
'costs.namePlaceholder': 'např. večeře, suvenýry, benzín…',
|
||||
'costs.note': 'Poznámka',
|
||||
'costs.notePlaceholder': 'Co zahrnovalo, kdo co dluží…',
|
||||
'costs.addNote': 'Přidat poznámku',
|
||||
'costs.showNote': 'Zobrazit poznámku',
|
||||
'costs.hideNote': 'Skrýt poznámku',
|
||||
'costs.totalAmount': 'Celková částka',
|
||||
'costs.currency': 'Měna',
|
||||
'costs.day': 'Den',
|
||||
|
||||
@@ -92,6 +92,11 @@ const budget: TranslationStrings = {
|
||||
'costs.undo': 'Rückgängig',
|
||||
'costs.whatFor': 'Wofür war es?',
|
||||
'costs.namePlaceholder': 'z.B. Abendessen, Souvenirs, Benzin…',
|
||||
'costs.note': 'Notiz',
|
||||
'costs.notePlaceholder': 'Was darin enthalten war, wer was zurückzahlt…',
|
||||
'costs.addNote': 'Notiz hinzufügen',
|
||||
'costs.showNote': 'Notiz anzeigen',
|
||||
'costs.hideNote': 'Notiz ausblenden',
|
||||
'costs.totalAmount': 'Gesamtbetrag',
|
||||
'costs.currency': 'Währung',
|
||||
'costs.day': 'Tag',
|
||||
|
||||
@@ -92,6 +92,11 @@ const budget: TranslationStrings = {
|
||||
'costs.undo': 'Undo',
|
||||
'costs.whatFor': 'What was it for?',
|
||||
'costs.namePlaceholder': 'e.g. Dinner, souvenirs, gas…',
|
||||
'costs.note': 'Note',
|
||||
'costs.notePlaceholder': 'What it covered, who owes what back…',
|
||||
'costs.addNote': 'Add note',
|
||||
'costs.showNote': 'Show note',
|
||||
'costs.hideNote': 'Hide note',
|
||||
'costs.totalAmount': 'Total amount',
|
||||
'costs.currency': 'Currency',
|
||||
'costs.day': 'Day',
|
||||
|
||||
@@ -89,6 +89,11 @@ const budget: TranslationStrings = {
|
||||
'costs.undo': 'Deshacer',
|
||||
'costs.whatFor': '¿Para qué fue?',
|
||||
'costs.namePlaceholder': 'p. ej. Cena, souvenirs, gasolina…',
|
||||
'costs.note': 'Nota',
|
||||
'costs.notePlaceholder': 'Qué incluía, quién debe qué…',
|
||||
'costs.addNote': 'Añadir nota',
|
||||
'costs.showNote': 'Mostrar nota',
|
||||
'costs.hideNote': 'Ocultar nota',
|
||||
'costs.totalAmount': 'Importe total',
|
||||
'costs.currency': 'Moneda',
|
||||
'costs.day': 'Día',
|
||||
|
||||
@@ -89,6 +89,11 @@ const budget: TranslationStrings = {
|
||||
'costs.undo': 'Annuler',
|
||||
'costs.whatFor': "C'était pour quoi ?",
|
||||
'costs.namePlaceholder': 'ex. dîner, souvenirs, essence…',
|
||||
'costs.note': 'Note',
|
||||
'costs.notePlaceholder': 'Ce que ça couvrait, qui doit quoi…',
|
||||
'costs.addNote': 'Ajouter une note',
|
||||
'costs.showNote': 'Afficher la note',
|
||||
'costs.hideNote': 'Masquer la note',
|
||||
'costs.totalAmount': 'Montant total',
|
||||
'costs.currency': 'Devise',
|
||||
'costs.day': 'Jour',
|
||||
|
||||
@@ -90,6 +90,11 @@ const budget: TranslationStrings = {
|
||||
'costs.undo': 'Αναίρεση',
|
||||
'costs.whatFor': 'Για τι ήταν;',
|
||||
'costs.namePlaceholder': 'π.χ. Δείπνο, σουβενίρ, βενζίνη…',
|
||||
'costs.note': 'Σημείωση',
|
||||
'costs.notePlaceholder': 'Τι κάλυπτε, ποιος χρωστάει τι…',
|
||||
'costs.addNote': 'Προσθήκη σημείωσης',
|
||||
'costs.showNote': 'Εμφάνιση σημείωσης',
|
||||
'costs.hideNote': 'Απόκρυψη σημείωσης',
|
||||
'costs.totalAmount': 'Συνολικό ποσό',
|
||||
'costs.currency': 'Νόμισμα',
|
||||
'costs.day': 'Ημέρα',
|
||||
|
||||
@@ -89,6 +89,11 @@ const budget: TranslationStrings = {
|
||||
'costs.undo': 'Visszavonás',
|
||||
'costs.whatFor': 'Mire volt?',
|
||||
'costs.namePlaceholder': 'pl. vacsora, ajándékok, benzin…',
|
||||
'costs.note': 'Megjegyzés',
|
||||
'costs.notePlaceholder': 'Mit fedezett, ki tartozik mivel…',
|
||||
'costs.addNote': 'Megjegyzés hozzáadása',
|
||||
'costs.showNote': 'Megjegyzés megjelenítése',
|
||||
'costs.hideNote': 'Megjegyzés elrejtése',
|
||||
'costs.totalAmount': 'Teljes összeg',
|
||||
'costs.currency': 'Pénznem',
|
||||
'costs.day': 'Nap',
|
||||
|
||||
@@ -89,6 +89,11 @@ const budget: TranslationStrings = {
|
||||
'costs.undo': 'Urungkan',
|
||||
'costs.whatFor': 'Untuk apa?',
|
||||
'costs.namePlaceholder': 'mis. Makan malam, oleh-oleh, bensin…',
|
||||
'costs.note': 'Catatan',
|
||||
'costs.notePlaceholder': 'Apa saja yang termasuk, siapa berutang apa…',
|
||||
'costs.addNote': 'Tambah catatan',
|
||||
'costs.showNote': 'Tampilkan catatan',
|
||||
'costs.hideNote': 'Sembunyikan catatan',
|
||||
'costs.totalAmount': 'Jumlah total',
|
||||
'costs.currency': 'Mata uang',
|
||||
'costs.day': 'Hari',
|
||||
|
||||
@@ -89,6 +89,11 @@ const budget: TranslationStrings = {
|
||||
'costs.undo': 'Annulla',
|
||||
'costs.whatFor': 'Per cosa era?',
|
||||
'costs.namePlaceholder': 'es. Cena, souvenir, benzina…',
|
||||
'costs.note': 'Nota',
|
||||
'costs.notePlaceholder': 'Cosa comprendeva, chi deve cosa…',
|
||||
'costs.addNote': 'Aggiungi nota',
|
||||
'costs.showNote': 'Mostra nota',
|
||||
'costs.hideNote': 'Nascondi nota',
|
||||
'costs.totalAmount': 'Importo totale',
|
||||
'costs.currency': 'Valuta',
|
||||
'costs.day': 'Giorno',
|
||||
|
||||
@@ -89,6 +89,11 @@ const budget: TranslationStrings = {
|
||||
'costs.undo': '元に戻す',
|
||||
'costs.whatFor': '何の支出ですか?',
|
||||
'costs.namePlaceholder': '例:夕食、お土産、ガソリン…',
|
||||
'costs.note': 'メモ',
|
||||
'costs.notePlaceholder': '内訳や立て替えのメモなど…',
|
||||
'costs.addNote': 'メモを追加',
|
||||
'costs.showNote': 'メモを表示',
|
||||
'costs.hideNote': 'メモを非表示',
|
||||
'costs.totalAmount': '合計金額',
|
||||
'costs.currency': '通貨',
|
||||
'costs.day': '日',
|
||||
|
||||
@@ -89,6 +89,11 @@ const budget: TranslationStrings = {
|
||||
'costs.undo': '실행 취소',
|
||||
'costs.whatFor': '무엇을 위한 것인가요?',
|
||||
'costs.namePlaceholder': '예: 저녁 식사, 기념품, 주유…',
|
||||
'costs.note': '메모',
|
||||
'costs.notePlaceholder': '무엇을 샀는지, 누가 갚아야 하는지…',
|
||||
'costs.addNote': '메모 추가',
|
||||
'costs.showNote': '메모 보기',
|
||||
'costs.hideNote': '메모 숨기기',
|
||||
'costs.totalAmount': '총 금액',
|
||||
'costs.currency': '통화',
|
||||
'costs.day': '날짜',
|
||||
|
||||
@@ -89,6 +89,11 @@ const budget: TranslationStrings = {
|
||||
'costs.undo': 'Ongedaan maken',
|
||||
'costs.whatFor': 'Waar was het voor?',
|
||||
'costs.namePlaceholder': 'bijv. Diner, souvenirs, benzine…',
|
||||
'costs.note': 'Notitie',
|
||||
'costs.notePlaceholder': 'Wat het omvatte, wie wat terugbetaalt…',
|
||||
'costs.addNote': 'Notitie toevoegen',
|
||||
'costs.showNote': 'Notitie tonen',
|
||||
'costs.hideNote': 'Notitie verbergen',
|
||||
'costs.totalAmount': 'Totaalbedrag',
|
||||
'costs.currency': 'Valuta',
|
||||
'costs.day': 'Dag',
|
||||
|
||||
@@ -89,6 +89,11 @@ const budget: TranslationStrings = {
|
||||
'costs.undo': 'Cofnij',
|
||||
'costs.whatFor': 'Na co to było?',
|
||||
'costs.namePlaceholder': 'np. kolacja, pamiątki, paliwo…',
|
||||
'costs.note': 'Notatka',
|
||||
'costs.notePlaceholder': 'Co obejmowało, kto ile oddaje…',
|
||||
'costs.addNote': 'Dodaj notatkę',
|
||||
'costs.showNote': 'Pokaż notatkę',
|
||||
'costs.hideNote': 'Ukryj notatkę',
|
||||
'costs.totalAmount': 'Łączna kwota',
|
||||
'costs.currency': 'Waluta',
|
||||
'costs.day': 'Dzień',
|
||||
|
||||
@@ -89,6 +89,11 @@ const budget: TranslationStrings = {
|
||||
'costs.undo': 'Отменить',
|
||||
'costs.whatFor': 'За что это было?',
|
||||
'costs.namePlaceholder': 'напр. ужин, сувениры, бензин…',
|
||||
'costs.note': 'Заметка',
|
||||
'costs.notePlaceholder': 'Что входило, кто сколько должен…',
|
||||
'costs.addNote': 'Добавить заметку',
|
||||
'costs.showNote': 'Показать заметку',
|
||||
'costs.hideNote': 'Скрыть заметку',
|
||||
'costs.totalAmount': 'Общая сумма',
|
||||
'costs.currency': 'Валюта',
|
||||
'costs.day': 'День',
|
||||
|
||||
@@ -89,6 +89,11 @@ const budget: TranslationStrings = {
|
||||
'costs.undo': 'Ångra',
|
||||
'costs.whatFor': 'Vad var det till för?',
|
||||
'costs.namePlaceholder': 't.ex. middag, souvenirer, bensin…',
|
||||
'costs.note': 'Anteckning',
|
||||
'costs.notePlaceholder': 'Vad det omfattade, vem som ska betala tillbaka…',
|
||||
'costs.addNote': 'Lägg till anteckning',
|
||||
'costs.showNote': 'Visa anteckning',
|
||||
'costs.hideNote': 'Dölj anteckning',
|
||||
'costs.totalAmount': 'Totalt belopp',
|
||||
'costs.currency': 'Valuta',
|
||||
'costs.day': 'Dag',
|
||||
|
||||
@@ -89,6 +89,11 @@ const budget: TranslationStrings = {
|
||||
'costs.undo': 'Geri al',
|
||||
'costs.whatFor': 'Ne içindi?',
|
||||
'costs.namePlaceholder': 'örn. Akşam yemeği, hediyelik, benzin…',
|
||||
'costs.note': 'Not',
|
||||
'costs.notePlaceholder': 'Neyi kapsadığı, kimin ne borcu olduğu…',
|
||||
'costs.addNote': 'Not ekle',
|
||||
'costs.showNote': 'Notu göster',
|
||||
'costs.hideNote': 'Notu gizle',
|
||||
'costs.totalAmount': 'Toplam tutar',
|
||||
'costs.currency': 'Para birimi',
|
||||
'costs.day': 'Gün',
|
||||
|
||||
@@ -89,6 +89,11 @@ const budget: TranslationStrings = {
|
||||
'costs.undo': 'Скасувати',
|
||||
'costs.whatFor': 'За що це було?',
|
||||
'costs.namePlaceholder': 'напр. вечеря, сувеніри, пальне…',
|
||||
'costs.note': 'Нотатка',
|
||||
'costs.notePlaceholder': 'Що входило, хто скільки винен…',
|
||||
'costs.addNote': 'Додати нотатку',
|
||||
'costs.showNote': 'Показати нотатку',
|
||||
'costs.hideNote': 'Сховати нотатку',
|
||||
'costs.totalAmount': 'Загальна сума',
|
||||
'costs.currency': 'Валюта',
|
||||
'costs.day': 'День',
|
||||
|
||||
@@ -89,6 +89,11 @@ const budget: TranslationStrings = {
|
||||
'costs.undo': 'Hoàn tác',
|
||||
'costs.whatFor': 'Nó dùng để làm gì?',
|
||||
'costs.namePlaceholder': 'ví dụ. Ăn tối, quà lưu niệm, xăng…',
|
||||
'costs.note': 'Ghi chú',
|
||||
'costs.notePlaceholder': 'Khoản này gồm những gì, ai nợ bao nhiêu…',
|
||||
'costs.addNote': 'Thêm ghi chú',
|
||||
'costs.showNote': 'Hiện ghi chú',
|
||||
'costs.hideNote': 'Ẩn ghi chú',
|
||||
'costs.totalAmount': 'Tổng số tiền',
|
||||
'costs.currency': 'Tiền tệ',
|
||||
'costs.day': 'Ngày',
|
||||
|
||||
@@ -88,6 +88,11 @@ const budget: TranslationStrings = {
|
||||
'costs.undo': '復原',
|
||||
'costs.whatFor': '這筆是什麼支出?',
|
||||
'costs.namePlaceholder': '例如:晚餐、紀念品、油費…',
|
||||
'costs.note': '備註',
|
||||
'costs.notePlaceholder': '包含哪些內容、誰需要還款…',
|
||||
'costs.addNote': '新增備註',
|
||||
'costs.showNote': '顯示備註',
|
||||
'costs.hideNote': '隱藏備註',
|
||||
'costs.totalAmount': '總金額',
|
||||
'costs.currency': '貨幣',
|
||||
'costs.day': '日期',
|
||||
|
||||
@@ -88,6 +88,11 @@ const budget: TranslationStrings = {
|
||||
'costs.undo': '撤销',
|
||||
'costs.whatFor': '这笔花在哪了?',
|
||||
'costs.namePlaceholder': '例如:晚餐、纪念品、油费…',
|
||||
'costs.note': '备注',
|
||||
'costs.notePlaceholder': '包含哪些内容、谁需要还款…',
|
||||
'costs.addNote': '添加备注',
|
||||
'costs.showNote': '显示备注',
|
||||
'costs.hideNote': '隐藏备注',
|
||||
'costs.totalAmount': '总金额',
|
||||
'costs.currency': '货币',
|
||||
'costs.day': '日期',
|
||||
|
||||
Reference in New Issue
Block a user