@carlonicora/nextjs-jsonapi 6.29.0 → 6.30.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{BlockNoteEditor-KGCHQQVY.js → BlockNoteEditor-FTRTY4YJ.js} +15 -15
- package/dist/{BlockNoteEditor-KGCHQQVY.js.map → BlockNoteEditor-FTRTY4YJ.js.map} +1 -1
- package/dist/{BlockNoteEditor-BHCNJ2JA.mjs → BlockNoteEditor-SQQF7OCY.mjs} +2 -2
- package/dist/billing/index.js +378 -378
- package/dist/billing/index.mjs +1 -1
- package/dist/{chunk-UQFDOZVF.mjs → chunk-MNN6MTEN.mjs} +552 -546
- package/dist/chunk-MNN6MTEN.mjs.map +1 -0
- package/dist/{chunk-WXTEAATG.js → chunk-S4FSGMKX.js} +11 -5
- package/dist/chunk-S4FSGMKX.js.map +1 -0
- package/dist/client/index.js +2 -2
- package/dist/client/index.mjs +1 -1
- package/dist/components/forms/CommonEditorButtons.d.ts.map +1 -1
- package/dist/components/forms/EditorSheet.d.ts.map +1 -1
- package/dist/components/index.js +2 -2
- package/dist/components/index.mjs +1 -1
- package/dist/contexts/index.js +2 -2
- package/dist/contexts/index.mjs +1 -1
- package/dist/email-automations/index.js +78 -78
- package/dist/email-automations/index.mjs +1 -1
- package/dist/features/analytics/index.js +107 -107
- package/dist/features/analytics/index.mjs +1 -1
- package/dist/features/blog/index.js +93 -93
- package/dist/features/blog/index.mjs +1 -1
- package/dist/features/help/index.js +31 -31
- package/dist/features/help/index.mjs +1 -1
- package/dist/features/tokenusage/index.js +102 -102
- package/dist/features/tokenusage/index.mjs +1 -1
- package/messages/en.json +1 -0
- package/messages/it.json +1 -0
- package/package.json +1 -1
- package/src/components/forms/CommonEditorButtons.tsx +16 -2
- package/src/components/forms/EditorSheet.tsx +7 -2
- package/src/components/forms/__tests__/EditorSheet.spec.tsx +36 -0
- package/dist/chunk-UQFDOZVF.mjs.map +0 -1
- package/dist/chunk-WXTEAATG.js.map +0 -1
- /package/dist/{BlockNoteEditor-BHCNJ2JA.mjs.map → BlockNoteEditor-SQQF7OCY.mjs.map} +0 -0
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { ReactNode } from "react";
|
|
2
2
|
import { useTranslations } from "next-intl";
|
|
3
|
+
import { Loader2 } from "lucide-react";
|
|
3
4
|
import { Button } from "../../shadcnui";
|
|
4
5
|
|
|
5
6
|
type CommonEditorButtonsProps = {
|
|
@@ -22,6 +23,19 @@ export function CommonEditorButtons({
|
|
|
22
23
|
}: CommonEditorButtonsProps) {
|
|
23
24
|
const t = useTranslations();
|
|
24
25
|
|
|
26
|
+
const submitLabel: ReactNode = form.formState.isSubmitting ? (
|
|
27
|
+
<>
|
|
28
|
+
<Loader2 className="h-4 w-4 animate-spin" />
|
|
29
|
+
{t(`ui.buttons.saving`)}
|
|
30
|
+
</>
|
|
31
|
+
) : buttonTitle ? (
|
|
32
|
+
buttonTitle
|
|
33
|
+
) : isEdit ? (
|
|
34
|
+
t(`ui.buttons.confirm_update`)
|
|
35
|
+
) : (
|
|
36
|
+
t(`ui.buttons.confirm_create`)
|
|
37
|
+
);
|
|
38
|
+
|
|
25
39
|
if (centerButtons) {
|
|
26
40
|
return (
|
|
27
41
|
<div className="flex w-full items-center justify-between gap-x-2">
|
|
@@ -33,7 +47,7 @@ export function CommonEditorButtons({
|
|
|
33
47
|
|
|
34
48
|
{!hideSubmit ? (
|
|
35
49
|
<Button type="submit" disabled={form.formState.isSubmitting || disabled} data-testid={`modal-button-create`}>
|
|
36
|
-
{
|
|
50
|
+
{submitLabel}
|
|
37
51
|
</Button>
|
|
38
52
|
) : (
|
|
39
53
|
<div />
|
|
@@ -56,7 +70,7 @@ export function CommonEditorButtons({
|
|
|
56
70
|
|
|
57
71
|
{!hideSubmit && (
|
|
58
72
|
<Button type="submit" disabled={form.formState.isSubmitting || disabled} data-testid={`modal-button-create`}>
|
|
59
|
-
{
|
|
73
|
+
{submitLabel}
|
|
60
74
|
</Button>
|
|
61
75
|
)}
|
|
62
76
|
</div>
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
|
|
3
3
|
import { useTranslations } from "next-intl";
|
|
4
|
-
import { isValidElement, ReactElement, ReactNode, useCallback, useEffect, useRef } from "react";
|
|
4
|
+
import { isValidElement, ReactElement, ReactNode, useCallback, useEffect, useRef, useState } from "react";
|
|
5
5
|
import { FieldValues, UseFormReturn } from "react-hook-form";
|
|
6
6
|
import { PencilIcon } from "lucide-react";
|
|
7
7
|
import { ActionBarProvider, useIsInActionBar } from "../../contexts/ActionBarContext";
|
|
@@ -200,7 +200,12 @@ export function EditorSheet<T extends FieldValues>({
|
|
|
200
200
|
const hasBeenOpen = useRef(false);
|
|
201
201
|
// Fingerprint of the values the form was last seeded with, used to detect that
|
|
202
202
|
// the entity behind `onReset` has changed while the sheet was closed.
|
|
203
|
-
|
|
203
|
+
// An edit form starts seeded with the entity as it was at mount (the values its
|
|
204
|
+
// `useForm` defaults came from), so the FIRST open also notices an entity that
|
|
205
|
+
// changed since — e.g. content autosaved on the page — instead of showing the
|
|
206
|
+
// mount-time values and saving them back over the newer ones.
|
|
207
|
+
const [mountFingerprint] = useState(() => (isEdit ? JSON.stringify(onReset()) : undefined));
|
|
208
|
+
const seeded = useRef<string | undefined>(mountFingerprint);
|
|
204
209
|
|
|
205
210
|
useEffect(() => {
|
|
206
211
|
if (open) {
|
|
@@ -344,6 +344,42 @@ describe("EditorSheet", () => {
|
|
|
344
344
|
});
|
|
345
345
|
});
|
|
346
346
|
|
|
347
|
+
describe("edit form seeding", () => {
|
|
348
|
+
function EntityEditor({ name }: { name: string }) {
|
|
349
|
+
const form = useForm<TestValues>({ resolver: zodResolver(schema), defaultValues: { name } });
|
|
350
|
+
return (
|
|
351
|
+
<EditorSheet
|
|
352
|
+
form={form}
|
|
353
|
+
onSubmit={vi.fn().mockResolvedValue({ id: "123" })}
|
|
354
|
+
onReset={() => ({ name })}
|
|
355
|
+
entityType="Test Entity"
|
|
356
|
+
isEdit={true}
|
|
357
|
+
module={testModule}
|
|
358
|
+
>
|
|
359
|
+
<input {...form.register("name")} data-testid="name-input" />
|
|
360
|
+
</EditorSheet>
|
|
361
|
+
);
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
it("opens the first time with the entity as it is now, not as it was at mount", async () => {
|
|
365
|
+
const r = render(<EntityEditor name="Old" />);
|
|
366
|
+
// The page saved a newer value (e.g. autosaved content) before the sheet ever opened.
|
|
367
|
+
r.rerender(<EntityEditor name="New" />);
|
|
368
|
+
|
|
369
|
+
await userEvent.click(document.querySelector('[data-help="editor.edit"]') as HTMLElement);
|
|
370
|
+
|
|
371
|
+
expect(screen.getByTestId("name-input")).toHaveValue("New");
|
|
372
|
+
});
|
|
373
|
+
|
|
374
|
+
it("keeps the mount values on the first open when the entity did not change", async () => {
|
|
375
|
+
render(<EntityEditor name="Same" />);
|
|
376
|
+
|
|
377
|
+
await userEvent.click(document.querySelector('[data-help="editor.edit"]') as HTMLElement);
|
|
378
|
+
|
|
379
|
+
expect(screen.getByTestId("name-input")).toHaveValue("Same");
|
|
380
|
+
});
|
|
381
|
+
});
|
|
382
|
+
|
|
347
383
|
describe("Activity hide and reveal (back/forward)", () => {
|
|
348
384
|
it("uncontrolled sheet is closed and the form reset after Activity reveal", async () => {
|
|
349
385
|
const page = (mode: "visible" | "hidden") => (
|