@carlonicora/nextjs-jsonapi 3.20.0 → 3.21.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-CTRQ6JWE.mjs → BlockNoteEditor-CSLA3M32.mjs} +2 -2
- package/dist/{BlockNoteEditor-2WFPGK64.js → BlockNoteEditor-NRI2TZXY.js} +9 -9
- package/dist/{BlockNoteEditor-2WFPGK64.js.map → BlockNoteEditor-NRI2TZXY.js.map} +1 -1
- package/dist/billing/index.js +335 -335
- package/dist/billing/index.mjs +1 -1
- package/dist/{chunk-CJHBL5AN.mjs → chunk-HSVAW3DQ.mjs} +45 -19
- package/dist/chunk-HSVAW3DQ.mjs.map +1 -0
- package/dist/{chunk-IQMJAYCJ.js → chunk-U32IWQZM.js} +144 -118
- package/dist/chunk-U32IWQZM.js.map +1 -0
- package/dist/client/index.js +2 -2
- package/dist/client/index.mjs +1 -1
- package/dist/components/index.d.mts +7 -1
- package/dist/components/index.d.ts +7 -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/features/help/index.js +31 -31
- package/dist/features/help/index.mjs +1 -1
- package/dist/features/tokenusage/index.js +75 -75
- package/dist/features/tokenusage/index.mjs +1 -1
- package/package.json +1 -1
- package/src/components/tables/ContentListTable.tsx +86 -26
- package/src/components/tables/__tests__/ContentListTable.spec.tsx +133 -10
- package/src/shadcnui/ui/badge.tsx +2 -0
- package/dist/chunk-CJHBL5AN.mjs.map +0 -1
- package/dist/chunk-IQMJAYCJ.js.map +0 -1
- /package/dist/{BlockNoteEditor-CTRQ6JWE.mjs.map → BlockNoteEditor-CSLA3M32.mjs.map} +0 -0
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { render, screen } from "@testing-library/react";
|
|
2
|
-
import { describe, expect, it, vi } from "vitest";
|
|
1
|
+
import { fireEvent, render, screen } from "@testing-library/react";
|
|
2
|
+
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
|
3
3
|
import { ContentListTable } from "../ContentListTable";
|
|
4
4
|
|
|
5
5
|
// `ContentListTable` imports `useTableGenerator` from the `../../hooks` barrel,
|
|
@@ -7,20 +7,40 @@ import { ContentListTable } from "../ContentListTable";
|
|
|
7
7
|
// barrel (spreading the actual module so the other exports survive) is the same
|
|
8
8
|
// approach the sibling `ContentListTable.test.tsx` in this folder uses; one
|
|
9
9
|
// plain column is enough here.
|
|
10
|
+
// `mockColumns.expandToggle` switches the mocked name cell to a button that
|
|
11
|
+
// toggles row expansion (the `renderExpandedRow` suite), plus a second column so
|
|
12
|
+
// the detail row's colSpan is checked against more than one column.
|
|
13
|
+
const mockColumns = vi.hoisted(() => ({ expandToggle: false }));
|
|
14
|
+
|
|
10
15
|
vi.mock("../../../hooks", async () => {
|
|
11
16
|
const actual = await vi.importActual("../../../hooks");
|
|
12
17
|
return {
|
|
13
18
|
...actual,
|
|
14
19
|
useTableGenerator: vi.fn((_type: any, params: any) => ({
|
|
15
20
|
data: params.data.map((item: any) => ({ ...item, jsonApiData: item })),
|
|
16
|
-
columns:
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
21
|
+
columns: mockColumns.expandToggle
|
|
22
|
+
? [
|
|
23
|
+
{
|
|
24
|
+
id: "name",
|
|
25
|
+
header: "Name",
|
|
26
|
+
accessorKey: "name",
|
|
27
|
+
cell: ({ row }: any) => <button onClick={row.getToggleExpandedHandler()}>{row.original.name}</button>,
|
|
28
|
+
},
|
|
29
|
+
{
|
|
30
|
+
id: "id",
|
|
31
|
+
header: "Id",
|
|
32
|
+
accessorKey: "id",
|
|
33
|
+
cell: ({ row }: any) => row.original.id,
|
|
34
|
+
},
|
|
35
|
+
]
|
|
36
|
+
: [
|
|
37
|
+
{
|
|
38
|
+
id: "name",
|
|
39
|
+
header: "Name",
|
|
40
|
+
accessorKey: "name",
|
|
41
|
+
cell: ({ row }: any) => row.original.name,
|
|
42
|
+
},
|
|
43
|
+
],
|
|
24
44
|
})),
|
|
25
45
|
};
|
|
26
46
|
});
|
|
@@ -60,3 +80,106 @@ describe("ContentListTable pagination footer", () => {
|
|
|
60
80
|
expect(screen.getByText("Row one")).toBeInTheDocument();
|
|
61
81
|
});
|
|
62
82
|
});
|
|
83
|
+
|
|
84
|
+
describe("ContentListTable renderExpandedRow", () => {
|
|
85
|
+
beforeEach(() => {
|
|
86
|
+
mockColumns.expandToggle = true;
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
afterEach(() => {
|
|
90
|
+
mockColumns.expandToggle = false;
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
// The callback receives `row.original.jsonApiData`; the mocked generator sets
|
|
94
|
+
// that to the raw data item, so `d` is `{ id, name }`.
|
|
95
|
+
const renderExpandedRow = (d: any) => `Detail for ${d.name}`;
|
|
96
|
+
|
|
97
|
+
it("renders no detail row until a row is expanded", () => {
|
|
98
|
+
render(
|
|
99
|
+
<ContentListTable
|
|
100
|
+
data={baseData}
|
|
101
|
+
fields={["name", "id"]}
|
|
102
|
+
tableGeneratorType={mockModule}
|
|
103
|
+
renderExpandedRow={renderExpandedRow}
|
|
104
|
+
/>,
|
|
105
|
+
);
|
|
106
|
+
expect(screen.queryByTestId("content-list-table-expanded-row")).toBeNull();
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
it("renders the callback output in a full-width row after toggling", () => {
|
|
110
|
+
render(
|
|
111
|
+
<ContentListTable
|
|
112
|
+
data={baseData}
|
|
113
|
+
fields={["name", "id"]}
|
|
114
|
+
tableGeneratorType={mockModule}
|
|
115
|
+
renderExpandedRow={renderExpandedRow}
|
|
116
|
+
/>,
|
|
117
|
+
);
|
|
118
|
+
fireEvent.click(screen.getByText("Row one"));
|
|
119
|
+
const detailRow = screen.getByTestId("content-list-table-expanded-row");
|
|
120
|
+
expect(detailRow).toHaveTextContent("Detail for Row one");
|
|
121
|
+
const cells = detailRow.querySelectorAll("td");
|
|
122
|
+
expect(cells).toHaveLength(1);
|
|
123
|
+
expect(cells[0].getAttribute("colspan")).toBe("2");
|
|
124
|
+
|
|
125
|
+
fireEvent.click(screen.getByText("Row one"));
|
|
126
|
+
expect(screen.queryByTestId("content-list-table-expanded-row")).toBeNull();
|
|
127
|
+
});
|
|
128
|
+
|
|
129
|
+
it("keeps the expansion on the record, not on the row position, when the rows change", () => {
|
|
130
|
+
const twoRows = {
|
|
131
|
+
...baseData,
|
|
132
|
+
data: [
|
|
133
|
+
{ id: "1", name: "Row one" },
|
|
134
|
+
{ id: "2", name: "Row two" },
|
|
135
|
+
],
|
|
136
|
+
};
|
|
137
|
+
const { rerender } = render(
|
|
138
|
+
<ContentListTable
|
|
139
|
+
data={twoRows}
|
|
140
|
+
fields={["name", "id"]}
|
|
141
|
+
tableGeneratorType={mockModule}
|
|
142
|
+
renderExpandedRow={renderExpandedRow}
|
|
143
|
+
/>,
|
|
144
|
+
);
|
|
145
|
+
fireEvent.click(screen.getByText("Row one"));
|
|
146
|
+
expect(screen.getByTestId("content-list-table-expanded-row")).toHaveTextContent("Detail for Row one");
|
|
147
|
+
|
|
148
|
+
// A search narrows the list: "Row two" now sits where "Row one" was.
|
|
149
|
+
rerender(
|
|
150
|
+
<ContentListTable
|
|
151
|
+
data={{ ...baseData, data: [{ id: "2", name: "Row two" }] }}
|
|
152
|
+
fields={["name", "id"]}
|
|
153
|
+
tableGeneratorType={mockModule}
|
|
154
|
+
renderExpandedRow={renderExpandedRow}
|
|
155
|
+
/>,
|
|
156
|
+
);
|
|
157
|
+
expect(screen.queryByTestId("content-list-table-expanded-row")).toBeNull();
|
|
158
|
+
});
|
|
159
|
+
|
|
160
|
+
it("rows cannot expand without the prop", () => {
|
|
161
|
+
render(<ContentListTable data={baseData} fields={["name", "id"]} tableGeneratorType={mockModule} />);
|
|
162
|
+
fireEvent.click(screen.getByText("Row one"));
|
|
163
|
+
expect(screen.queryByTestId("content-list-table-expanded-row")).toBeNull();
|
|
164
|
+
expect(screen.queryByText("Detail for Row one")).toBeNull();
|
|
165
|
+
});
|
|
166
|
+
|
|
167
|
+
it("grouped rows also expand", () => {
|
|
168
|
+
render(
|
|
169
|
+
<ContentListTable
|
|
170
|
+
data={baseData}
|
|
171
|
+
fields={["name", "id"]}
|
|
172
|
+
tableGeneratorType={mockModule}
|
|
173
|
+
groupBy="name"
|
|
174
|
+
renderExpandedRow={renderExpandedRow}
|
|
175
|
+
/>,
|
|
176
|
+
);
|
|
177
|
+
fireEvent.click(screen.getByRole("button", { name: "Row one" }));
|
|
178
|
+
const detailRow = screen.getByTestId("content-list-table-expanded-row");
|
|
179
|
+
expect(detailRow).toHaveTextContent("Detail for Row one");
|
|
180
|
+
// The detail row sits directly under the grouped data row, after the group header.
|
|
181
|
+
const dataRow = screen.getByRole("button", { name: "Row one" }).closest("tr")!;
|
|
182
|
+
expect(dataRow.nextElementSibling).toBe(detailRow);
|
|
183
|
+
expect(dataRow.previousElementSibling).toHaveTextContent("Row one");
|
|
184
|
+
});
|
|
185
|
+
});
|
|
@@ -25,6 +25,8 @@ const badgeVariants = cva(
|
|
|
25
25
|
softGray: "bg-gray-500/10 text-gray-700 dark:bg-gray-500/15 dark:text-gray-400",
|
|
26
26
|
softOrange: "bg-orange-500/10 text-orange-700 dark:bg-orange-500/15 dark:text-orange-400",
|
|
27
27
|
softAmber: "bg-amber-500/10 text-amber-700 dark:bg-amber-500/15 dark:text-amber-400",
|
|
28
|
+
softEmerald: "bg-emerald-500/10 text-emerald-700 dark:bg-emerald-500/15 dark:text-emerald-400",
|
|
29
|
+
softPurple: "bg-purple-500/10 text-purple-700 dark:bg-purple-500/15 dark:text-purple-400",
|
|
28
30
|
blue: "bg-sky-500 text-primary-foreground [a]:hover:bg-sky-500/80",
|
|
29
31
|
green: "bg-emerald-500 text-primary-foreground [a]:hover:bg-emerald-500/80",
|
|
30
32
|
red: "bg-red-500 text-primary-foreground [a]:hover:bg-red-500/80",
|