@pautena/react-design-system 0.0.1 → 0.1.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/.prettierignore +2 -1
- package/babel.config.js +10 -0
- package/dist/cjs/index.js +28 -28
- package/dist/cjs/index.js.map +1 -1
- package/dist/cjs/types/components/app-bar/app-bar.types.d.ts +2 -1
- package/dist/cjs/types/components/content/content.d.ts +2 -0
- package/dist/cjs/types/components/content/content.types.d.ts +4 -0
- package/dist/cjs/types/components/content/index.d.ts +2 -0
- package/dist/cjs/types/components/header/header.d.ts +2 -61
- package/dist/cjs/types/components/header/header.types.d.ts +55 -0
- package/dist/cjs/types/components/header/index.d.ts +1 -0
- package/dist/cjs/types/components/index.d.ts +1 -0
- package/dist/cjs/types/components/tab/index.d.ts +0 -1
- package/dist/cjs/types/components/tab/tab-card/tab-card.d.ts +1 -2
- package/dist/cjs/types/components/table-list/table-list.d.ts +4 -7
- package/dist/cjs/types/generators/generators.mock.d.ts +22 -1
- package/dist/cjs/types/generators/generators.model.d.ts +5 -1
- package/dist/cjs/types/generators/model-form/model-form.d.ts +5 -5
- package/dist/cjs/types/generators/model-router/model-router.d.ts +4 -35
- package/dist/cjs/types/generators/model-router/model-router.types.d.ts +8 -0
- package/dist/cjs/types/generators/model-router/screens/add-screen.d.ts +16 -2
- package/dist/cjs/types/generators/model-router/screens/details-screen.d.ts +20 -2
- package/dist/cjs/types/generators/model-router/screens/list-screen.d.ts +30 -2
- package/dist/cjs/types/generators/model-router/screens/screens.types.d.ts +11 -0
- package/dist/cjs/types/generators/model-router/screens/update-screen.d.ts +29 -2
- package/dist/cjs/types/generators/model-router/stories/templates.d.ts +23 -0
- package/dist/cjs/types/generators/object-details/object-details.d.ts +4 -4
- package/dist/cjs/types/layouts/app-bar-with-drawer-layout/app-bar-with-drawer-layout.d.ts +5 -8
- package/dist/cjs/types/layouts/header-layout/header-layout.d.ts +4 -5
- package/dist/cjs/types/layouts/index.d.ts +1 -6
- package/dist/cjs/types/providers/index.d.ts +1 -0
- package/dist/cjs/types/providers/notification-center/index.d.ts +1 -0
- package/dist/cjs/types/providers/tab-provider/index.d.ts +2 -0
- package/dist/cjs/types/providers/tab-provider/tab-provider.context.d.ts +4 -0
- package/dist/cjs/types/providers/tab-provider/tab-provider.provider.d.ts +6 -0
- package/dist/cjs/types/utils/theme.d.ts +7 -4
- package/dist/esm/index.js +28 -28
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/types/components/app-bar/app-bar.types.d.ts +2 -1
- package/dist/esm/types/components/content/content.d.ts +2 -0
- package/dist/esm/types/components/content/content.types.d.ts +4 -0
- package/dist/esm/types/components/content/index.d.ts +2 -0
- package/dist/esm/types/components/header/header.d.ts +2 -61
- package/dist/esm/types/components/header/header.types.d.ts +55 -0
- package/dist/esm/types/components/header/index.d.ts +1 -0
- package/dist/esm/types/components/index.d.ts +1 -0
- package/dist/esm/types/components/tab/index.d.ts +0 -1
- package/dist/esm/types/components/tab/tab-card/tab-card.d.ts +1 -2
- package/dist/esm/types/components/table-list/table-list.d.ts +4 -7
- package/dist/esm/types/generators/generators.mock.d.ts +22 -1
- package/dist/esm/types/generators/generators.model.d.ts +5 -1
- package/dist/esm/types/generators/model-form/model-form.d.ts +5 -5
- package/dist/esm/types/generators/model-router/model-router.d.ts +4 -35
- package/dist/esm/types/generators/model-router/model-router.types.d.ts +8 -0
- package/dist/esm/types/generators/model-router/screens/add-screen.d.ts +16 -2
- package/dist/esm/types/generators/model-router/screens/details-screen.d.ts +20 -2
- package/dist/esm/types/generators/model-router/screens/list-screen.d.ts +30 -2
- package/dist/esm/types/generators/model-router/screens/screens.types.d.ts +11 -0
- package/dist/esm/types/generators/model-router/screens/update-screen.d.ts +29 -2
- package/dist/esm/types/generators/model-router/stories/templates.d.ts +23 -0
- package/dist/esm/types/generators/object-details/object-details.d.ts +4 -4
- package/dist/esm/types/layouts/app-bar-with-drawer-layout/app-bar-with-drawer-layout.d.ts +5 -8
- package/dist/esm/types/layouts/header-layout/header-layout.d.ts +4 -5
- package/dist/esm/types/layouts/index.d.ts +1 -6
- package/dist/esm/types/providers/index.d.ts +1 -0
- package/dist/esm/types/providers/notification-center/index.d.ts +1 -0
- package/dist/esm/types/providers/tab-provider/index.d.ts +2 -0
- package/dist/esm/types/providers/tab-provider/tab-provider.context.d.ts +4 -0
- package/dist/esm/types/providers/tab-provider/tab-provider.provider.d.ts +6 -0
- package/dist/esm/types/utils/theme.d.ts +7 -4
- package/dist/index.d.ts +146 -122
- package/jest.config.js +3 -0
- package/package.json +3 -1
- package/rollup.config.js +12 -0
- package/src/components/app-bar/app-bar.types.ts +2 -1
- package/src/components/content/content.stories.tsx +23 -0
- package/src/components/content/content.test.tsx +26 -0
- package/src/components/content/content.tsx +11 -0
- package/src/components/content/content.types.ts +5 -0
- package/src/components/content/index.ts +2 -0
- package/src/components/drawer-item/drawer-item.tsx +2 -0
- package/src/components/header/header.test.tsx +18 -16
- package/src/components/header/header.tsx +5 -69
- package/src/components/header/header.types.ts +61 -0
- package/src/components/header/index.ts +1 -0
- package/src/components/index.ts +1 -0
- package/src/components/tab/index.ts +0 -1
- package/src/components/tab/tab-card/tab-card.dummy.tsx +14 -11
- package/src/components/tab/tab-card/tab-card.test.tsx +2 -2
- package/src/components/tab/tab-card/tab-card.tsx +11 -14
- package/src/components/tab/tab-panel/tab-panel.test.tsx +4 -4
- package/src/components/tab/tab-panel/tab-panel.tsx +2 -2
- package/src/components/table/enhanced-table/enhanced-table.tsx +2 -2
- package/src/components/table-list/table-list.test.tsx +3 -2
- package/src/components/table-list/table-list.tsx +4 -8
- package/src/components/value-displays/group-value-card/group-value-card.tsx +2 -4
- package/src/generators/generators.mock.ts +25 -2
- package/src/generators/generators.model.ts +6 -1
- package/src/generators/model-form/model-form.test.tsx +5 -3
- package/src/generators/model-form/model-form.tsx +15 -15
- package/src/generators/model-router/model-router.test.tsx +72 -39
- package/src/generators/model-router/model-router.tsx +16 -41
- package/src/generators/model-router/model-router.types.ts +14 -0
- package/src/generators/model-router/screens/add-screen.tsx +53 -36
- package/src/generators/model-router/screens/details-screen.tsx +52 -43
- package/src/generators/model-router/screens/list-screen.tsx +89 -60
- package/src/generators/model-router/screens/screens.types.ts +13 -0
- package/src/generators/model-router/screens/update-screen.tsx +76 -42
- package/src/generators/model-router/stories/details-screen.stories.tsx +38 -0
- package/src/generators/model-router/stories/list-screen.stories.tsx +45 -0
- package/src/generators/model-router/stories/model-router.stories.tsx +164 -0
- package/src/generators/model-router/stories/templates.tsx +39 -0
- package/src/generators/object-details/object-details.tsx +18 -12
- package/src/layouts/app-bar-with-drawer-layout/app-bar-with-drawer-layout.stories.tsx +7 -8
- package/src/layouts/app-bar-with-drawer-layout/app-bar-with-drawer-layout.test.tsx +30 -0
- package/src/layouts/app-bar-with-drawer-layout/app-bar-with-drawer-layout.tsx +10 -7
- package/src/layouts/header-layout/header-layout.stories.tsx +158 -22
- package/src/layouts/header-layout/header-layout.test.tsx +37 -0
- package/src/layouts/header-layout/header-layout.tsx +12 -13
- package/src/layouts/index.ts +1 -6
- package/src/providers/index.ts +1 -0
- package/src/providers/notification-center/index.ts +1 -0
- package/src/providers/tab-provider/index.ts +2 -0
- package/src/providers/tab-provider/tab-provider.context.ts +8 -0
- package/src/providers/tab-provider/tab-provider.provider.tsx +13 -0
- package/src/storybook.tsx +41 -7
- package/src/tests/assertions.ts +4 -0
- package/src/tests/components.tsx +1 -1
- package/src/utils/theme.ts +7 -2
- package/tsconfig.json +8 -10
- package/tsconfig.rollup.json +2 -0
- package/dist/cjs/types/components/tab/tab.context.d.ts +0 -4
- package/dist/cjs/types/layouts/data-table-layout/data-table-layout.d.ts +0 -12
- package/dist/cjs/types/layouts/data-table-layout/index.d.ts +0 -1
- package/dist/cjs/types/layouts/details-layout/details-layout.d.ts +0 -12
- package/dist/cjs/types/layouts/details-layout/index.d.ts +0 -1
- package/dist/cjs/types/layouts/form-layout/form-layout.d.ts +0 -8
- package/dist/cjs/types/layouts/form-layout/index.d.ts +0 -1
- package/dist/cjs/types/layouts/list-layout/index.d.ts +0 -1
- package/dist/cjs/types/layouts/list-layout/list-layout.d.ts +0 -8
- package/dist/cjs/types/layouts/tab-layout/index.d.ts +0 -1
- package/dist/cjs/types/layouts/tab-layout/tab-layout.d.ts +0 -7
- package/dist/esm/types/components/tab/tab.context.d.ts +0 -4
- package/dist/esm/types/layouts/data-table-layout/data-table-layout.d.ts +0 -12
- package/dist/esm/types/layouts/data-table-layout/index.d.ts +0 -1
- package/dist/esm/types/layouts/details-layout/details-layout.d.ts +0 -12
- package/dist/esm/types/layouts/details-layout/index.d.ts +0 -1
- package/dist/esm/types/layouts/form-layout/form-layout.d.ts +0 -8
- package/dist/esm/types/layouts/form-layout/index.d.ts +0 -1
- package/dist/esm/types/layouts/list-layout/index.d.ts +0 -1
- package/dist/esm/types/layouts/list-layout/list-layout.d.ts +0 -8
- package/dist/esm/types/layouts/tab-layout/index.d.ts +0 -1
- package/dist/esm/types/layouts/tab-layout/tab-layout.d.ts +0 -7
- package/src/components/tab/tab.context.ts +0 -5
- package/src/generators/model-router/model-router.stories.tsx +0 -160
- package/src/layouts/data-table-layout/data-table-layout.stories.tsx +0 -94
- package/src/layouts/data-table-layout/data-table-layout.tsx +0 -30
- package/src/layouts/data-table-layout/index.ts +0 -1
- package/src/layouts/details-layout/details-layout.stories.tsx +0 -81
- package/src/layouts/details-layout/details-layout.tsx +0 -33
- package/src/layouts/details-layout/index.ts +0 -1
- package/src/layouts/form-layout/form-layout.stories.tsx +0 -65
- package/src/layouts/form-layout/form-layout.tsx +0 -18
- package/src/layouts/form-layout/index.ts +0 -1
- package/src/layouts/list-layout/index.ts +0 -1
- package/src/layouts/list-layout/list-layout.stories.tsx +0 -102
- package/src/layouts/list-layout/list-layout.tsx +0 -36
- package/src/layouts/tab-layout/index.ts +0 -1
- package/src/layouts/tab-layout/tab-layout.stories.tsx +0 -88
- package/src/layouts/tab-layout/tab-layout.tsx +0 -11
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React from "react";
|
|
2
|
-
import { DummyModelRouter } from "./model-router.stories";
|
|
2
|
+
import { DummyModelRouter } from "./stories/model-router.stories";
|
|
3
3
|
import {
|
|
4
4
|
expectModelFieldInputExist,
|
|
5
5
|
expectProgressIndicator,
|
|
@@ -9,11 +9,12 @@ import {
|
|
|
9
9
|
TestRouter,
|
|
10
10
|
expectModelFieldValue,
|
|
11
11
|
expectModelFieldInputValue,
|
|
12
|
-
} from "
|
|
12
|
+
} from "~/tests";
|
|
13
13
|
import userEvent from "@testing-library/user-event";
|
|
14
14
|
import { getRandomItem } from "../../utils";
|
|
15
15
|
import { Model } from "../generators.model";
|
|
16
|
-
import { createModelInstance } from "../generators.mock";
|
|
16
|
+
import { createModelInstance, MockInstance, mockModel } from "../generators.mock";
|
|
17
|
+
import { NotificationCenterProvider } from "../../providers";
|
|
17
18
|
|
|
18
19
|
const REQUEST_TIMEOUT = 20;
|
|
19
20
|
|
|
@@ -39,7 +40,7 @@ describe("ModelRouter", () => {
|
|
|
39
40
|
name: `Edit ${id}`,
|
|
40
41
|
level: 1,
|
|
41
42
|
}),
|
|
42
|
-
expectListItems: async ({ data, model }: { data:
|
|
43
|
+
expectListItems: async ({ data, model }: { data: MockInstance[]; model: Model }) => {
|
|
43
44
|
for (let i = 0; i < model.fields.length; ++i) {
|
|
44
45
|
const { id, listable } = model.fields[i];
|
|
45
46
|
|
|
@@ -48,10 +49,10 @@ describe("ModelRouter", () => {
|
|
|
48
49
|
}
|
|
49
50
|
}
|
|
50
51
|
},
|
|
51
|
-
expectMenuOption: async ({ id }: { id:
|
|
52
|
+
expectMenuOption: async ({ id }: { id: string }) => {
|
|
52
53
|
await screen.findByTestId(`options-${id}`);
|
|
53
54
|
},
|
|
54
|
-
expectSubmitInstanceCall: (mockFn: jest.Mock, instance:
|
|
55
|
+
expectSubmitInstanceCall: (mockFn: jest.Mock, instance: MockInstance) => {
|
|
55
56
|
expect(mockFn).toHaveBeenCalledTimes(1);
|
|
56
57
|
expect(mockFn).toHaveBeenCalledWith({
|
|
57
58
|
id: instance.id,
|
|
@@ -81,14 +82,14 @@ describe("ModelRouter", () => {
|
|
|
81
82
|
navigateToAddScreen: async () => {
|
|
82
83
|
await userEvent.click(screen.getByRole("button", { name: /add/i }));
|
|
83
84
|
},
|
|
84
|
-
navigateToUpdateScreen: async ({ id }: { id:
|
|
85
|
+
navigateToUpdateScreen: async ({ id }: { id: string }) => {
|
|
85
86
|
await actions.openItemOptions({ id });
|
|
86
87
|
await userEvent.click(screen.getByRole("menuitem", { name: /edit/i }));
|
|
87
88
|
},
|
|
88
89
|
navigateToDetailScreen: async ({ name }: { name: string }) => {
|
|
89
90
|
await userEvent.click(await screen.findByRole("cell", { name }));
|
|
90
91
|
},
|
|
91
|
-
openItemOptions: async ({ id }: { id:
|
|
92
|
+
openItemOptions: async ({ id }: { id: string }) => {
|
|
92
93
|
await userEvent.click(await screen.findByTestId(`options-${id}`));
|
|
93
94
|
},
|
|
94
95
|
fullfillModelForm: async ({
|
|
@@ -100,7 +101,7 @@ describe("ModelRouter", () => {
|
|
|
100
101
|
submit?: boolean;
|
|
101
102
|
clear?: boolean;
|
|
102
103
|
}) => {
|
|
103
|
-
const instance = createModelInstance(model);
|
|
104
|
+
const instance = createModelInstance<MockInstance>(model);
|
|
104
105
|
|
|
105
106
|
const idElement = screen.getByRole("textbox", { name: "Id" });
|
|
106
107
|
const firstNameElement = screen.getByRole("textbox", { name: /first name/i });
|
|
@@ -167,26 +168,32 @@ describe("ModelRouter", () => {
|
|
|
167
168
|
router = "memory",
|
|
168
169
|
screen = "initial",
|
|
169
170
|
}: { router?: TestRouter; screen?: "initial" | "add" | "details" | "update" } = {}) => {
|
|
170
|
-
const
|
|
171
|
-
const
|
|
171
|
+
const onRequestList = jest.fn();
|
|
172
|
+
const onRequestItem = jest.fn();
|
|
173
|
+
const onSubmitNewItem = jest.fn();
|
|
174
|
+
const onRequestUpdateItem = jest.fn();
|
|
172
175
|
const onSubmitUpdate = jest.fn();
|
|
173
176
|
const onRequestDelete = jest.fn();
|
|
174
177
|
const args = DummyModelRouter.args;
|
|
175
178
|
const instance = render(
|
|
176
|
-
<
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
179
|
+
<NotificationCenterProvider>
|
|
180
|
+
<DummyModelRouter
|
|
181
|
+
{...args}
|
|
182
|
+
requestTimeout={REQUEST_TIMEOUT}
|
|
183
|
+
onRequestListAction={onRequestList}
|
|
184
|
+
onRequestItem={onRequestItem}
|
|
185
|
+
onSubmitNewItemAction={onSubmitNewItem}
|
|
186
|
+
onRequestUpdateItemAction={onRequestUpdateItem}
|
|
187
|
+
onSubmitUpdateAction={onSubmitUpdate}
|
|
188
|
+
onRequestDeleteAction={onRequestDelete}
|
|
189
|
+
/>
|
|
190
|
+
</NotificationCenterProvider>,
|
|
184
191
|
{
|
|
185
192
|
router,
|
|
186
193
|
},
|
|
187
194
|
);
|
|
188
195
|
|
|
189
|
-
const randomItem = getRandomItem
|
|
196
|
+
const randomItem = getRandomItem(args.initialData);
|
|
190
197
|
|
|
191
198
|
if (screen === "add") {
|
|
192
199
|
await actions.navigateToAddScreen();
|
|
@@ -199,10 +206,12 @@ describe("ModelRouter", () => {
|
|
|
199
206
|
return {
|
|
200
207
|
...instance,
|
|
201
208
|
data: args.initialData,
|
|
202
|
-
model:
|
|
209
|
+
model: mockModel,
|
|
203
210
|
randomItem,
|
|
204
|
-
|
|
205
|
-
|
|
211
|
+
onRequestList,
|
|
212
|
+
onRequestItem,
|
|
213
|
+
onSubmitNewItem,
|
|
214
|
+
onRequestUpdateItem,
|
|
206
215
|
onSubmitUpdate,
|
|
207
216
|
onRequestDelete,
|
|
208
217
|
};
|
|
@@ -225,7 +234,7 @@ describe("ModelRouter", () => {
|
|
|
225
234
|
|
|
226
235
|
it("would render the update screen if we navigate there", async () => {
|
|
227
236
|
const { data } = await renderComponent();
|
|
228
|
-
const { item } = getRandomItem<
|
|
237
|
+
const { item } = getRandomItem<MockInstance>(data);
|
|
229
238
|
const { id } = item;
|
|
230
239
|
|
|
231
240
|
await actions.navigateToUpdateScreen({ id });
|
|
@@ -237,7 +246,7 @@ describe("ModelRouter", () => {
|
|
|
237
246
|
const { data } = await renderComponent();
|
|
238
247
|
const {
|
|
239
248
|
item: { id, firstName },
|
|
240
|
-
} = getRandomItem<
|
|
249
|
+
} = getRandomItem<MockInstance>(data);
|
|
241
250
|
|
|
242
251
|
await actions.navigateToDetailScreen({ name: firstName });
|
|
243
252
|
|
|
@@ -264,7 +273,7 @@ describe("ModelRouter", () => {
|
|
|
264
273
|
const { history, data } = await renderComponent({ router: "router" });
|
|
265
274
|
const {
|
|
266
275
|
item: { id },
|
|
267
|
-
} = getRandomItem<
|
|
276
|
+
} = getRandomItem<MockInstance>(data);
|
|
268
277
|
|
|
269
278
|
await actions.navigateToUpdateScreen({ id });
|
|
270
279
|
|
|
@@ -275,7 +284,7 @@ describe("ModelRouter", () => {
|
|
|
275
284
|
const { history, data } = await renderComponent({ router: "router" });
|
|
276
285
|
const {
|
|
277
286
|
item: { id, firstName },
|
|
278
|
-
} = getRandomItem<
|
|
287
|
+
} = getRandomItem<MockInstance>(data);
|
|
279
288
|
|
|
280
289
|
await actions.navigateToDetailScreen({ name: firstName });
|
|
281
290
|
|
|
@@ -284,10 +293,10 @@ describe("ModelRouter", () => {
|
|
|
284
293
|
});
|
|
285
294
|
|
|
286
295
|
describe("list screen", () => {
|
|
287
|
-
it("would call
|
|
288
|
-
const {
|
|
296
|
+
it("would call onRequestList when is mounted", async () => {
|
|
297
|
+
const { onRequestList } = await renderComponent();
|
|
289
298
|
|
|
290
|
-
expect(
|
|
299
|
+
expect(onRequestList).toHaveBeenCalledTimes(1);
|
|
291
300
|
});
|
|
292
301
|
|
|
293
302
|
it("would render a loading indicator until the data is ready", async () => {
|
|
@@ -334,7 +343,7 @@ describe("ModelRouter", () => {
|
|
|
334
343
|
const { data, history } = await renderComponent({ router: "router" });
|
|
335
344
|
const {
|
|
336
345
|
item: { id, firstName },
|
|
337
|
-
} = getRandomItem<
|
|
346
|
+
} = getRandomItem<MockInstance>(data);
|
|
338
347
|
|
|
339
348
|
await userEvent.click(await screen.findByRole("cell", { name: firstName }));
|
|
340
349
|
|
|
@@ -346,7 +355,7 @@ describe("ModelRouter", () => {
|
|
|
346
355
|
const { data } = await renderComponent();
|
|
347
356
|
|
|
348
357
|
for (let i = 0; i < data.length; ++i) {
|
|
349
|
-
const id =
|
|
358
|
+
const id = data[i].id;
|
|
350
359
|
await assertions.expectMenuOption({ id });
|
|
351
360
|
}
|
|
352
361
|
});
|
|
@@ -355,7 +364,7 @@ describe("ModelRouter", () => {
|
|
|
355
364
|
const { data } = await renderComponent({ router: "router" });
|
|
356
365
|
const {
|
|
357
366
|
item: { id },
|
|
358
|
-
} = getRandomItem<
|
|
367
|
+
} = getRandomItem<MockInstance>(data);
|
|
359
368
|
|
|
360
369
|
await actions.openItemOptions({ id });
|
|
361
370
|
|
|
@@ -366,7 +375,7 @@ describe("ModelRouter", () => {
|
|
|
366
375
|
const { data } = await renderComponent({ router: "router" });
|
|
367
376
|
const {
|
|
368
377
|
item: { id },
|
|
369
|
-
} = getRandomItem<
|
|
378
|
+
} = getRandomItem<MockInstance>(data);
|
|
370
379
|
|
|
371
380
|
await actions.openItemOptions({ id });
|
|
372
381
|
|
|
@@ -417,11 +426,11 @@ describe("ModelRouter", () => {
|
|
|
417
426
|
});
|
|
418
427
|
|
|
419
428
|
it("would make a request when the form is submitted", async () => {
|
|
420
|
-
const {
|
|
429
|
+
const { onSubmitNewItem, model } = await renderComponent({ screen: "add" });
|
|
421
430
|
|
|
422
431
|
const newInstance = await actions.fullfillModelForm({ model, submit: true });
|
|
423
432
|
|
|
424
|
-
assertions.expectSubmitInstanceCall(
|
|
433
|
+
assertions.expectSubmitInstanceCall(onSubmitNewItem, newInstance);
|
|
425
434
|
});
|
|
426
435
|
|
|
427
436
|
it("would show a loading indicator when the request is in progress", async () => {
|
|
@@ -480,6 +489,18 @@ describe("ModelRouter", () => {
|
|
|
480
489
|
await assertions.expectListScreen();
|
|
481
490
|
});
|
|
482
491
|
|
|
492
|
+
it("would call onRequestItem when is mounted", async () => {
|
|
493
|
+
const {
|
|
494
|
+
onRequestItem,
|
|
495
|
+
randomItem: {
|
|
496
|
+
item: { id },
|
|
497
|
+
},
|
|
498
|
+
} = await renderComponent({ screen: "details" });
|
|
499
|
+
|
|
500
|
+
expect(onRequestItem).toHaveBeenCalledTimes(1);
|
|
501
|
+
expect(onRequestItem).toHaveBeenCalledWith(id);
|
|
502
|
+
});
|
|
503
|
+
|
|
483
504
|
it("would show a loading indicator when the request is in progress", async () => {
|
|
484
505
|
await renderComponent({ screen: "details" });
|
|
485
506
|
|
|
@@ -542,6 +563,18 @@ describe("ModelRouter", () => {
|
|
|
542
563
|
await assertions.expectListScreen();
|
|
543
564
|
});
|
|
544
565
|
|
|
566
|
+
it("would make a request to retrive the instance to update", async () => {
|
|
567
|
+
const {
|
|
568
|
+
onRequestUpdateItem,
|
|
569
|
+
randomItem: {
|
|
570
|
+
item: { id },
|
|
571
|
+
},
|
|
572
|
+
} = await renderComponent({ screen: "update" });
|
|
573
|
+
|
|
574
|
+
expect(onRequestUpdateItem).toHaveBeenCalledTimes(1);
|
|
575
|
+
expect(onRequestUpdateItem).toHaveBeenCalledWith(id);
|
|
576
|
+
});
|
|
577
|
+
|
|
545
578
|
it("would show a loading indicator while the instance is requested", async () => {
|
|
546
579
|
await renderComponent({ screen: "update" });
|
|
547
580
|
|
|
@@ -591,7 +624,7 @@ describe("ModelRouter", () => {
|
|
|
591
624
|
it("would make a request when we try to delete an option", async () => {
|
|
592
625
|
const { data, onRequestDelete } = await renderComponent();
|
|
593
626
|
|
|
594
|
-
const { item } = getRandomItem<
|
|
627
|
+
const { item } = getRandomItem<MockInstance>(data);
|
|
595
628
|
const { id, firstName } = item;
|
|
596
629
|
|
|
597
630
|
await screen.findByRole("cell", { name: firstName });
|
|
@@ -607,7 +640,7 @@ describe("ModelRouter", () => {
|
|
|
607
640
|
it("would show a loading indicator while the request is in progress", async () => {
|
|
608
641
|
const { data } = await renderComponent();
|
|
609
642
|
|
|
610
|
-
const { item } = getRandomItem<
|
|
643
|
+
const { item } = getRandomItem<MockInstance>(data);
|
|
611
644
|
const { id, firstName } = item;
|
|
612
645
|
|
|
613
646
|
await screen.findByRole("cell", { name: firstName });
|
|
@@ -619,7 +652,7 @@ describe("ModelRouter", () => {
|
|
|
619
652
|
|
|
620
653
|
it("would remove the item from the list when the request finish", async () => {
|
|
621
654
|
const { data } = await renderComponent();
|
|
622
|
-
const { item } = getRandomItem<
|
|
655
|
+
const { item } = getRandomItem<MockInstance>(data);
|
|
623
656
|
const { id, firstName } = item;
|
|
624
657
|
|
|
625
658
|
await screen.findByRole("cell", { name: firstName });
|
|
@@ -1,48 +1,23 @@
|
|
|
1
1
|
import React from "react";
|
|
2
2
|
import { Routes, Route } from "react-router-dom";
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
3
|
+
import { BasicModelInstance } from "../generators.model";
|
|
4
|
+
import {
|
|
5
|
+
AddScreen,
|
|
6
|
+
AddScreenProps,
|
|
7
|
+
DetailsScreen,
|
|
8
|
+
DetailsScreenProps,
|
|
9
|
+
ListScreen,
|
|
10
|
+
ListScreenProps,
|
|
11
|
+
UpdateScreen,
|
|
12
|
+
UpdateScreenProps,
|
|
13
|
+
} from "./screens";
|
|
5
14
|
|
|
6
|
-
export
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
success?: boolean;
|
|
11
|
-
}
|
|
15
|
+
export type ModelRouterProps<T extends BasicModelInstance> = DetailsScreenProps<T> &
|
|
16
|
+
ListScreenProps<T> &
|
|
17
|
+
AddScreenProps<T> &
|
|
18
|
+
UpdateScreenProps<T>;
|
|
12
19
|
|
|
13
|
-
export
|
|
14
|
-
modelName: string;
|
|
15
|
-
model: Model;
|
|
16
|
-
//list screen
|
|
17
|
-
requestList?: () => void;
|
|
18
|
-
list: {
|
|
19
|
-
data: any[];
|
|
20
|
-
onClickRemoveItem: (item: any) => void;
|
|
21
|
-
listRequest: RequestState;
|
|
22
|
-
requestDelete: RequestState;
|
|
23
|
-
};
|
|
24
|
-
//add screen
|
|
25
|
-
add: {
|
|
26
|
-
onSubmit: (obj: object) => void;
|
|
27
|
-
request: RequestState;
|
|
28
|
-
};
|
|
29
|
-
//detail screen
|
|
30
|
-
detail: {
|
|
31
|
-
onScreenMount?: (id: string) => void;
|
|
32
|
-
request: RequestState;
|
|
33
|
-
instance?: any;
|
|
34
|
-
};
|
|
35
|
-
//update screen
|
|
36
|
-
update: {
|
|
37
|
-
onSubmit: (obj: object) => void;
|
|
38
|
-
request: RequestState;
|
|
39
|
-
requestInstance: RequestState;
|
|
40
|
-
onRequestInstance: (id: string) => void;
|
|
41
|
-
instance?: any;
|
|
42
|
-
};
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
export const ModelRouter = (props: ModelRouterProps) => {
|
|
20
|
+
export const ModelRouter = <T extends BasicModelInstance>(props: ModelRouterProps<T>) => {
|
|
46
21
|
return (
|
|
47
22
|
<Routes>
|
|
48
23
|
<Route path="" element={<ListScreen {...props} />} />
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export interface RequestState {
|
|
2
|
+
idle?: boolean;
|
|
3
|
+
loading?: boolean;
|
|
4
|
+
error?: string;
|
|
5
|
+
success?: boolean;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export const IdleRequest: RequestState = {
|
|
9
|
+
idle: true,
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
export const LoadingRequest: RequestState = {
|
|
13
|
+
loading: true,
|
|
14
|
+
};
|
|
@@ -1,52 +1,69 @@
|
|
|
1
1
|
import React, { useEffect } from "react";
|
|
2
2
|
import { useNavigate } from "react-router-dom";
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
3
|
+
import { Header, Content } from "~/components";
|
|
4
|
+
import { BasicModelInstance, ModelForm } from "~/generators";
|
|
5
|
+
import { HeaderLayout } from "../../../layouts";
|
|
6
|
+
import { useNotificationCenter } from "../../../providers";
|
|
7
|
+
import { RequestState } from "../model-router.types";
|
|
8
|
+
import { BaseScreenProps } from "./screens.types";
|
|
6
9
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
id: "add",
|
|
21
|
-
text: `Add new ${modelName}`,
|
|
22
|
-
link: "/add",
|
|
23
|
-
},
|
|
24
|
-
],
|
|
25
|
-
},
|
|
26
|
-
modelFormProps: {
|
|
27
|
-
model,
|
|
28
|
-
saveButtonText: "Save",
|
|
29
|
-
onSubmit: add.onSubmit,
|
|
30
|
-
},
|
|
31
|
-
};
|
|
32
|
-
};
|
|
10
|
+
export interface AddScreenProps<T extends BasicModelInstance> extends BaseScreenProps {
|
|
11
|
+
/**
|
|
12
|
+
* Callback executed when the user wants to
|
|
13
|
+
* add a new item
|
|
14
|
+
*/
|
|
15
|
+
onSubmitNewItem: (obj: T) => void;
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Current status of the request to retrieve
|
|
19
|
+
* add a new item
|
|
20
|
+
*/
|
|
21
|
+
newItemRequest: RequestState;
|
|
22
|
+
}
|
|
33
23
|
|
|
34
|
-
export const AddScreen =
|
|
24
|
+
export const AddScreen = <T extends BasicModelInstance>({
|
|
25
|
+
model,
|
|
26
|
+
modelName,
|
|
27
|
+
onSubmitNewItem,
|
|
28
|
+
newItemRequest,
|
|
29
|
+
}: AddScreenProps<T>) => {
|
|
35
30
|
const navigate = useNavigate();
|
|
36
31
|
const { show } = useNotificationCenter();
|
|
37
32
|
|
|
38
33
|
useEffect(() => {
|
|
39
|
-
if (
|
|
34
|
+
if (newItemRequest.success) {
|
|
40
35
|
show({ message: "Item added successfully", severity: "success" });
|
|
41
36
|
navigate("/");
|
|
42
37
|
}
|
|
43
|
-
}, [
|
|
38
|
+
}, [newItemRequest.success]);
|
|
44
39
|
|
|
45
40
|
useEffect(() => {
|
|
46
|
-
if (
|
|
47
|
-
show({ title: "We had an error", message:
|
|
41
|
+
if (newItemRequest.error) {
|
|
42
|
+
show({ title: "We had an error", message: newItemRequest.error, severity: "error" });
|
|
48
43
|
}
|
|
49
|
-
}, [
|
|
44
|
+
}, [newItemRequest.error]);
|
|
50
45
|
|
|
51
|
-
return
|
|
46
|
+
return (
|
|
47
|
+
<HeaderLayout loading={newItemRequest.loading}>
|
|
48
|
+
<Header
|
|
49
|
+
title={`Add ${modelName}`}
|
|
50
|
+
preset="default"
|
|
51
|
+
breadcrumbs={[
|
|
52
|
+
{
|
|
53
|
+
id: "list",
|
|
54
|
+
text: modelName,
|
|
55
|
+
link: "/",
|
|
56
|
+
},
|
|
57
|
+
{
|
|
58
|
+
id: "add",
|
|
59
|
+
text: `Add new ${modelName}`,
|
|
60
|
+
link: "/add",
|
|
61
|
+
},
|
|
62
|
+
]}
|
|
63
|
+
/>
|
|
64
|
+
<Content>
|
|
65
|
+
<ModelForm model={model} saveButtonText="Save" onSubmit={onSubmitNewItem} />
|
|
66
|
+
</Content>
|
|
67
|
+
</HeaderLayout>
|
|
68
|
+
);
|
|
52
69
|
};
|
|
@@ -1,53 +1,62 @@
|
|
|
1
1
|
import React, { useEffect } from "react";
|
|
2
2
|
import { useParams } from "react-router-dom";
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import
|
|
3
|
+
import { RequestState } from "../model-router.types";
|
|
4
|
+
import { Content, Header } from "~/components";
|
|
5
|
+
import { HeaderLayout } from "~/layouts";
|
|
6
|
+
import { BaseScreenProps } from "./screens.types";
|
|
7
|
+
import { BasicModelInstance, ObjectDetails } from "~/generators";
|
|
7
8
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
link: `/${id}`,
|
|
27
|
-
},
|
|
28
|
-
],
|
|
29
|
-
},
|
|
30
|
-
objectDetailsProps: {
|
|
31
|
-
model,
|
|
32
|
-
instance: detail.instance,
|
|
33
|
-
},
|
|
34
|
-
notFoundPlaceholderProps: {
|
|
35
|
-
title: "Not found",
|
|
36
|
-
subtitle: "There is no item with that id",
|
|
37
|
-
icon: ({ size, color }: PlaceholderIconArgs) => (
|
|
38
|
-
<SentimentVeryDissatisfiedIcon color={color} sx={{ fontSize: size }} />
|
|
39
|
-
),
|
|
40
|
-
},
|
|
41
|
-
};
|
|
42
|
-
};
|
|
9
|
+
export interface DetailsScreenProps<T extends BasicModelInstance> extends BaseScreenProps {
|
|
10
|
+
/**
|
|
11
|
+
* Callback executed each time we want
|
|
12
|
+
* the details information of an item
|
|
13
|
+
*/
|
|
14
|
+
onRequestItem: (id: string) => void;
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Current status of the request to retrieve
|
|
18
|
+
* an item
|
|
19
|
+
*/
|
|
20
|
+
itemRequest: RequestState;
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Item to be displayed
|
|
24
|
+
*/
|
|
25
|
+
detailsItem?: T;
|
|
26
|
+
}
|
|
43
27
|
|
|
44
|
-
export const DetailsScreen =
|
|
45
|
-
|
|
28
|
+
export const DetailsScreen = <T extends BasicModelInstance>({
|
|
29
|
+
model,
|
|
30
|
+
modelName,
|
|
31
|
+
onRequestItem,
|
|
32
|
+
itemRequest,
|
|
33
|
+
detailsItem,
|
|
34
|
+
}: DetailsScreenProps<T>) => {
|
|
46
35
|
const { id = "" } = useParams();
|
|
47
36
|
|
|
48
37
|
useEffect(() => {
|
|
49
|
-
|
|
38
|
+
onRequestItem(id);
|
|
50
39
|
}, [id]);
|
|
51
40
|
|
|
52
|
-
return
|
|
41
|
+
return (
|
|
42
|
+
<HeaderLayout loading={itemRequest.loading}>
|
|
43
|
+
<Header
|
|
44
|
+
title={id}
|
|
45
|
+
preset="default"
|
|
46
|
+
breadcrumbs={[
|
|
47
|
+
{
|
|
48
|
+
id: "list",
|
|
49
|
+
text: modelName,
|
|
50
|
+
link: "/",
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
id: "detail",
|
|
54
|
+
text: id,
|
|
55
|
+
link: `/${id}`,
|
|
56
|
+
},
|
|
57
|
+
]}
|
|
58
|
+
/>
|
|
59
|
+
<Content>{detailsItem && <ObjectDetails model={model} instance={detailsItem} />}</Content>
|
|
60
|
+
</HeaderLayout>
|
|
61
|
+
);
|
|
53
62
|
};
|