@cosmicdrift/kumiko-renderer 0.327.0 → 0.328.1
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/app/action-form-shim.d.ts +14 -0
- package/{src/app/action-form-shim.ts → dist/app/action-form-shim.js} +26 -44
- package/dist/app/app-features-context.d.ts +8 -0
- package/dist/app/app-features-context.js +16 -0
- package/dist/app/column-renderers.d.ts +30 -0
- package/dist/app/column-renderers.js +34 -0
- package/dist/app/config-edit-shim.d.ts +11 -0
- package/{src/app/config-edit-shim.ts → dist/app/config-edit-shim.js} +12 -25
- package/dist/app/content-editors.d.ts +38 -0
- package/dist/app/content-editors.js +26 -0
- package/dist/app/content-preview.d.ts +11 -0
- package/dist/app/content-preview.js +30 -0
- package/dist/app/custom-screens.d.ts +11 -0
- package/dist/app/custom-screens.js +20 -0
- package/dist/app/dashboard-body.d.ts +16 -0
- package/dist/app/dashboard-body.js +11 -0
- package/dist/app/extension-form-submit.d.ts +32 -0
- package/dist/app/extension-form-submit.js +73 -0
- package/dist/app/extension-sections.d.ts +72 -0
- package/dist/app/extension-sections.js +34 -0
- package/dist/app/feature-schema.d.ts +4 -0
- package/{src/app/feature-schema.ts → dist/app/feature-schema.js} +12 -22
- package/dist/app/form-schema.d.ts +4 -0
- package/dist/app/form-schema.js +85 -0
- package/dist/app/kumiko-screen.d.ts +43 -0
- package/dist/app/kumiko-screen.js +2206 -0
- package/dist/app/layout-fields.d.ts +3 -0
- package/dist/app/layout-fields.js +20 -0
- package/dist/app/list-facets.d.ts +48 -0
- package/dist/app/list-facets.js +185 -0
- package/dist/app/nav.d.ts +61 -0
- package/dist/app/nav.js +139 -0
- package/dist/app/projection-detail-shim.d.ts +8 -0
- package/dist/app/projection-detail-shim.js +71 -0
- package/dist/app/projection-list-shim.d.ts +13 -0
- package/{src/app/projection-list-shim.ts → dist/app/projection-list-shim.js} +26 -38
- package/dist/app/qn.d.ts +7 -0
- package/{src/app/qn.ts → dist/app/qn.js} +9 -11
- package/dist/app/qualify-screen-id.d.ts +2 -0
- package/{src/app/qualify-screen-id.ts → dist/app/qualify-screen-id.js} +5 -6
- package/dist/app/reference-facet-bridge.d.ts +10 -0
- package/dist/app/reference-facet-bridge.js +22 -0
- package/dist/app/return-to.d.ts +31 -0
- package/dist/app/return-to.js +188 -0
- package/dist/app/row-actions.d.ts +77 -0
- package/dist/app/row-actions.js +416 -0
- package/dist/app/screen-access.d.ts +8 -0
- package/dist/app/screen-access.js +48 -0
- package/dist/app/secret-mint-body.d.ts +10 -0
- package/dist/app/secret-mint-body.js +140 -0
- package/dist/app/secrets-edit-body.d.ts +8 -0
- package/dist/app/secrets-edit-body.js +76 -0
- package/dist/app/use-embedded-screen.d.ts +6 -0
- package/dist/app/use-embedded-screen.js +19 -0
- package/dist/app/variable-chips.d.ts +7 -0
- package/dist/app/variable-chips.js +16 -0
- package/dist/app/write-failed-error.d.ts +6 -0
- package/dist/app/write-failed-error.js +21 -0
- package/dist/components/embedded-list-field.d.ts +10 -0
- package/dist/components/embedded-list-field.js +259 -0
- package/dist/components/grid-cell-for-field.d.ts +25 -0
- package/dist/components/grid-cell-for-field.js +31 -0
- package/dist/components/multi-select-checkboxes.d.ts +14 -0
- package/dist/components/multi-select-checkboxes.js +36 -0
- package/dist/components/reference-create-dialog.d.ts +13 -0
- package/dist/components/reference-create-dialog.js +46 -0
- package/dist/components/related-list-section.d.ts +25 -0
- package/dist/components/related-list-section.js +273 -0
- package/dist/components/render-edit-action-button.d.ts +22 -0
- package/dist/components/render-edit-action-button.js +43 -0
- package/dist/components/render-edit-logic.d.ts +6 -0
- package/dist/components/render-edit-logic.js +63 -0
- package/dist/components/render-edit-types.d.ts +209 -0
- package/dist/components/render-edit-types.js +1 -0
- package/dist/components/render-edit.d.ts +6 -0
- package/dist/components/render-edit.js +1169 -0
- package/dist/components/render-field.d.ts +38 -0
- package/dist/components/render-field.js +544 -0
- package/dist/components/render-list.d.ts +117 -0
- package/dist/components/render-list.js +232 -0
- package/dist/components/write-form-section.d.ts +17 -0
- package/dist/components/write-form-section.js +104 -0
- package/dist/context/dispatcher-context.d.ts +10 -0
- package/{src/context/dispatcher-context.tsx → dist/context/dispatcher-context.js} +16 -29
- package/dist/context/draft-storage-context.d.ts +12 -0
- package/dist/context/draft-storage-context.js +18 -0
- package/dist/context/user-roles-context.d.ts +7 -0
- package/{src/context/user-roles-context.tsx → dist/context/user-roles-context.js} +7 -15
- package/dist/format-when.d.ts +1 -0
- package/{src/format-when.ts → dist/format-when.js} +7 -7
- package/dist/hooks/reference-limits.d.ts +3 -0
- package/{src/hooks/reference-limits.ts → dist/hooks/reference-limits.js} +0 -1
- package/dist/hooks/use-ai-text.d.ts +52 -0
- package/dist/hooks/use-ai-text.js +90 -0
- package/dist/hooks/use-disclosure.d.ts +7 -0
- package/dist/hooks/use-disclosure.js +8 -0
- package/dist/hooks/use-form.d.ts +7 -0
- package/dist/hooks/use-form.js +36 -0
- package/dist/hooks/use-list-url-state.d.ts +43 -0
- package/dist/hooks/use-list-url-state.js +131 -0
- package/dist/hooks/use-mutation.d.ts +9 -0
- package/dist/hooks/use-mutation.js +37 -0
- package/dist/hooks/use-query.d.ts +14 -0
- package/dist/hooks/use-query.js +118 -0
- package/dist/hooks/use-reference-lookup.d.ts +14 -0
- package/dist/hooks/use-reference-lookup.js +63 -0
- package/dist/hooks/use-store.d.ts +3 -0
- package/dist/hooks/use-store.js +38 -0
- package/dist/hooks/use-stream-handler.d.ts +14 -0
- package/dist/hooks/use-stream-handler.js +93 -0
- package/dist/i18n-defaults.d.ts +2 -0
- package/dist/i18n-defaults.js +201 -0
- package/dist/i18n.d.ts +64 -0
- package/dist/i18n.js +166 -0
- package/dist/index.d.ts +77 -0
- package/dist/index.js +55 -0
- package/dist/inside-drawer.d.ts +2 -0
- package/dist/inside-drawer.js +9 -0
- package/dist/page-header-slot.d.ts +2 -0
- package/dist/page-header-slot.js +9 -0
- package/dist/primitives.d.ts +1351 -0
- package/dist/primitives.js +73 -0
- package/dist/screen-fills-height.d.ts +3 -0
- package/dist/screen-fills-height.js +3 -0
- package/dist/share-links.d.ts +4 -0
- package/dist/share-links.js +11 -0
- package/dist/sort-by-accessor.d.ts +5 -0
- package/dist/sort-by-accessor.js +16 -0
- package/dist/sse/live-events.d.ts +23 -0
- package/dist/sse/live-events.js +28 -0
- package/dist/tokens.d.ts +83 -0
- package/dist/tokens.js +80 -0
- package/package.json +16 -9
- package/src/changes.json +52 -0
- package/src/__tests__/error-i18n-defaults.test.ts +0 -82
- package/src/__tests__/format-when.test.ts +0 -12
- package/src/__tests__/i18n.test.tsx +0 -283
- package/src/__tests__/merge-search-params-into-initial.test.ts +0 -525
- package/src/__tests__/qn.test.ts +0 -83
- package/src/__tests__/share-links.test.ts +0 -26
- package/src/__tests__/sort-by-accessor.test.ts +0 -48
- package/src/__tests__/stringify-nav-params.test.ts +0 -33
- package/src/__tests__/use-list-url-state.test.tsx +0 -250
- package/src/app/__tests__/action-form-field-labels.test.tsx +0 -92
- package/src/app/__tests__/action-form-shim.test.ts +0 -137
- package/src/app/__tests__/build-list-query-payload.test.ts +0 -107
- package/src/app/__tests__/config-edit-shim.test.ts +0 -57
- package/src/app/__tests__/content-editors.test.tsx +0 -128
- package/src/app/__tests__/content-preview.test.tsx +0 -184
- package/src/app/__tests__/entity-edit-create-search-params.test.tsx +0 -236
- package/src/app/__tests__/entity-edit-jsonb-embedded-submit.test.tsx +0 -239
- package/src/app/__tests__/entity-list-create-singleton.test.tsx +0 -128
- package/src/app/__tests__/entity-list-row-action-entity-target.test.tsx +0 -424
- package/src/app/__tests__/entity-list-row-action-icon.test.tsx +0 -248
- package/src/app/__tests__/entity-list-row-action-kumiko-actions-view.test.tsx +0 -162
- package/src/app/__tests__/entity-list-row-action-refetch.test.tsx +0 -401
- package/src/app/__tests__/entity-list-screen-padding.test.tsx +0 -111
- package/src/app/__tests__/feature-schema.test.ts +0 -40
- package/src/app/__tests__/form-schema.test.ts +0 -247
- package/src/app/__tests__/list-daterange-facet.test.ts +0 -165
- package/src/app/__tests__/list-filter-facets.test.tsx +0 -521
- package/src/app/__tests__/nav.test.ts +0 -198
- package/src/app/__tests__/projection-detail-actions.test.tsx +0 -719
- package/src/app/__tests__/projection-detail-reference-field.test.tsx +0 -165
- package/src/app/__tests__/projection-detail-shim.test.ts +0 -188
- package/src/app/__tests__/projection-detail-singleton.test.tsx +0 -191
- package/src/app/__tests__/projection-list-bad-shape.test.tsx +0 -152
- package/src/app/__tests__/projection-list-reference-column.test.tsx +0 -219
- package/src/app/__tests__/projection-list-search-sort.test.tsx +0 -212
- package/src/app/__tests__/qualified-names.test.ts +0 -37
- package/src/app/__tests__/return-to.test.ts +0 -396
- package/src/app/__tests__/row-actions-navigate-tab.test.ts +0 -223
- package/src/app/__tests__/row-default-edit-action.test.tsx +0 -324
- package/src/app/__tests__/screen-access-allows.test.ts +0 -34
- package/src/app/__tests__/secret-mint-body.test.tsx +0 -404
- package/src/app/__tests__/variable-chips.test.tsx +0 -70
- package/src/app/app-features-context.tsx +0 -25
- package/src/app/column-renderers.tsx +0 -68
- package/src/app/content-editors.tsx +0 -85
- package/src/app/content-preview.tsx +0 -67
- package/src/app/custom-screens.tsx +0 -29
- package/src/app/dashboard-body.tsx +0 -33
- package/src/app/extension-form-submit.tsx +0 -123
- package/src/app/extension-sections.tsx +0 -111
- package/src/app/form-schema.ts +0 -91
- package/src/app/kumiko-screen.tsx +0 -3614
- package/src/app/layout-fields.ts +0 -31
- package/src/app/list-facets.ts +0 -259
- package/src/app/nav.tsx +0 -258
- package/src/app/projection-detail-shim.ts +0 -85
- package/src/app/reference-facet-bridge.tsx +0 -58
- package/src/app/return-to.tsx +0 -234
- package/src/app/row-actions.ts +0 -639
- package/src/app/screen-access.ts +0 -63
- package/src/app/secret-mint-body.tsx +0 -259
- package/src/app/secrets-edit-body.tsx +0 -194
- package/src/app/use-embedded-screen.ts +0 -27
- package/src/app/variable-chips.tsx +0 -39
- package/src/app/write-failed-error.ts +0 -27
- package/src/components/__tests__/embedded-list-field.test.tsx +0 -531
- package/src/components/__tests__/multi-select-checkboxes.test.tsx +0 -162
- package/src/components/__tests__/related-list-section-empty-state.test.tsx +0 -143
- package/src/components/__tests__/related-list-section.test.tsx +0 -1669
- package/src/components/__tests__/render-edit-action-button.test.tsx +0 -205
- package/src/components/__tests__/render-edit-hidden-section.test.tsx +0 -128
- package/src/components/__tests__/render-edit-logic.test.ts +0 -314
- package/src/components/__tests__/render-edit-screen-description.test.tsx +0 -152
- package/src/components/__tests__/render-edit-submit-actions.test.tsx +0 -460
- package/src/components/__tests__/render-field-app-locale.test.tsx +0 -142
- package/src/components/__tests__/render-field-enum-option.test.tsx +0 -99
- package/src/components/__tests__/render-field-icon-derivation.test.tsx +0 -119
- package/src/components/__tests__/render-field-json-format.test.tsx +0 -164
- package/src/components/__tests__/render-field-money-embedded-list-consistency.test.tsx +0 -212
- package/src/components/__tests__/render-field-money-roundtrip.test.tsx +0 -217
- package/src/components/__tests__/render-field-number-grouping.test.tsx +0 -76
- package/src/components/__tests__/render-field-number-unit.test.tsx +0 -227
- package/src/components/__tests__/render-field-password-format.test.tsx +0 -101
- package/src/components/__tests__/render-field-select-display.test.tsx +0 -134
- package/src/components/__tests__/render-field-unit-format.test.tsx +0 -107
- package/src/components/__tests__/render-field-unsupported-types.test.tsx +0 -195
- package/src/components/__tests__/render-list-toolbar-icon-only.test.tsx +0 -146
- package/src/components/__tests__/write-form-section.test.tsx +0 -375
- package/src/components/embedded-list-field.tsx +0 -354
- package/src/components/grid-cell-for-field.tsx +0 -60
- package/src/components/multi-select-checkboxes.tsx +0 -93
- package/src/components/reference-create-dialog.tsx +0 -91
- package/src/components/related-list-section.tsx +0 -467
- package/src/components/render-edit-action-button.tsx +0 -106
- package/src/components/render-edit-logic.ts +0 -85
- package/src/components/render-edit-types.ts +0 -216
- package/src/components/render-edit.tsx +0 -1700
- package/src/components/render-field.tsx +0 -942
- package/src/components/render-list.tsx +0 -561
- package/src/components/write-form-section.tsx +0 -199
- package/src/context/draft-storage-context.tsx +0 -39
- package/src/hooks/__tests__/use-ai-text.test.tsx +0 -177
- package/src/hooks/__tests__/use-disclosure.test.tsx +0 -25
- package/src/hooks/__tests__/use-form.test.tsx +0 -65
- package/src/hooks/__tests__/use-mutation.test.tsx +0 -77
- package/src/hooks/__tests__/use-stream-handler.test.tsx +0 -107
- package/src/hooks/use-ai-text.ts +0 -172
- package/src/hooks/use-disclosure.ts +0 -20
- package/src/hooks/use-form.ts +0 -78
- package/src/hooks/use-list-url-state.ts +0 -171
- package/src/hooks/use-mutation.ts +0 -61
- package/src/hooks/use-query.ts +0 -132
- package/src/hooks/use-reference-lookup.ts +0 -76
- package/src/hooks/use-store.ts +0 -48
- package/src/hooks/use-stream-handler.ts +0 -134
- package/src/i18n-defaults.ts +0 -220
- package/src/i18n.tsx +0 -286
- package/src/index.ts +0 -272
- package/src/primitives.tsx +0 -1446
- package/src/share-links.ts +0 -12
- package/src/sort-by-accessor.ts +0 -20
- package/src/sse/live-events.tsx +0 -56
- package/src/tokens.tsx +0 -170
|
@@ -1,162 +0,0 @@
|
|
|
1
|
-
// fw-i18n-funde: user-data-rights's export-job-list screen (bundled-features/
|
|
2
|
-
// src/user-data-rights/screens.ts) ships a `navigate` row action labelled
|
|
3
|
-
// "kumiko.actions.view", following the same `kumiko.actions.*` convention as
|
|
4
|
-
// tenant/screens.ts and user/screens.ts (e.g. "kumiko.actions.edit"). Unlike
|
|
5
|
-
// those, "kumiko.actions.view" was never declared in the framework's default
|
|
6
|
-
// bundle (renderer/src/i18n-defaults.ts) — every mounting app rendered the
|
|
7
|
-
// raw key instead of a translated label. This renders the real entityList
|
|
8
|
-
// pipeline (KumikoScreen → EntityListBody) against the framework's own
|
|
9
|
-
// kumikoDefaultTranslations, mirroring entity-list-row-action-refetch.test.tsx's
|
|
10
|
-
// harness, and asserts the row action resolves to actual text.
|
|
11
|
-
|
|
12
|
-
import { describe, expect, test } from "bun:test";
|
|
13
|
-
import type {
|
|
14
|
-
EntityDefinition,
|
|
15
|
-
EntityListScreenDefinition,
|
|
16
|
-
} from "@cosmicdrift/kumiko-framework/ui-types";
|
|
17
|
-
import type { Dispatcher } from "@cosmicdrift/kumiko-headless";
|
|
18
|
-
import { render, waitFor } from "@testing-library/react";
|
|
19
|
-
import type { ComponentType, ReactNode } from "react";
|
|
20
|
-
import { DispatcherProvider } from "../../context/dispatcher-context";
|
|
21
|
-
import { createStaticLocaleResolver, LocaleProvider } from "../../i18n";
|
|
22
|
-
import { kumikoDefaultTranslations } from "../../i18n-defaults";
|
|
23
|
-
import {
|
|
24
|
-
type CorePrimitives,
|
|
25
|
-
type DataTableProps,
|
|
26
|
-
type DataTableRowAction,
|
|
27
|
-
PrimitivesProvider,
|
|
28
|
-
} from "../../primitives";
|
|
29
|
-
import type { FeatureSchema } from "../feature-schema";
|
|
30
|
-
import { KumikoScreen } from "../kumiko-screen";
|
|
31
|
-
import { NavProvider } from "../nav";
|
|
32
|
-
|
|
33
|
-
function stubDispatcher(): Dispatcher {
|
|
34
|
-
return {
|
|
35
|
-
write: (async () => ({ isSuccess: true, data: {} })) as unknown as Dispatcher["write"],
|
|
36
|
-
query: (async () => ({
|
|
37
|
-
isSuccess: true,
|
|
38
|
-
data: { rows: [{ id: "job-1", status: "completed" }], nextCursor: null, total: 1 },
|
|
39
|
-
})) as unknown as Dispatcher["query"],
|
|
40
|
-
batch: (async () => ({ isSuccess: true, results: [] })) as unknown as Dispatcher["batch"],
|
|
41
|
-
statusStore: {
|
|
42
|
-
getState: () => "online",
|
|
43
|
-
subscribe: () => () => {},
|
|
44
|
-
} as unknown as Dispatcher["statusStore"],
|
|
45
|
-
async *stream() {},
|
|
46
|
-
pendingWrites: () => [],
|
|
47
|
-
pendingFiles: () => [],
|
|
48
|
-
};
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
let capturedRowActions: readonly DataTableRowAction[] | undefined;
|
|
52
|
-
const captureDataTable: ComponentType<DataTableProps> = (props) => {
|
|
53
|
-
capturedRowActions = props.rowActions;
|
|
54
|
-
return null;
|
|
55
|
-
};
|
|
56
|
-
const noop = (): ReactNode => null;
|
|
57
|
-
const passChildren = ({ children }: { readonly children?: ReactNode }): ReactNode => children;
|
|
58
|
-
|
|
59
|
-
const testPrimitives: CorePrimitives = {
|
|
60
|
-
Button: noop,
|
|
61
|
-
Banner: passChildren,
|
|
62
|
-
Field: passChildren,
|
|
63
|
-
Input: noop,
|
|
64
|
-
DataTable: captureDataTable,
|
|
65
|
-
Form: passChildren,
|
|
66
|
-
Section: passChildren,
|
|
67
|
-
Card: passChildren,
|
|
68
|
-
Grid: passChildren,
|
|
69
|
-
GridCell: passChildren,
|
|
70
|
-
Text: passChildren,
|
|
71
|
-
Heading: noop,
|
|
72
|
-
Dialog: noop,
|
|
73
|
-
Modal: noop,
|
|
74
|
-
Lightbox: noop,
|
|
75
|
-
ConfigSourceBadge: noop,
|
|
76
|
-
ConfigCascadeView: noop,
|
|
77
|
-
Link: noop,
|
|
78
|
-
};
|
|
79
|
-
|
|
80
|
-
function buildSchema(): FeatureSchema {
|
|
81
|
-
const entity: EntityDefinition = {
|
|
82
|
-
fields: {
|
|
83
|
-
status: {
|
|
84
|
-
type: "text",
|
|
85
|
-
maxLength: 50,
|
|
86
|
-
required: false,
|
|
87
|
-
searchable: false,
|
|
88
|
-
sortable: false,
|
|
89
|
-
},
|
|
90
|
-
},
|
|
91
|
-
};
|
|
92
|
-
// Mirrors user-data-rights's export-job-list rowAction verbatim (kind,
|
|
93
|
-
// label key, entityId) — only ids/entity/screen are renamed for the fixture.
|
|
94
|
-
const listScreen: EntityListScreenDefinition = {
|
|
95
|
-
id: "export-job-list",
|
|
96
|
-
type: "entityList",
|
|
97
|
-
entity: "export-job",
|
|
98
|
-
columns: ["status"],
|
|
99
|
-
rowActions: [
|
|
100
|
-
{
|
|
101
|
-
kind: "navigate",
|
|
102
|
-
id: "view",
|
|
103
|
-
label: "kumiko.actions.view",
|
|
104
|
-
screen: "export-job-detail",
|
|
105
|
-
entityId: "id",
|
|
106
|
-
},
|
|
107
|
-
],
|
|
108
|
-
};
|
|
109
|
-
return {
|
|
110
|
-
featureName: "user-data-rights",
|
|
111
|
-
entities: { "export-job": entity },
|
|
112
|
-
screens: [listScreen],
|
|
113
|
-
} as FeatureSchema;
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
function renderListScreen(): void {
|
|
117
|
-
render(
|
|
118
|
-
<LocaleProvider
|
|
119
|
-
resolver={createStaticLocaleResolver({ locale: "en" })}
|
|
120
|
-
fallbackBundles={[kumikoDefaultTranslations]}
|
|
121
|
-
>
|
|
122
|
-
<DispatcherProvider dispatcher={stubDispatcher()}>
|
|
123
|
-
<NavProvider
|
|
124
|
-
value={{
|
|
125
|
-
route: { screenId: "user-data-rights:export-job-list" },
|
|
126
|
-
navigate: () => {},
|
|
127
|
-
replace: () => {},
|
|
128
|
-
hrefFor: () => "",
|
|
129
|
-
searchParams: {},
|
|
130
|
-
setSearchParams: () => {},
|
|
131
|
-
}}
|
|
132
|
-
>
|
|
133
|
-
<PrimitivesProvider value={testPrimitives}>
|
|
134
|
-
<KumikoScreen schema={buildSchema()} qn="user-data-rights:screen:export-job-list" />
|
|
135
|
-
</PrimitivesProvider>
|
|
136
|
-
</NavProvider>
|
|
137
|
-
</DispatcherProvider>
|
|
138
|
-
</LocaleProvider>,
|
|
139
|
-
);
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
function requireViewAction(): DataTableRowAction {
|
|
143
|
-
const action = capturedRowActions?.find((a) => a.id === "view");
|
|
144
|
-
if (!action) throw new Error("expected the 'view' row action to be captured");
|
|
145
|
-
return action;
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
describe("entityList navigate row-action renders the framework's kumiko.actions.* labels", () => {
|
|
149
|
-
test("kumiko.actions.view resolves to real text, not the raw key", async () => {
|
|
150
|
-
capturedRowActions = undefined;
|
|
151
|
-
|
|
152
|
-
renderListScreen();
|
|
153
|
-
|
|
154
|
-
await waitFor(() => {
|
|
155
|
-
expect(capturedRowActions).toBeDefined();
|
|
156
|
-
});
|
|
157
|
-
|
|
158
|
-
const viewAction = requireViewAction();
|
|
159
|
-
expect(viewAction.label).not.toBe("kumiko.actions.view");
|
|
160
|
-
expect(viewAction.label).toBe("View");
|
|
161
|
-
});
|
|
162
|
-
});
|
|
@@ -1,401 +0,0 @@
|
|
|
1
|
-
// Bug found while archiving a cost-type in solon (kumiko-framework#113-adjacent):
|
|
2
|
-
// a `writeHandler` row-action on an entityList screen writes successfully
|
|
3
|
-
// (HTTP 200, projection updated) but the list keeps showing the old state,
|
|
4
|
-
// because nothing ever refetches the rows query after the write resolves.
|
|
5
|
-
// Actions with a `redirect`/navigate target hide this — the screen remount
|
|
6
|
-
// reloads everything. This test renders the real list path (KumikoScreen →
|
|
7
|
-
// EntityListScreen → EntityListBody → RenderList) under a stub dispatcher
|
|
8
|
-
// that counts `query()` calls, and proves the rows query refetches after a
|
|
9
|
-
// successful row-action write, but NOT after a failed one (no double-fetch,
|
|
10
|
-
// no silent refetch loop).
|
|
11
|
-
|
|
12
|
-
import { describe, expect, test } from "bun:test";
|
|
13
|
-
import type {
|
|
14
|
-
EntityDefinition,
|
|
15
|
-
EntityListScreenDefinition,
|
|
16
|
-
ProjectionListScreenDefinition,
|
|
17
|
-
} from "@cosmicdrift/kumiko-framework/ui-types";
|
|
18
|
-
import type { Dispatcher } from "@cosmicdrift/kumiko-headless";
|
|
19
|
-
import { act, fireEvent, render, screen, waitFor } from "@testing-library/react";
|
|
20
|
-
import type { ComponentType, ReactNode } from "react";
|
|
21
|
-
import { DispatcherProvider } from "../../context/dispatcher-context";
|
|
22
|
-
import { createStaticLocaleResolver, LocaleProvider } from "../../i18n";
|
|
23
|
-
import { kumikoDefaultTranslations } from "../../i18n-defaults";
|
|
24
|
-
import {
|
|
25
|
-
type ButtonProps,
|
|
26
|
-
type CorePrimitives,
|
|
27
|
-
type DataTableProps,
|
|
28
|
-
type DataTableRowAction,
|
|
29
|
-
PrimitivesProvider,
|
|
30
|
-
} from "../../primitives";
|
|
31
|
-
import type { FeatureSchema } from "../feature-schema";
|
|
32
|
-
import { KumikoScreen } from "../kumiko-screen";
|
|
33
|
-
import { NavProvider } from "../nav";
|
|
34
|
-
|
|
35
|
-
let capturedRowActions: readonly DataTableRowAction[] | undefined;
|
|
36
|
-
const captureDataTable: ComponentType<DataTableProps> = (props) => {
|
|
37
|
-
capturedRowActions = props.rowActions;
|
|
38
|
-
return null;
|
|
39
|
-
};
|
|
40
|
-
const noop = (): ReactNode => null;
|
|
41
|
-
const passChildren = ({ children }: { readonly children?: ReactNode }): ReactNode => children;
|
|
42
|
-
|
|
43
|
-
const testPrimitives: CorePrimitives = {
|
|
44
|
-
Button: noop,
|
|
45
|
-
Banner: passChildren,
|
|
46
|
-
Field: passChildren,
|
|
47
|
-
Input: noop,
|
|
48
|
-
DataTable: captureDataTable,
|
|
49
|
-
Form: passChildren,
|
|
50
|
-
Section: passChildren,
|
|
51
|
-
Card: passChildren,
|
|
52
|
-
Grid: passChildren,
|
|
53
|
-
GridCell: passChildren,
|
|
54
|
-
Text: passChildren,
|
|
55
|
-
Heading: noop,
|
|
56
|
-
Dialog: noop,
|
|
57
|
-
Modal: noop,
|
|
58
|
-
Lightbox: noop,
|
|
59
|
-
ConfigSourceBadge: noop,
|
|
60
|
-
ConfigCascadeView: noop,
|
|
61
|
-
Link: noop,
|
|
62
|
-
};
|
|
63
|
-
|
|
64
|
-
let queryCallCount = 0;
|
|
65
|
-
let writeIsSuccess = true;
|
|
66
|
-
|
|
67
|
-
function stubDispatcher(): Dispatcher {
|
|
68
|
-
return {
|
|
69
|
-
write: (async () => {
|
|
70
|
-
if (!writeIsSuccess) {
|
|
71
|
-
return {
|
|
72
|
-
isSuccess: false,
|
|
73
|
-
error: {
|
|
74
|
-
code: "unknown",
|
|
75
|
-
httpStatus: 500,
|
|
76
|
-
i18nKey: "kumiko:error:unknown",
|
|
77
|
-
message: "boom",
|
|
78
|
-
},
|
|
79
|
-
};
|
|
80
|
-
}
|
|
81
|
-
return { isSuccess: true, data: {} };
|
|
82
|
-
}) as unknown as Dispatcher["write"],
|
|
83
|
-
query: (async () => {
|
|
84
|
-
queryCallCount += 1;
|
|
85
|
-
return {
|
|
86
|
-
isSuccess: true,
|
|
87
|
-
data: { rows: [{ id: "unit-1", status: "active" }], nextCursor: null, total: 1 },
|
|
88
|
-
};
|
|
89
|
-
}) as unknown as Dispatcher["query"],
|
|
90
|
-
batch: (async () => ({ isSuccess: true, results: [] })) as unknown as Dispatcher["batch"],
|
|
91
|
-
statusStore: {
|
|
92
|
-
getState: () => "online",
|
|
93
|
-
subscribe: () => () => {},
|
|
94
|
-
} as unknown as Dispatcher["statusStore"],
|
|
95
|
-
async *stream() {},
|
|
96
|
-
pendingWrites: () => [],
|
|
97
|
-
pendingFiles: () => [],
|
|
98
|
-
};
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
function buildSchema(): FeatureSchema {
|
|
102
|
-
const entity: EntityDefinition = {
|
|
103
|
-
fields: {
|
|
104
|
-
status: {
|
|
105
|
-
type: "text",
|
|
106
|
-
maxLength: 50,
|
|
107
|
-
required: false,
|
|
108
|
-
searchable: false,
|
|
109
|
-
sortable: false,
|
|
110
|
-
},
|
|
111
|
-
},
|
|
112
|
-
};
|
|
113
|
-
const listScreen: EntityListScreenDefinition = {
|
|
114
|
-
id: "unit-list",
|
|
115
|
-
type: "entityList",
|
|
116
|
-
entity: "unit",
|
|
117
|
-
columns: ["status"],
|
|
118
|
-
rowActions: [
|
|
119
|
-
{
|
|
120
|
-
id: "archive",
|
|
121
|
-
label: "Archive",
|
|
122
|
-
handler: "units:write:unit:archive",
|
|
123
|
-
},
|
|
124
|
-
],
|
|
125
|
-
};
|
|
126
|
-
return {
|
|
127
|
-
featureName: "units",
|
|
128
|
-
entities: { unit: entity },
|
|
129
|
-
screens: [listScreen],
|
|
130
|
-
} as FeatureSchema;
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
function renderListScreen(): void {
|
|
134
|
-
render(
|
|
135
|
-
<LocaleProvider
|
|
136
|
-
resolver={createStaticLocaleResolver({ locale: "de-DE" })}
|
|
137
|
-
fallbackBundles={[kumikoDefaultTranslations]}
|
|
138
|
-
>
|
|
139
|
-
<DispatcherProvider dispatcher={stubDispatcher()}>
|
|
140
|
-
<NavProvider
|
|
141
|
-
value={{
|
|
142
|
-
route: { screenId: "units:unit-list" },
|
|
143
|
-
navigate: () => {},
|
|
144
|
-
replace: () => {},
|
|
145
|
-
hrefFor: () => "",
|
|
146
|
-
searchParams: {},
|
|
147
|
-
setSearchParams: () => {},
|
|
148
|
-
}}
|
|
149
|
-
>
|
|
150
|
-
<PrimitivesProvider value={testPrimitives}>
|
|
151
|
-
<KumikoScreen schema={buildSchema()} qn="units:screen:unit-list" />
|
|
152
|
-
</PrimitivesProvider>
|
|
153
|
-
</NavProvider>
|
|
154
|
-
</DispatcherProvider>
|
|
155
|
-
</LocaleProvider>,
|
|
156
|
-
);
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
function requireArchiveAction(): DataTableRowAction {
|
|
160
|
-
const action = capturedRowActions?.find((a) => a.id === "archive");
|
|
161
|
-
if (!action) throw new Error("expected the 'archive' row action to be captured");
|
|
162
|
-
return action;
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
describe("entityList row-action writeHandler refetches the rows query", () => {
|
|
166
|
-
test("a successful row-action write triggers exactly one refetch", async () => {
|
|
167
|
-
capturedRowActions = undefined;
|
|
168
|
-
queryCallCount = 0;
|
|
169
|
-
writeIsSuccess = true;
|
|
170
|
-
|
|
171
|
-
renderListScreen();
|
|
172
|
-
|
|
173
|
-
await waitFor(() => {
|
|
174
|
-
expect(capturedRowActions).toBeDefined();
|
|
175
|
-
});
|
|
176
|
-
|
|
177
|
-
const countAfterMount = queryCallCount;
|
|
178
|
-
expect(countAfterMount).toBeGreaterThan(0);
|
|
179
|
-
|
|
180
|
-
await act(async () => {
|
|
181
|
-
await requireArchiveAction().onTrigger({ id: "unit-1", values: { id: "unit-1" } });
|
|
182
|
-
});
|
|
183
|
-
|
|
184
|
-
await waitFor(() => {
|
|
185
|
-
expect(queryCallCount).toBe(countAfterMount + 1);
|
|
186
|
-
});
|
|
187
|
-
|
|
188
|
-
// Give any accidental extra refetch a chance to land before asserting
|
|
189
|
-
// there wasn't one (no double-fetch, no refetch loop).
|
|
190
|
-
await new Promise((resolve) => setTimeout(resolve, 20));
|
|
191
|
-
expect(queryCallCount).toBe(countAfterMount + 1);
|
|
192
|
-
});
|
|
193
|
-
|
|
194
|
-
test("a failed row-action write does not refetch the rows query", async () => {
|
|
195
|
-
capturedRowActions = undefined;
|
|
196
|
-
queryCallCount = 0;
|
|
197
|
-
writeIsSuccess = false;
|
|
198
|
-
|
|
199
|
-
renderListScreen();
|
|
200
|
-
|
|
201
|
-
await waitFor(() => {
|
|
202
|
-
expect(capturedRowActions).toBeDefined();
|
|
203
|
-
});
|
|
204
|
-
|
|
205
|
-
const countAfterMount = queryCallCount;
|
|
206
|
-
expect(countAfterMount).toBeGreaterThan(0);
|
|
207
|
-
|
|
208
|
-
await act(async () => {
|
|
209
|
-
await expect(
|
|
210
|
-
requireArchiveAction().onTrigger({ id: "unit-1", values: { id: "unit-1" } }),
|
|
211
|
-
).rejects.toThrow();
|
|
212
|
-
});
|
|
213
|
-
|
|
214
|
-
await new Promise((resolve) => setTimeout(resolve, 20));
|
|
215
|
-
expect(queryCallCount).toBe(countAfterMount);
|
|
216
|
-
});
|
|
217
|
-
});
|
|
218
|
-
|
|
219
|
-
// toolbarActions render through RenderList's `toolbarEnd` slot via the real
|
|
220
|
-
// ToolbarActionView primitive, not through the DataTable's `rowActions` prop
|
|
221
|
-
// (that's what captureDataTable above captures) — a stub that ignores
|
|
222
|
-
// `toolbarEnd` never mounts the button, so this needs its own DataTable stub
|
|
223
|
-
// that renders that slot, plus a real Button primitive to click through.
|
|
224
|
-
const TestButton: ComponentType<ButtonProps> = ({ children, onClick, testId }) => (
|
|
225
|
-
<button type="button" data-testid={testId} onClick={() => void onClick?.()}>
|
|
226
|
-
{children}
|
|
227
|
-
</button>
|
|
228
|
-
);
|
|
229
|
-
|
|
230
|
-
const renderToolbarEnd: ComponentType<DataTableProps> = (props) => <>{props.toolbarEnd}</>;
|
|
231
|
-
|
|
232
|
-
const toolbarTestPrimitives: CorePrimitives = {
|
|
233
|
-
...testPrimitives,
|
|
234
|
-
Button: TestButton,
|
|
235
|
-
DataTable: renderToolbarEnd,
|
|
236
|
-
};
|
|
237
|
-
|
|
238
|
-
function buildToolbarSchema(): FeatureSchema {
|
|
239
|
-
const entity: EntityDefinition = {
|
|
240
|
-
fields: {
|
|
241
|
-
status: {
|
|
242
|
-
type: "text",
|
|
243
|
-
maxLength: 50,
|
|
244
|
-
required: false,
|
|
245
|
-
searchable: false,
|
|
246
|
-
sortable: false,
|
|
247
|
-
},
|
|
248
|
-
},
|
|
249
|
-
};
|
|
250
|
-
const listScreen: EntityListScreenDefinition = {
|
|
251
|
-
id: "unit-list",
|
|
252
|
-
type: "entityList",
|
|
253
|
-
entity: "unit",
|
|
254
|
-
columns: ["status"],
|
|
255
|
-
toolbarActions: [
|
|
256
|
-
{
|
|
257
|
-
kind: "writeHandler",
|
|
258
|
-
id: "sync",
|
|
259
|
-
label: "Sync",
|
|
260
|
-
handler: "units:write:unit:sync",
|
|
261
|
-
},
|
|
262
|
-
],
|
|
263
|
-
};
|
|
264
|
-
return {
|
|
265
|
-
featureName: "units",
|
|
266
|
-
entities: { unit: entity },
|
|
267
|
-
screens: [listScreen],
|
|
268
|
-
} as FeatureSchema;
|
|
269
|
-
}
|
|
270
|
-
|
|
271
|
-
function renderToolbarListScreen(): void {
|
|
272
|
-
render(
|
|
273
|
-
<LocaleProvider
|
|
274
|
-
resolver={createStaticLocaleResolver({ locale: "de-DE" })}
|
|
275
|
-
fallbackBundles={[kumikoDefaultTranslations]}
|
|
276
|
-
>
|
|
277
|
-
<DispatcherProvider dispatcher={stubDispatcher()}>
|
|
278
|
-
<NavProvider
|
|
279
|
-
value={{
|
|
280
|
-
route: { screenId: "units:unit-list" },
|
|
281
|
-
navigate: () => {},
|
|
282
|
-
replace: () => {},
|
|
283
|
-
hrefFor: () => "",
|
|
284
|
-
searchParams: {},
|
|
285
|
-
setSearchParams: () => {},
|
|
286
|
-
}}
|
|
287
|
-
>
|
|
288
|
-
<PrimitivesProvider value={toolbarTestPrimitives}>
|
|
289
|
-
<KumikoScreen schema={buildToolbarSchema()} qn="units:screen:unit-list" />
|
|
290
|
-
</PrimitivesProvider>
|
|
291
|
-
</NavProvider>
|
|
292
|
-
</DispatcherProvider>
|
|
293
|
-
</LocaleProvider>,
|
|
294
|
-
);
|
|
295
|
-
}
|
|
296
|
-
|
|
297
|
-
describe("entityList toolbarAction writeHandler refetches the rows query", () => {
|
|
298
|
-
test("a successful toolbarAction write triggers exactly one refetch", async () => {
|
|
299
|
-
queryCallCount = 0;
|
|
300
|
-
writeIsSuccess = true;
|
|
301
|
-
|
|
302
|
-
renderToolbarListScreen();
|
|
303
|
-
|
|
304
|
-
const button = await waitFor(() => screen.getByTestId("render-list-toolbar-action-sync"));
|
|
305
|
-
const countAfterMount = queryCallCount;
|
|
306
|
-
expect(countAfterMount).toBeGreaterThan(0);
|
|
307
|
-
|
|
308
|
-
fireEvent.click(button);
|
|
309
|
-
|
|
310
|
-
await waitFor(() => {
|
|
311
|
-
expect(queryCallCount).toBe(countAfterMount + 1);
|
|
312
|
-
});
|
|
313
|
-
|
|
314
|
-
// Give any accidental extra refetch a chance to land before asserting
|
|
315
|
-
// there wasn't one.
|
|
316
|
-
await new Promise((resolve) => setTimeout(resolve, 20));
|
|
317
|
-
expect(queryCallCount).toBe(countAfterMount + 1);
|
|
318
|
-
});
|
|
319
|
-
});
|
|
320
|
-
|
|
321
|
-
// projectionList runs its own writeHandler-refetch path (ProjectionListBody,
|
|
322
|
-
// separate from EntityListBody above) — the copy-paste edit that added the
|
|
323
|
-
// refetch call there is untested without this.
|
|
324
|
-
function buildProjectionListSchema(): FeatureSchema {
|
|
325
|
-
const listScreen: ProjectionListScreenDefinition = {
|
|
326
|
-
id: "unit-projection-list",
|
|
327
|
-
type: "projectionList",
|
|
328
|
-
query: "units:query:unit:list",
|
|
329
|
-
columns: [{ field: "status", label: "Status" }],
|
|
330
|
-
rowActions: [
|
|
331
|
-
{
|
|
332
|
-
kind: "writeHandler",
|
|
333
|
-
id: "archive",
|
|
334
|
-
label: "Archive",
|
|
335
|
-
handler: "units:write:unit:archive",
|
|
336
|
-
},
|
|
337
|
-
],
|
|
338
|
-
};
|
|
339
|
-
return {
|
|
340
|
-
featureName: "units",
|
|
341
|
-
entities: {},
|
|
342
|
-
screens: [listScreen],
|
|
343
|
-
} as FeatureSchema;
|
|
344
|
-
}
|
|
345
|
-
|
|
346
|
-
function renderProjectionListScreen(): void {
|
|
347
|
-
render(
|
|
348
|
-
<LocaleProvider
|
|
349
|
-
resolver={createStaticLocaleResolver({ locale: "de-DE" })}
|
|
350
|
-
fallbackBundles={[kumikoDefaultTranslations]}
|
|
351
|
-
>
|
|
352
|
-
<DispatcherProvider dispatcher={stubDispatcher()}>
|
|
353
|
-
<NavProvider
|
|
354
|
-
value={{
|
|
355
|
-
route: { screenId: "units:unit-projection-list" },
|
|
356
|
-
navigate: () => {},
|
|
357
|
-
replace: () => {},
|
|
358
|
-
hrefFor: () => "",
|
|
359
|
-
searchParams: {},
|
|
360
|
-
setSearchParams: () => {},
|
|
361
|
-
}}
|
|
362
|
-
>
|
|
363
|
-
<PrimitivesProvider value={testPrimitives}>
|
|
364
|
-
<KumikoScreen
|
|
365
|
-
schema={buildProjectionListSchema()}
|
|
366
|
-
qn="units:screen:unit-projection-list"
|
|
367
|
-
/>
|
|
368
|
-
</PrimitivesProvider>
|
|
369
|
-
</NavProvider>
|
|
370
|
-
</DispatcherProvider>
|
|
371
|
-
</LocaleProvider>,
|
|
372
|
-
);
|
|
373
|
-
}
|
|
374
|
-
|
|
375
|
-
describe("projectionList row-action writeHandler refetches the rows query", () => {
|
|
376
|
-
test("a successful row-action write triggers exactly one refetch", async () => {
|
|
377
|
-
capturedRowActions = undefined;
|
|
378
|
-
queryCallCount = 0;
|
|
379
|
-
writeIsSuccess = true;
|
|
380
|
-
|
|
381
|
-
renderProjectionListScreen();
|
|
382
|
-
|
|
383
|
-
await waitFor(() => {
|
|
384
|
-
expect(capturedRowActions).toBeDefined();
|
|
385
|
-
});
|
|
386
|
-
|
|
387
|
-
const countAfterMount = queryCallCount;
|
|
388
|
-
expect(countAfterMount).toBeGreaterThan(0);
|
|
389
|
-
|
|
390
|
-
await act(async () => {
|
|
391
|
-
await requireArchiveAction().onTrigger({ id: "unit-1", values: { id: "unit-1" } });
|
|
392
|
-
});
|
|
393
|
-
|
|
394
|
-
await waitFor(() => {
|
|
395
|
-
expect(queryCallCount).toBe(countAfterMount + 1);
|
|
396
|
-
});
|
|
397
|
-
|
|
398
|
-
await new Promise((resolve) => setTimeout(resolve, 20));
|
|
399
|
-
expect(queryCallCount).toBe(countAfterMount + 1);
|
|
400
|
-
});
|
|
401
|
-
});
|
|
@@ -1,111 +0,0 @@
|
|
|
1
|
-
// A list screen's chrome is the DataTable's own outer wrapper — no
|
|
2
|
-
// FormScreenShell/PageSection sits around it. `screenPadding` is how that
|
|
3
|
-
// wrapper reaches the shared screen-padding token, so it has to be set on the
|
|
4
|
-
// real list path (KumikoScreen → EntityListScreen → EntityListBody →
|
|
5
|
-
// RenderList), not just be available on the primitive (fw#2640).
|
|
6
|
-
import { describe, expect, test } from "bun:test";
|
|
7
|
-
import type {
|
|
8
|
-
EntityDefinition,
|
|
9
|
-
EntityListScreenDefinition,
|
|
10
|
-
} from "@cosmicdrift/kumiko-framework/ui-types";
|
|
11
|
-
import type { Dispatcher } from "@cosmicdrift/kumiko-headless";
|
|
12
|
-
import { render, waitFor } from "@testing-library/react";
|
|
13
|
-
import type { ComponentType, ReactNode } from "react";
|
|
14
|
-
import { DispatcherProvider } from "../../context/dispatcher-context";
|
|
15
|
-
import { createStaticLocaleResolver, LocaleProvider } from "../../i18n";
|
|
16
|
-
import { type CorePrimitives, type DataTableProps, PrimitivesProvider } from "../../primitives";
|
|
17
|
-
import type { FeatureSchema } from "../feature-schema";
|
|
18
|
-
import { KumikoScreen } from "../kumiko-screen";
|
|
19
|
-
import { NavProvider } from "../nav";
|
|
20
|
-
|
|
21
|
-
const noop = (): ReactNode => null;
|
|
22
|
-
const passChildren = ({ children }: { readonly children?: ReactNode }): ReactNode => children;
|
|
23
|
-
|
|
24
|
-
function stubDispatcher(): Dispatcher {
|
|
25
|
-
return {
|
|
26
|
-
write: (async () => ({ isSuccess: true, data: {} })) as unknown as Dispatcher["write"],
|
|
27
|
-
query: (async () => ({
|
|
28
|
-
isSuccess: true,
|
|
29
|
-
data: { rows: [], total: 0 },
|
|
30
|
-
})) as unknown as Dispatcher["query"],
|
|
31
|
-
batch: (async () => ({ isSuccess: true, results: [] })) as unknown as Dispatcher["batch"],
|
|
32
|
-
statusStore: {
|
|
33
|
-
getState: () => "online",
|
|
34
|
-
subscribe: () => () => {},
|
|
35
|
-
} as unknown as Dispatcher["statusStore"],
|
|
36
|
-
async *stream() {},
|
|
37
|
-
pendingWrites: () => [],
|
|
38
|
-
pendingFiles: () => [],
|
|
39
|
-
};
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
function buildSchema(): FeatureSchema {
|
|
43
|
-
const entity: EntityDefinition = {
|
|
44
|
-
fields: {
|
|
45
|
-
name: { type: "text", maxLength: 200, required: false, searchable: false, sortable: false },
|
|
46
|
-
},
|
|
47
|
-
};
|
|
48
|
-
const listScreen: EntityListScreenDefinition = {
|
|
49
|
-
id: "org-list",
|
|
50
|
-
type: "entityList",
|
|
51
|
-
entity: "org",
|
|
52
|
-
columns: ["name"],
|
|
53
|
-
};
|
|
54
|
-
return {
|
|
55
|
-
featureName: "orgs",
|
|
56
|
-
entities: { org: entity },
|
|
57
|
-
screens: [listScreen],
|
|
58
|
-
} as FeatureSchema;
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
describe("entityList screen padding (fw#2640)", () => {
|
|
62
|
-
test("the list screen marks its table as the screen body", async () => {
|
|
63
|
-
let capturedScreenPadding: boolean | undefined;
|
|
64
|
-
const capturingDataTable: ComponentType<DataTableProps> = (props) => {
|
|
65
|
-
capturedScreenPadding = props.screenPadding;
|
|
66
|
-
return null;
|
|
67
|
-
};
|
|
68
|
-
const primitives: CorePrimitives = {
|
|
69
|
-
Button: noop,
|
|
70
|
-
Banner: passChildren,
|
|
71
|
-
Field: passChildren,
|
|
72
|
-
Input: noop,
|
|
73
|
-
DataTable: capturingDataTable,
|
|
74
|
-
Form: passChildren,
|
|
75
|
-
Section: passChildren,
|
|
76
|
-
Card: passChildren,
|
|
77
|
-
Grid: passChildren,
|
|
78
|
-
GridCell: passChildren,
|
|
79
|
-
Text: passChildren,
|
|
80
|
-
Heading: noop,
|
|
81
|
-
Dialog: noop,
|
|
82
|
-
Modal: noop,
|
|
83
|
-
Lightbox: noop,
|
|
84
|
-
ConfigSourceBadge: noop,
|
|
85
|
-
ConfigCascadeView: noop,
|
|
86
|
-
Link: noop,
|
|
87
|
-
};
|
|
88
|
-
render(
|
|
89
|
-
<LocaleProvider resolver={createStaticLocaleResolver({ locale: "de-DE" })}>
|
|
90
|
-
<DispatcherProvider dispatcher={stubDispatcher()}>
|
|
91
|
-
<NavProvider
|
|
92
|
-
value={{
|
|
93
|
-
route: { screenId: "orgs:org-list" },
|
|
94
|
-
navigate: () => {},
|
|
95
|
-
replace: () => {},
|
|
96
|
-
hrefFor: () => "",
|
|
97
|
-
searchParams: {},
|
|
98
|
-
setSearchParams: () => {},
|
|
99
|
-
}}
|
|
100
|
-
>
|
|
101
|
-
<PrimitivesProvider value={primitives}>
|
|
102
|
-
<KumikoScreen schema={buildSchema()} qn="orgs:screen:org-list" />
|
|
103
|
-
</PrimitivesProvider>
|
|
104
|
-
</NavProvider>
|
|
105
|
-
</DispatcherProvider>
|
|
106
|
-
</LocaleProvider>,
|
|
107
|
-
);
|
|
108
|
-
|
|
109
|
-
await waitFor(() => expect(capturedScreenPadding).toBe(true));
|
|
110
|
-
});
|
|
111
|
-
});
|