diff --git a/CHANGELOG.md b/CHANGELOG.md index 588729b..8e53ce3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,12 @@ e este projeto adere ao [Versionamento Semântico](https://semver.org/lang/pt-BR ## [Unreleased] +## [2.0.3] - 2026-03-26 + +### Corrigido + +- Lançamentos: `/transactions` deixa de depender de `crypto.randomUUID()` no carregamento inicial, corrigindo a falha em ambientes self-hosted sem HTTPS ao abrir a página + ## [2.0.2] - 2026-03-25 ### Adicionado diff --git a/package.json b/package.json index 2b1ffb8..2b6bf43 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "openmonetis", - "version": "2.0.2", + "version": "2.0.3", "private": true, "scripts": { "dev": "next dev --turbopack", diff --git a/src/features/transactions/components/dialogs/mass-add-dialog.tsx b/src/features/transactions/components/dialogs/mass-add-dialog.tsx index 80d511d..c02d3b3 100644 --- a/src/features/transactions/components/dialogs/mass-add-dialog.tsx +++ b/src/features/transactions/components/dialogs/mass-add-dialog.tsx @@ -38,6 +38,7 @@ import { import { Separator } from "@/shared/components/ui/separator"; import { Spinner } from "@/shared/components/ui/spinner"; import { getTodayDateString } from "@/shared/utils/date"; +import { createClientSafeId } from "@/shared/utils/id"; import { dateToPeriod, displayPeriod, @@ -120,6 +121,19 @@ interface TransactionRow { payerId: string | undefined; } +function createEmptyTransactionRow( + defaultPayerId?: string | null, +): TransactionRow { + return { + id: createClientSafeId(), + purchaseDate: getTodayDateString(), + name: "", + amount: "", + categoryId: undefined, + payerId: defaultPayerId ?? undefined, + }; +} + export function MassAddDialog({ open, onOpenChange, @@ -153,15 +167,8 @@ export function MassAddDialog({ const isCartaoSelected = paymentMethod === "Cartão de crédito"; // Transaction rows - const [transactions, setTransactions] = useState([ - { - id: crypto.randomUUID(), - purchaseDate: getTodayDateString(), - name: "", - amount: "", - categoryId: undefined, - payerId: defaultPayerId ?? undefined, - }, + const [transactions, setTransactions] = useState(() => [ + createEmptyTransactionRow(defaultPayerId), ]); // Categorias agrupadas e filtradas por tipo de transação @@ -175,14 +182,7 @@ export function MassAddDialog({ const addTransaction = () => { setTransactions([ ...transactions, - { - id: crypto.randomUUID(), - purchaseDate: getTodayDateString(), - name: "", - amount: "", - categoryId: undefined, - payerId: defaultPayerId ?? undefined, - }, + createEmptyTransactionRow(defaultPayerId), ]); }; @@ -256,16 +256,7 @@ export function MassAddDialog({ setPeriod(selectedPeriod); setContaId(undefined); setCartaoId(defaultCardId ?? undefined); - setTransactions([ - { - id: crypto.randomUUID(), - purchaseDate: getTodayDateString(), - name: "", - amount: "", - categoryId: undefined, - payerId: defaultPayerId ?? undefined, - }, - ]); + setTransactions([createEmptyTransactionRow(defaultPayerId)]); } catch (_error) { // Error is handled by the onSubmit function } finally { diff --git a/src/features/transactions/components/page/transactions-page.tsx b/src/features/transactions/components/page/transactions-page.tsx index ff084f2..812c1de 100644 --- a/src/features/transactions/components/page/transactions-page.tsx +++ b/src/features/transactions/components/page/transactions-page.tsx @@ -575,7 +575,7 @@ export function TransactionsPage({ onConfirm={handleBulkEdit} /> - {allowCreate ? ( + {allowCreate && massAddOpen ? ( byte.toString(FALLBACK_HEX_RADIX).padStart(2, "0")) + .join(""); + } + + let hex = ""; + + for (let index = 0; index < byteCount; index += 1) { + hex += Math.floor(Math.random() * 256) + .toString(FALLBACK_HEX_RADIX) + .padStart(2, "0"); + } + + return hex; +} + +export function createClientSafeId() { + const cryptoApi = globalThis.crypto; + + if (cryptoApi?.randomUUID) { + return cryptoApi.randomUUID(); + } + + return [ + randomHex(4), + randomHex(2), + randomHex(2), + randomHex(2), + randomHex(6), + ].join("-"); +}