mirror of
https://github.com/felipegcoutinho/openmonetis.git
synced 2026-05-09 11:01:45 +00:00
fix(transactions): avoid crypto.randomUUID on initial load
This commit is contained in:
@@ -7,6 +7,12 @@ e este projeto adere ao [Versionamento Semântico](https://semver.org/lang/pt-BR
|
|||||||
|
|
||||||
## [Unreleased]
|
## [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
|
## [2.0.2] - 2026-03-25
|
||||||
|
|
||||||
### Adicionado
|
### Adicionado
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "openmonetis",
|
"name": "openmonetis",
|
||||||
"version": "2.0.2",
|
"version": "2.0.3",
|
||||||
"private": true,
|
"private": true,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "next dev --turbopack",
|
"dev": "next dev --turbopack",
|
||||||
|
|||||||
@@ -38,6 +38,7 @@ import {
|
|||||||
import { Separator } from "@/shared/components/ui/separator";
|
import { Separator } from "@/shared/components/ui/separator";
|
||||||
import { Spinner } from "@/shared/components/ui/spinner";
|
import { Spinner } from "@/shared/components/ui/spinner";
|
||||||
import { getTodayDateString } from "@/shared/utils/date";
|
import { getTodayDateString } from "@/shared/utils/date";
|
||||||
|
import { createClientSafeId } from "@/shared/utils/id";
|
||||||
import {
|
import {
|
||||||
dateToPeriod,
|
dateToPeriod,
|
||||||
displayPeriod,
|
displayPeriod,
|
||||||
@@ -120,6 +121,19 @@ interface TransactionRow {
|
|||||||
payerId: string | undefined;
|
payerId: string | undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function createEmptyTransactionRow(
|
||||||
|
defaultPayerId?: string | null,
|
||||||
|
): TransactionRow {
|
||||||
|
return {
|
||||||
|
id: createClientSafeId(),
|
||||||
|
purchaseDate: getTodayDateString(),
|
||||||
|
name: "",
|
||||||
|
amount: "",
|
||||||
|
categoryId: undefined,
|
||||||
|
payerId: defaultPayerId ?? undefined,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
export function MassAddDialog({
|
export function MassAddDialog({
|
||||||
open,
|
open,
|
||||||
onOpenChange,
|
onOpenChange,
|
||||||
@@ -153,15 +167,8 @@ export function MassAddDialog({
|
|||||||
const isCartaoSelected = paymentMethod === "Cartão de crédito";
|
const isCartaoSelected = paymentMethod === "Cartão de crédito";
|
||||||
|
|
||||||
// Transaction rows
|
// Transaction rows
|
||||||
const [transactions, setTransactions] = useState<TransactionRow[]>([
|
const [transactions, setTransactions] = useState<TransactionRow[]>(() => [
|
||||||
{
|
createEmptyTransactionRow(defaultPayerId),
|
||||||
id: crypto.randomUUID(),
|
|
||||||
purchaseDate: getTodayDateString(),
|
|
||||||
name: "",
|
|
||||||
amount: "",
|
|
||||||
categoryId: undefined,
|
|
||||||
payerId: defaultPayerId ?? undefined,
|
|
||||||
},
|
|
||||||
]);
|
]);
|
||||||
|
|
||||||
// Categorias agrupadas e filtradas por tipo de transação
|
// Categorias agrupadas e filtradas por tipo de transação
|
||||||
@@ -175,14 +182,7 @@ export function MassAddDialog({
|
|||||||
const addTransaction = () => {
|
const addTransaction = () => {
|
||||||
setTransactions([
|
setTransactions([
|
||||||
...transactions,
|
...transactions,
|
||||||
{
|
createEmptyTransactionRow(defaultPayerId),
|
||||||
id: crypto.randomUUID(),
|
|
||||||
purchaseDate: getTodayDateString(),
|
|
||||||
name: "",
|
|
||||||
amount: "",
|
|
||||||
categoryId: undefined,
|
|
||||||
payerId: defaultPayerId ?? undefined,
|
|
||||||
},
|
|
||||||
]);
|
]);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -256,16 +256,7 @@ export function MassAddDialog({
|
|||||||
setPeriod(selectedPeriod);
|
setPeriod(selectedPeriod);
|
||||||
setContaId(undefined);
|
setContaId(undefined);
|
||||||
setCartaoId(defaultCardId ?? undefined);
|
setCartaoId(defaultCardId ?? undefined);
|
||||||
setTransactions([
|
setTransactions([createEmptyTransactionRow(defaultPayerId)]);
|
||||||
{
|
|
||||||
id: crypto.randomUUID(),
|
|
||||||
purchaseDate: getTodayDateString(),
|
|
||||||
name: "",
|
|
||||||
amount: "",
|
|
||||||
categoryId: undefined,
|
|
||||||
payerId: defaultPayerId ?? undefined,
|
|
||||||
},
|
|
||||||
]);
|
|
||||||
} catch (_error) {
|
} catch (_error) {
|
||||||
// Error is handled by the onSubmit function
|
// Error is handled by the onSubmit function
|
||||||
} finally {
|
} finally {
|
||||||
|
|||||||
@@ -575,7 +575,7 @@ export function TransactionsPage({
|
|||||||
onConfirm={handleBulkEdit}
|
onConfirm={handleBulkEdit}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
{allowCreate ? (
|
{allowCreate && massAddOpen ? (
|
||||||
<MassAddDialog
|
<MassAddDialog
|
||||||
open={massAddOpen}
|
open={massAddOpen}
|
||||||
onOpenChange={setMassAddOpen}
|
onOpenChange={setMassAddOpen}
|
||||||
|
|||||||
37
src/shared/utils/id.ts
Normal file
37
src/shared/utils/id.ts
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
const FALLBACK_HEX_RADIX = 16;
|
||||||
|
|
||||||
|
function randomHex(byteCount: number) {
|
||||||
|
const cryptoApi = globalThis.crypto;
|
||||||
|
|
||||||
|
if (cryptoApi?.getRandomValues) {
|
||||||
|
return Array.from(cryptoApi.getRandomValues(new Uint8Array(byteCount)))
|
||||||
|
.map((byte) => 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("-");
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user