@vaadin/hilla-react-crud 24.4.0-alpha1

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.
Files changed (172) hide show
  1. package/.lintstagedrc.js +6 -0
  2. package/LICENSE +201 -0
  3. package/README.md +27 -0
  4. package/autocrud-dialog.d.ts +11 -0
  5. package/autocrud-dialog.d.ts.map +1 -0
  6. package/autocrud-dialog.js +24 -0
  7. package/autocrud-dialog.js.map +7 -0
  8. package/autocrud-feature.d.ts +4 -0
  9. package/autocrud-feature.d.ts.map +1 -0
  10. package/autocrud-feature.js +8 -0
  11. package/autocrud-feature.js.map +7 -0
  12. package/autocrud.d.ts +82 -0
  13. package/autocrud.d.ts.map +1 -0
  14. package/autocrud.js +94 -0
  15. package/autocrud.js.map +7 -0
  16. package/autocrud.obj.js +6 -0
  17. package/autocrud.obj.js.map +7 -0
  18. package/autoform-feature.d.ts +4 -0
  19. package/autoform-feature.d.ts.map +1 -0
  20. package/autoform-feature.js +8 -0
  21. package/autoform-feature.js.map +7 -0
  22. package/autoform-field.d.ts +122 -0
  23. package/autoform-field.d.ts.map +1 -0
  24. package/autoform-field.js +118 -0
  25. package/autoform-field.js.map +7 -0
  26. package/autoform.d.ts +228 -0
  27. package/autoform.d.ts.map +1 -0
  28. package/autoform.js +178 -0
  29. package/autoform.js.map +7 -0
  30. package/autoform.obj.js +6 -0
  31. package/autoform.obj.js.map +7 -0
  32. package/autogrid-column-context.d.ts +39 -0
  33. package/autogrid-column-context.d.ts.map +1 -0
  34. package/autogrid-column-context.js +8 -0
  35. package/autogrid-column-context.js.map +7 -0
  36. package/autogrid-columns.d.ts +6 -0
  37. package/autogrid-columns.d.ts.map +1 -0
  38. package/autogrid-columns.js +102 -0
  39. package/autogrid-columns.js.map +7 -0
  40. package/autogrid-feature.d.ts +4 -0
  41. package/autogrid-feature.d.ts.map +1 -0
  42. package/autogrid-feature.js +8 -0
  43. package/autogrid-feature.js.map +7 -0
  44. package/autogrid-renderers.d.ts +28 -0
  45. package/autogrid-renderers.d.ts.map +1 -0
  46. package/autogrid-renderers.js +92 -0
  47. package/autogrid-renderers.js.map +7 -0
  48. package/autogrid.d.ts +130 -0
  49. package/autogrid.d.ts.map +1 -0
  50. package/autogrid.js +234 -0
  51. package/autogrid.js.map +7 -0
  52. package/autogrid.obj.js +6 -0
  53. package/autogrid.obj.js.map +7 -0
  54. package/crud.d.js +1 -0
  55. package/crud.d.js.map +7 -0
  56. package/crud.d.ts +17 -0
  57. package/data-provider.d.ts +56 -0
  58. package/data-provider.d.ts.map +1 -0
  59. package/data-provider.js +121 -0
  60. package/data-provider.js.map +7 -0
  61. package/header-filter.d.ts +54 -0
  62. package/header-filter.d.ts.map +1 -0
  63. package/header-filter.js +258 -0
  64. package/header-filter.js.map +7 -0
  65. package/header-sorter.d.ts +3 -0
  66. package/header-sorter.d.ts.map +1 -0
  67. package/header-sorter.js +28 -0
  68. package/header-sorter.js.map +7 -0
  69. package/i18n.d.ts +2 -0
  70. package/i18n.d.ts.map +1 -0
  71. package/i18n.js +5 -0
  72. package/i18n.js.map +7 -0
  73. package/index.d.ts +5 -0
  74. package/index.d.ts.map +1 -0
  75. package/index.js +13 -0
  76. package/index.js.map +7 -0
  77. package/locale.d.ts +19 -0
  78. package/locale.d.ts.map +1 -0
  79. package/locale.js +123 -0
  80. package/locale.js.map +7 -0
  81. package/media-query.d.ts +2 -0
  82. package/media-query.d.ts.map +1 -0
  83. package/media-query.js +16 -0
  84. package/media-query.js.map +7 -0
  85. package/model-info.d.ts +23 -0
  86. package/model-info.d.ts.map +1 -0
  87. package/model-info.js +137 -0
  88. package/model-info.js.map +7 -0
  89. package/package.json +87 -0
  90. package/types/com/vaadin/hilla/crud/filter/AndFilter.d.js +1 -0
  91. package/types/com/vaadin/hilla/crud/filter/AndFilter.d.js.map +7 -0
  92. package/types/com/vaadin/hilla/crud/filter/AndFilter.d.ts +6 -0
  93. package/types/com/vaadin/hilla/crud/filter/AndFilterModel.d.ts +9 -0
  94. package/types/com/vaadin/hilla/crud/filter/AndFilterModel.d.ts.map +1 -0
  95. package/types/com/vaadin/hilla/crud/filter/AndFilterModel.js +13 -0
  96. package/types/com/vaadin/hilla/crud/filter/AndFilterModel.js.map +7 -0
  97. package/types/com/vaadin/hilla/crud/filter/Filter.d.js +1 -0
  98. package/types/com/vaadin/hilla/crud/filter/Filter.d.js.map +7 -0
  99. package/types/com/vaadin/hilla/crud/filter/Filter.d.ts +3 -0
  100. package/types/com/vaadin/hilla/crud/filter/FilterModel.d.ts +7 -0
  101. package/types/com/vaadin/hilla/crud/filter/FilterModel.d.ts.map +1 -0
  102. package/types/com/vaadin/hilla/crud/filter/FilterModel.js +9 -0
  103. package/types/com/vaadin/hilla/crud/filter/FilterModel.js.map +7 -0
  104. package/types/com/vaadin/hilla/crud/filter/FilterUnion.d.js +1 -0
  105. package/types/com/vaadin/hilla/crud/filter/FilterUnion.d.js.map +7 -0
  106. package/types/com/vaadin/hilla/crud/filter/FilterUnion.d.ts +5 -0
  107. package/types/com/vaadin/hilla/crud/filter/OrFilter.d.js +1 -0
  108. package/types/com/vaadin/hilla/crud/filter/OrFilter.d.js.map +7 -0
  109. package/types/com/vaadin/hilla/crud/filter/OrFilter.d.ts +6 -0
  110. package/types/com/vaadin/hilla/crud/filter/OrFilterModel.d.ts +9 -0
  111. package/types/com/vaadin/hilla/crud/filter/OrFilterModel.d.ts.map +1 -0
  112. package/types/com/vaadin/hilla/crud/filter/OrFilterModel.js +13 -0
  113. package/types/com/vaadin/hilla/crud/filter/OrFilterModel.js.map +7 -0
  114. package/types/com/vaadin/hilla/crud/filter/PropertyStringFilter/Matcher.d.ts +8 -0
  115. package/types/com/vaadin/hilla/crud/filter/PropertyStringFilter/Matcher.d.ts.map +1 -0
  116. package/types/com/vaadin/hilla/crud/filter/PropertyStringFilter/Matcher.js +12 -0
  117. package/types/com/vaadin/hilla/crud/filter/PropertyStringFilter/Matcher.js.map +7 -0
  118. package/types/com/vaadin/hilla/crud/filter/PropertyStringFilter/MatcherModel.d.ts +8 -0
  119. package/types/com/vaadin/hilla/crud/filter/PropertyStringFilter/MatcherModel.d.ts.map +1 -0
  120. package/types/com/vaadin/hilla/crud/filter/PropertyStringFilter/MatcherModel.js +11 -0
  121. package/types/com/vaadin/hilla/crud/filter/PropertyStringFilter/MatcherModel.js.map +7 -0
  122. package/types/com/vaadin/hilla/crud/filter/PropertyStringFilter.d.js +1 -0
  123. package/types/com/vaadin/hilla/crud/filter/PropertyStringFilter.d.js.map +7 -0
  124. package/types/com/vaadin/hilla/crud/filter/PropertyStringFilter.d.ts +9 -0
  125. package/types/com/vaadin/hilla/crud/filter/PropertyStringFilterModel.d.ts +12 -0
  126. package/types/com/vaadin/hilla/crud/filter/PropertyStringFilterModel.d.ts.map +1 -0
  127. package/types/com/vaadin/hilla/crud/filter/PropertyStringFilterModel.js +20 -0
  128. package/types/com/vaadin/hilla/crud/filter/PropertyStringFilterModel.js.map +7 -0
  129. package/types/com/vaadin/hilla/mappedtypes/Order.d.js +1 -0
  130. package/types/com/vaadin/hilla/mappedtypes/Order.d.js.map +7 -0
  131. package/types/com/vaadin/hilla/mappedtypes/Order.d.ts +9 -0
  132. package/types/com/vaadin/hilla/mappedtypes/OrderModel.d.ts +13 -0
  133. package/types/com/vaadin/hilla/mappedtypes/OrderModel.d.ts.map +1 -0
  134. package/types/com/vaadin/hilla/mappedtypes/OrderModel.js +23 -0
  135. package/types/com/vaadin/hilla/mappedtypes/OrderModel.js.map +7 -0
  136. package/types/com/vaadin/hilla/mappedtypes/Pageable.d.js +1 -0
  137. package/types/com/vaadin/hilla/mappedtypes/Pageable.d.js.map +7 -0
  138. package/types/com/vaadin/hilla/mappedtypes/Pageable.d.ts +7 -0
  139. package/types/com/vaadin/hilla/mappedtypes/PageableModel.d.ts +11 -0
  140. package/types/com/vaadin/hilla/mappedtypes/PageableModel.d.ts.map +1 -0
  141. package/types/com/vaadin/hilla/mappedtypes/PageableModel.js +19 -0
  142. package/types/com/vaadin/hilla/mappedtypes/PageableModel.js.map +7 -0
  143. package/types/com/vaadin/hilla/mappedtypes/Sort.d.js +1 -0
  144. package/types/com/vaadin/hilla/mappedtypes/Sort.d.js.map +7 -0
  145. package/types/com/vaadin/hilla/mappedtypes/Sort.d.ts +5 -0
  146. package/types/com/vaadin/hilla/mappedtypes/SortModel.d.ts +9 -0
  147. package/types/com/vaadin/hilla/mappedtypes/SortModel.d.ts.map +1 -0
  148. package/types/com/vaadin/hilla/mappedtypes/SortModel.js +13 -0
  149. package/types/com/vaadin/hilla/mappedtypes/SortModel.js.map +7 -0
  150. package/types/org/springframework/data/domain/Sort/Direction.d.ts +6 -0
  151. package/types/org/springframework/data/domain/Sort/Direction.d.ts.map +1 -0
  152. package/types/org/springframework/data/domain/Sort/Direction.js +10 -0
  153. package/types/org/springframework/data/domain/Sort/Direction.js.map +7 -0
  154. package/types/org/springframework/data/domain/Sort/DirectionModel.d.ts +8 -0
  155. package/types/org/springframework/data/domain/Sort/DirectionModel.d.ts.map +1 -0
  156. package/types/org/springframework/data/domain/Sort/DirectionModel.js +11 -0
  157. package/types/org/springframework/data/domain/Sort/DirectionModel.js.map +7 -0
  158. package/types/org/springframework/data/domain/Sort/NullHandling.d.ts +7 -0
  159. package/types/org/springframework/data/domain/Sort/NullHandling.d.ts.map +1 -0
  160. package/types/org/springframework/data/domain/Sort/NullHandling.js +11 -0
  161. package/types/org/springframework/data/domain/Sort/NullHandling.js.map +7 -0
  162. package/types/org/springframework/data/domain/Sort/NullHandlingModel.d.ts +8 -0
  163. package/types/org/springframework/data/domain/Sort/NullHandlingModel.d.ts.map +1 -0
  164. package/types/org/springframework/data/domain/Sort/NullHandlingModel.js +11 -0
  165. package/types/org/springframework/data/domain/Sort/NullHandlingModel.js.map +7 -0
  166. package/types.d.js +1 -0
  167. package/types.d.js.map +7 -0
  168. package/types.d.ts +12 -0
  169. package/util.d.ts +12 -0
  170. package/util.d.ts.map +1 -0
  171. package/util.js +55 -0
  172. package/util.js.map +7 -0
package/autoform.js ADDED
@@ -0,0 +1,178 @@
1
+ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
2
+ import { EndpointError } from "@vaadin/hilla-core";
3
+ import { ValidationError } from "@vaadin/hilla-lit-form";
4
+ import { useForm } from "@vaadin/hilla-react-form";
5
+ import { Button } from "@vaadin/react-components/Button.js";
6
+ import { ConfirmDialog } from "@vaadin/react-components/ConfirmDialog";
7
+ import { FormLayout } from "@vaadin/react-components/FormLayout";
8
+ import { VerticalLayout } from "@vaadin/react-components/VerticalLayout.js";
9
+ import {
10
+ useEffect,
11
+ useMemo,
12
+ useState
13
+ } from "react";
14
+ import { AutoFormField } from "./autoform-field.js";
15
+ import css from "./autoform.obj.js";
16
+ import { getDefaultProperties, ModelInfo } from "./model-info.js";
17
+ import { registerStylesheet } from "./util.js";
18
+ registerStylesheet(css);
19
+ const emptyItem = Symbol();
20
+ function AutoForm({
21
+ service,
22
+ model,
23
+ itemIdProperty,
24
+ item = emptyItem,
25
+ onSubmitError,
26
+ onSubmitSuccess,
27
+ disabled,
28
+ layoutRenderer: LayoutRenderer,
29
+ visibleFields,
30
+ formLayoutProps,
31
+ fieldOptions,
32
+ style,
33
+ id,
34
+ className,
35
+ deleteButtonVisible,
36
+ onDeleteSuccess,
37
+ onDeleteError
38
+ }) {
39
+ const form = useForm(model, {
40
+ onSubmit: async (formItem) => service.save(formItem)
41
+ });
42
+ const [formError, setFormError] = useState("");
43
+ const [showDeleteDialog, setShowDeleteDialog] = useState(false);
44
+ const modelInfo = useMemo(() => new ModelInfo(model, itemIdProperty), [model]);
45
+ const isEditMode = item !== void 0 && item !== null && item !== emptyItem;
46
+ const showDeleteButton = deleteButtonVisible && isEditMode && modelInfo.idProperty;
47
+ const isSubmitDisabled = !!disabled || isEditMode && !form.dirty;
48
+ useEffect(() => {
49
+ if (item !== emptyItem) {
50
+ form.read(item);
51
+ } else {
52
+ form.clear();
53
+ }
54
+ }, [item]);
55
+ function handleSubmitError(error) {
56
+ if (error instanceof ValidationError) {
57
+ const nonPropertyErrorMessages = error.errors.filter((validationError) => !validationError.property).map((validationError) => validationError.validatorMessage ?? validationError.message);
58
+ if (nonPropertyErrorMessages.length > 0) {
59
+ setFormError(
60
+ /* @__PURE__ */ jsxs(Fragment, { children: [
61
+ "Validation errors:",
62
+ /* @__PURE__ */ jsx("ul", { children: nonPropertyErrorMessages.map((message, index) => /* @__PURE__ */ jsx("li", { children: message }, index)) })
63
+ ] })
64
+ );
65
+ }
66
+ } else if (error instanceof EndpointError) {
67
+ if (onSubmitError) {
68
+ onSubmitError({ error, setMessage: setFormError });
69
+ } else {
70
+ setFormError(error.message);
71
+ }
72
+ } else {
73
+ throw error;
74
+ }
75
+ }
76
+ async function handleSubmit() {
77
+ try {
78
+ setFormError("");
79
+ const newItem = await form.submit();
80
+ if (newItem === void 0) {
81
+ throw new EndpointError("No update performed");
82
+ } else if (onSubmitSuccess) {
83
+ onSubmitSuccess({ item: newItem });
84
+ }
85
+ if (!item || item === emptyItem) {
86
+ form.clear();
87
+ }
88
+ } catch (error) {
89
+ handleSubmitError(error);
90
+ }
91
+ }
92
+ function deleteItem() {
93
+ setShowDeleteDialog(true);
94
+ }
95
+ async function confirmDelete() {
96
+ const deletedItem = item;
97
+ try {
98
+ const idProperty = modelInfo.idProperty;
99
+ const id2 = item[idProperty.name];
100
+ await service.delete(id2);
101
+ if (onDeleteSuccess) {
102
+ onDeleteSuccess({ item: deletedItem });
103
+ }
104
+ } catch (error) {
105
+ if (error instanceof EndpointError) {
106
+ if (onDeleteError) {
107
+ onDeleteError({ error, setMessage: setFormError });
108
+ } else {
109
+ setFormError(error.message);
110
+ }
111
+ } else {
112
+ throw error;
113
+ }
114
+ } finally {
115
+ setShowDeleteDialog(false);
116
+ }
117
+ }
118
+ function cancelDelete() {
119
+ setShowDeleteDialog(false);
120
+ }
121
+ const handleKeyDown = (event) => {
122
+ if (event.key === "Enter" && !isSubmitDisabled) {
123
+ void handleSubmit();
124
+ }
125
+ };
126
+ function createAutoFormField(propertyInfo) {
127
+ const fieldOptionsForProperty = fieldOptions?.[propertyInfo.name] ?? {};
128
+ return /* @__PURE__ */ jsx(
129
+ AutoFormField,
130
+ {
131
+ propertyInfo,
132
+ form,
133
+ disabled,
134
+ options: fieldOptionsForProperty
135
+ },
136
+ propertyInfo.name
137
+ );
138
+ }
139
+ const visibleProperties = visibleFields ? modelInfo.getProperties(visibleFields) : getDefaultProperties(modelInfo);
140
+ const fields = visibleProperties.map(createAutoFormField);
141
+ const layout = LayoutRenderer ? /* @__PURE__ */ jsx(LayoutRenderer, { form, children: fields }) : /* @__PURE__ */ jsx(FormLayout, { ...formLayoutProps, children: fields });
142
+ return /* @__PURE__ */ jsxs("div", { className: `auto-form ${className ?? ""}`, id, style, "data-testid": "auto-form", children: [
143
+ /* @__PURE__ */ jsxs(VerticalLayout, { className: "auto-form-fields", onKeyDown: handleKeyDown, children: [
144
+ layout,
145
+ formError ? /* @__PURE__ */ jsx("div", { style: { color: "var(--lumo-error-color)" }, children: formError }) : /* @__PURE__ */ jsx(Fragment, {})
146
+ ] }),
147
+ /* @__PURE__ */ jsxs("div", { className: "auto-form-toolbar", children: [
148
+ /* @__PURE__ */ jsx(
149
+ Button,
150
+ {
151
+ theme: "primary",
152
+ disabled: isSubmitDisabled,
153
+ onClick: handleSubmit,
154
+ children: "Submit"
155
+ }
156
+ ),
157
+ form.dirty ? /* @__PURE__ */ jsx(Button, { theme: "tertiary", onClick: () => form.reset(), children: "Discard" }) : null,
158
+ showDeleteButton && /* @__PURE__ */ jsx(Button, { className: "auto-form-delete-button", theme: "tertiary error", onClick: deleteItem, children: "Delete..." })
159
+ ] }),
160
+ showDeleteDialog && /* @__PURE__ */ jsx(
161
+ ConfirmDialog,
162
+ {
163
+ opened: true,
164
+ header: "Delete item",
165
+ confirmTheme: "error",
166
+ cancelButtonVisible: true,
167
+ onConfirm: confirmDelete,
168
+ onCancel: cancelDelete,
169
+ children: "Are you sure you want to delete the selected item?"
170
+ }
171
+ )
172
+ ] });
173
+ }
174
+ export {
175
+ AutoForm,
176
+ emptyItem
177
+ };
178
+ //# sourceMappingURL=autoform.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["src/autoform.tsx"],
4
+ "sourcesContent": ["import { EndpointError } from '@vaadin/hilla-core';\nimport { type AbstractModel, type DetachedModelConstructor, ValidationError, type Value } from '@vaadin/hilla-lit-form';\nimport { useForm, type UseFormResult } from '@vaadin/hilla-react-form';\nimport { Button } from '@vaadin/react-components/Button.js';\nimport { ConfirmDialog } from '@vaadin/react-components/ConfirmDialog';\nimport { FormLayout } from '@vaadin/react-components/FormLayout';\nimport { VerticalLayout } from '@vaadin/react-components/VerticalLayout.js';\nimport {\n type ComponentType,\n type JSX,\n type KeyboardEvent,\n type ReactElement,\n useEffect,\n useMemo,\n useState,\n} from 'react';\nimport { AutoFormField, type AutoFormFieldProps, type FieldOptions } from './autoform-field.js';\nimport css from './autoform.obj.js';\nimport type { FormService } from './crud.js';\nimport { getDefaultProperties, ModelInfo, type PropertyInfo } from './model-info.js';\nimport { type ComponentStyleProps, registerStylesheet } from './util.js';\n\nregisterStylesheet(css);\n\nexport const emptyItem = Symbol();\n\n/**\n * An event that is fired when an error occurs while submitting the form.\n */\nexport type SubmitErrorEvent = {\n /**\n * The error that occurred.\n */\n error: EndpointError;\n /**\n * A function that can be used to set a custom error message. This will be\n * shown in the form at the same position as the default error message.\n * You are not required to call this function if you want to handle the\n * error differently.\n */\n setMessage(message: string): void;\n};\n\n/**\n * An event that is fired when the form has been successfully submitted.\n */\nexport type SubmitEvent<TItem> = {\n /**\n * The item that was submitted, as returned by the service.\n */\n item: TItem;\n};\n\n/**\n * An event that is fired when an error occurs while deleting an item.\n */\nexport type DeleteErrorEvent = {\n /**\n * The error that occurred.\n */\n error: EndpointError;\n /**\n * A function that can be used to set a custom error message. This will be\n * shown in the form at the same position as the default error message.\n * You are not required to call this function if you want to handle the\n * error differently.\n */\n setMessage(message: string): void;\n};\n\n/**\n * An event that is fired when the form has been successfully deleted.\n */\nexport type DeleteEvent<TItem> = {\n /**\n * The item that was deleted, as returned by the service.\n */\n item: TItem;\n};\n\nexport type AutoFormLayoutRendererProps<M extends AbstractModel> = Readonly<{\n form: UseFormResult<M>;\n children: ReadonlyArray<ReactElement<AutoFormFieldProps>>;\n}>;\n\nexport type AutoFormProps<M extends AbstractModel = AbstractModel> = ComponentStyleProps &\n Readonly<{\n /**\n * The service to use for saving and deleting items. This must be a\n * TypeScript service that has been generated by Hilla from a backend Java\n * service that implements the `com.vaadin.hilla.crud.FormService` interface.\n */\n service: FormService<Value<M>>;\n /**\n * The entity model to use, which determines which fields to show in the\n * form. This must be a Typescript model class that has been generated by\n * Hilla from a backend Java class. The model must match with the type of\n * the items handled by the service. For example, a `PersonModel` can be\n * used with a service that handles `Person` instances.\n *\n * By default, the form shows fields for all properties of the model which\n * have a type that is supported. Use the `visibleFields` option to customize\n * which fields to show and in which order.\n */\n model: DetachedModelConstructor<M>;\n /**\n * The property to use to detect an item's ID. The item ID is required for\n * deleting items via the `FormService.delete` method. The delete button\n * will not be shown if no item ID can be found.\n *\n * By default, the component uses the property annotated with\n * `jakarta.persistence.Id`, or a property named `id`, in that order.\n * This option can be used to override the default behavior, or define the ID\n * property in case a class doesn't have a property matching the defaults.\n */\n itemIdProperty?: string;\n /**\n * The item to edit in the form. The form fields are automatically populated\n * with values from the item's properties. In order to create a new item,\n * either pass `null`, or leave this prop as undefined.\n *\n * Use the `onSubmitSuccess` callback to get notified when the item has been\n * saved.\n *\n * When submitting a new item (i.e. when `item` is null or undefined), the\n * form will be automatically cleared, allowing to submit another new item.\n * In order to keep editing the same item after submitting, set the `item`\n * prop to the new item.\n */\n item?: Value<M> | typeof emptyItem | null;\n /**\n * Whether the form should be disabled. This disables all form fields and\n * all buttons.\n */\n disabled?: boolean;\n /**\n * Allows to customize the layout of the form by providing a custom\n * renderer. The renderer receives the form instance and the pre-rendered\n * fields as props. The renderer can either reuse the pre-rendered fields in\n * the custom layout, or render custom fields and connect them to the form\n * manually.\n *\n * Check the component documentation for details and examples.\n *\n * Example using pre-rendered fields:\n * ```tsx\n * <AutoForm layoutRenderer={({ children }) =>\n * <VerticalLayout>\n * {children}\n * <p>All data is collected anonymously.</p>\n * </VerticalLayout>\n * } />\n * ```\n *\n * Example rendering custom fields:\n * ```tsx\n * <AutoForm layoutRenderer={({ form }) =>\n * <VerticalLayout>\n * <TextField {...form.field(form.model.name)} />\n * ...\n * </VerticalLayout>\n * } />\n * ```\n */\n layoutRenderer?: ComponentType<AutoFormLayoutRendererProps<M>>;\n /**\n * Defines the fields to show in the form, and in which order. This takes\n * an array of property names. Properties that are not included in this\n * array will not be shown in the form, and properties that are included,\n * but don't exist in the model, will be ignored.\n */\n visibleFields?: string[];\n /**\n * Allows to customize the FormLayout used by default. This is especially useful\n * to define the `responsiveSteps`. See the\n * {@link https://hilla.dev/docs/react/components/form-layout | FormLayout documentation}\n * for details.\n */\n formLayoutProps?: ComponentStyleProps & Pick<Parameters<typeof FormLayout>[0], 'responsiveSteps'>;\n /**\n * Allows to customize individual fields of the form. This takes an object\n * where the keys are property names, and the values are options for the\n * respective field for editing that property.\n */\n fieldOptions?: Record<string, FieldOptions>;\n /**\n * Whether to show the delete button in the form. This is disabled by\n * default. If enabled, the delete button will only be shown when editing\n * an existing item, which means that `item` is not null. The delete button\n * will also only be shown if an item has a discernible ID. See the\n * `itemIdProperty` prop for details how the item ID is detected.\n *\n * Use the `onDeleteSuccess` callback to get notified when the item has been\n * deleted.\n *\n * NOTE: This only hides the button, it does not prevent from calling the\n * delete method on the service. To completely disable deleting, you must\n * override the `delete` method in the backend Java service to either throw\n * an exception or annotate it with `@DenyAll` to prevent access.\n */\n deleteButtonVisible?: boolean;\n /**\n * A callback that will be called if an unexpected error occurs while\n * submitting the form.\n *\n * Note that this will not be called for validation errors, which are\n * handled automatically.\n */\n onSubmitError?({ error }: SubmitErrorEvent): void;\n /**\n * A callback that will be called after the form has been successfully\n * submitted and the item has been saved.\n *\n * When submitting a new item (i.e. when `item` is null or undefined), the\n * form will be automatically cleared, allowing to submit another new item.\n * In order to keep editing the same item after submitting, set the `item`\n * prop to the new item.\n */\n onSubmitSuccess?({ item }: SubmitEvent<Value<M>>): void;\n /**\n * A callback that will be called if an unexpected error occurs while\n * deleting an item.\n */\n onDeleteError?({ error }: DeleteErrorEvent): void;\n /**\n * A callback that will be called after the form has been successfully\n * deleted.\n */\n onDeleteSuccess?({ item }: DeleteEvent<Value<M>>): void;\n }>;\n\n/**\n * Auto Form is a component that automatically generates a form for editing,\n * updating and deleting items from a backend service.\n *\n * Example usage:\n * ```tsx\n * import { AutoForm } from '@hilla/react-crud';\n * import PersonService from 'Frontend/generated/endpoints';\n * import PersonModel from 'Frontend/generated/com/example/application/Person';\n *\n * <AutoForm\n * service={PersonService}\n * model={PersonModel}\n * onSubmitSuccess={({ item }) => {\n * console.log('Submitted item:', item);\n * }}\n * />\n * ```\n */\nexport function AutoForm<M extends AbstractModel>({\n service,\n model,\n itemIdProperty,\n item = emptyItem,\n onSubmitError,\n onSubmitSuccess,\n disabled,\n layoutRenderer: LayoutRenderer,\n visibleFields,\n formLayoutProps,\n fieldOptions,\n style,\n id,\n className,\n deleteButtonVisible,\n onDeleteSuccess,\n onDeleteError,\n}: AutoFormProps<M>): JSX.Element {\n const form = useForm(model, {\n onSubmit: async (formItem) => service.save(formItem),\n });\n const [formError, setFormError] = useState<JSX.Element | string>('');\n const [showDeleteDialog, setShowDeleteDialog] = useState(false);\n const modelInfo = useMemo(() => new ModelInfo(model, itemIdProperty), [model]);\n\n const isEditMode = item !== undefined && item !== null && item !== emptyItem;\n const showDeleteButton = deleteButtonVisible && isEditMode && modelInfo.idProperty;\n const isSubmitDisabled = !!disabled || (isEditMode && !form.dirty);\n\n useEffect(() => {\n if (item !== emptyItem) {\n form.read(item);\n } else {\n form.clear();\n }\n }, [item]);\n\n function handleSubmitError(error: unknown) {\n if (error instanceof ValidationError) {\n const nonPropertyErrorMessages = error.errors\n .filter((validationError) => !validationError.property)\n .map((validationError) => validationError.validatorMessage ?? validationError.message);\n if (nonPropertyErrorMessages.length > 0) {\n setFormError(\n <>\n Validation errors:\n <ul>\n {nonPropertyErrorMessages.map((message, index) => (\n <li key={index}>{message}</li>\n ))}\n </ul>\n </>,\n );\n }\n } else if (error instanceof EndpointError) {\n if (onSubmitError) {\n onSubmitError({ error, setMessage: setFormError });\n } else {\n setFormError(error.message);\n }\n } else {\n throw error;\n }\n }\n\n async function handleSubmit(): Promise<void> {\n try {\n setFormError('');\n const newItem = await form.submit();\n if (newItem === undefined) {\n // If update returns an empty object, then no update was performed\n throw new EndpointError('No update performed');\n } else if (onSubmitSuccess) {\n onSubmitSuccess({ item: newItem });\n }\n // Automatically clear the form after submitting a new item.\n // Otherwise, there would be no way for the developer to clear it, as the\n // there is no new value to set for the item prop to trigger the above\n // effect in case the prop is already null, undefined or the empty item.\n if (!item || item === emptyItem) {\n form.clear();\n }\n } catch (error) {\n handleSubmitError(error);\n }\n }\n\n function deleteItem() {\n setShowDeleteDialog(true);\n }\n\n async function confirmDelete() {\n // At this point, item can not be null or emptyItem\n const deletedItem = item as Value<M>;\n try {\n const idProperty = modelInfo.idProperty!;\n // eslint-disable-next-line\n const id = (item as any)[idProperty.name];\n await service.delete(id);\n if (onDeleteSuccess) {\n onDeleteSuccess({ item: deletedItem });\n }\n } catch (error) {\n if (error instanceof EndpointError) {\n if (onDeleteError) {\n onDeleteError({ error, setMessage: setFormError });\n } else {\n setFormError(error.message);\n }\n } else {\n throw error;\n }\n } finally {\n setShowDeleteDialog(false);\n }\n }\n\n function cancelDelete() {\n setShowDeleteDialog(false);\n }\n\n const handleKeyDown = (event: KeyboardEvent): void => {\n if (event.key === 'Enter' && !isSubmitDisabled) {\n // eslint-disable-next-line no-void\n void handleSubmit();\n }\n };\n\n function createAutoFormField(propertyInfo: PropertyInfo): JSX.Element {\n const fieldOptionsForProperty = fieldOptions?.[propertyInfo.name] ?? {};\n\n return (\n <AutoFormField\n key={propertyInfo.name}\n propertyInfo={propertyInfo}\n form={form}\n disabled={disabled}\n options={fieldOptionsForProperty}\n />\n );\n }\n\n const visibleProperties = visibleFields ? modelInfo.getProperties(visibleFields) : getDefaultProperties(modelInfo);\n\n const fields = visibleProperties.map(createAutoFormField);\n\n const layout = LayoutRenderer ? (\n <LayoutRenderer form={form}>{fields}</LayoutRenderer>\n ) : (\n <FormLayout {...formLayoutProps}>{fields}</FormLayout>\n );\n\n return (\n <div className={`auto-form ${className ?? ''}`} id={id} style={style} data-testid=\"auto-form\">\n <VerticalLayout className=\"auto-form-fields\" onKeyDown={handleKeyDown}>\n {layout}\n {formError ? <div style={{ color: 'var(--lumo-error-color)' }}>{formError}</div> : <></>}\n </VerticalLayout>\n <div className=\"auto-form-toolbar\">\n <Button\n theme=\"primary\"\n disabled={isSubmitDisabled}\n // eslint-disable-next-line @typescript-eslint/no-misused-promises\n onClick={handleSubmit}\n >\n Submit\n </Button>\n {form.dirty ? (\n <Button theme=\"tertiary\" onClick={() => form.reset()}>\n Discard\n </Button>\n ) : null}\n {showDeleteButton && (\n <Button className=\"auto-form-delete-button\" theme=\"tertiary error\" onClick={deleteItem}>\n Delete...\n </Button>\n )}\n </div>\n {showDeleteDialog && (\n <ConfirmDialog\n opened\n header=\"Delete item\"\n confirmTheme=\"error\"\n cancelButtonVisible\n // eslint-disable-next-line\n onConfirm={confirmDelete}\n onCancel={cancelDelete}\n >\n Are you sure you want to delete the selected item?\n </ConfirmDialog>\n )}\n </div>\n );\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["id"]
7
+ }
@@ -0,0 +1,6 @@
1
+ const css = new CSSStyleSheet();
2
+ css.replaceSync(`.auto-form{display:flex;flex-direction:column;gap:var(--lumo-space-m)}.auto-form-toolbar{align-items:center;display:flex;flex-direction:row-reverse;gap:var(--lumo-space-xs) var(--lumo-space-s);justify-content:flex-start}.auto-form-delete-button{margin-right:auto}`);
3
+ export {
4
+ css as default
5
+ };
6
+ //# sourceMappingURL=autoform.obj.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["src/autoform.obj.css"],
4
+ "sourcesContent": ["const css = new CSSStyleSheet();css.replaceSync(`.auto-form{display:flex;flex-direction:column;gap:var(--lumo-space-m)}.auto-form-toolbar{align-items:center;display:flex;flex-direction:row-reverse;gap:var(--lumo-space-xs) var(--lumo-space-s);justify-content:flex-start}.auto-form-delete-button{margin-right:auto}`);export { css as default };"],
5
+ "mappings": "AAAA,MAAM,MAAM,IAAI,cAAc;AAAE,IAAI,YAAY,yQAAyQ;",
6
+ "names": []
7
+ }
@@ -0,0 +1,39 @@
1
+ import type { GridSorterDirection } from '@vaadin/react-components/GridSorter.js';
2
+ import { type Dispatch, type SetStateAction, type ComponentType } from 'react';
3
+ import type { ColumnOptions } from './autogrid-columns';
4
+ import type { HeaderFilterRendererProps } from './header-filter';
5
+ import type { PropertyInfo } from './model-info';
6
+ import type FilterUnion from './types/com/vaadin/hilla/crud/filter/FilterUnion';
7
+ export interface SorterState {
8
+ direction: GridSorterDirection;
9
+ }
10
+ export type SortState = Record<string, SorterState | undefined>;
11
+ export type ColumnContext = Readonly<{
12
+ propertyInfo: PropertyInfo;
13
+ setColumnFilter(filter: FilterUnion, filterKey: string): void;
14
+ sortState: SortState;
15
+ setSortState: Dispatch<SetStateAction<SortState>>;
16
+ customColumnOptions?: ColumnOptions;
17
+ headerFilterRenderer: ComponentType<HeaderFilterRendererProps>;
18
+ filterKey: string;
19
+ }>;
20
+ export declare const ColumnContext: import("react").Context<Readonly<{
21
+ propertyInfo: PropertyInfo;
22
+ setColumnFilter(filter: FilterUnion, filterKey: string): void;
23
+ sortState: SortState;
24
+ setSortState: Dispatch<SetStateAction<SortState>>;
25
+ customColumnOptions?: ColumnOptions | undefined;
26
+ headerFilterRenderer: ComponentType<HeaderFilterRendererProps>;
27
+ filterKey: string;
28
+ }> | null>;
29
+ export type CustomColumnContext = Readonly<{
30
+ setColumnFilter(filter: FilterUnion, filterKey: string): void;
31
+ headerFilterRenderer: ComponentType<HeaderFilterRendererProps>;
32
+ filterKey: string;
33
+ }>;
34
+ export declare const CustomColumnContext: import("react").Context<Readonly<{
35
+ setColumnFilter(filter: FilterUnion, filterKey: string): void;
36
+ headerFilterRenderer: ComponentType<HeaderFilterRendererProps>;
37
+ filterKey: string;
38
+ }> | null>;
39
+ //# sourceMappingURL=autogrid-column-context.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"autogrid-column-context.d.ts","sourceRoot":"","sources":["src/autogrid-column-context.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,wCAAwC,CAAC;AAClF,OAAO,EAAE,KAAK,QAAQ,EAAE,KAAK,cAAc,EAAiB,KAAK,aAAa,EAAE,MAAM,OAAO,CAAC;AAC9F,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACxD,OAAO,KAAK,EAAE,yBAAyB,EAAE,MAAM,iBAAiB,CAAC;AACjE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AACjD,OAAO,KAAK,WAAW,MAAM,kDAAkD,CAAC;AAEhF,MAAM,WAAW,WAAW;IAC1B,SAAS,EAAE,mBAAmB,CAAC;CAChC;AAED,MAAM,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,EAAE,WAAW,GAAG,SAAS,CAAC,CAAC;AAEhE,MAAM,MAAM,aAAa,GAAG,QAAQ,CAAC;IACnC,YAAY,EAAE,YAAY,CAAC;IAC3B,eAAe,CAAC,MAAM,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9D,SAAS,EAAE,SAAS,CAAC;IACrB,YAAY,EAAE,QAAQ,CAAC,cAAc,CAAC,SAAS,CAAC,CAAC,CAAC;IAClD,mBAAmB,CAAC,EAAE,aAAa,CAAC;IACpC,oBAAoB,EAAE,aAAa,CAAC,yBAAyB,CAAC,CAAC;IAC/D,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC,CAAC;AAEH,eAAO,MAAM,aAAa;kBATV,YAAY;4BACF,WAAW,aAAa,MAAM,GAAG,IAAI;eAClD,SAAS;kBACN,SAAS,eAAe,SAAS,CAAC,CAAC;;0BAE3B,cAAc,yBAAyB,CAAC;eACnD,MAAM;UAGmD,CAAC;AAEvE,MAAM,MAAM,mBAAmB,GAAG,QAAQ,CAAC;IACzC,eAAe,CAAC,MAAM,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IAC9D,oBAAoB,EAAE,aAAa,CAAC,yBAAyB,CAAC,CAAC;IAC/D,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC,CAAC;AAEH,eAAO,MAAM,mBAAmB;4BALN,WAAW,aAAa,MAAM,GAAG,IAAI;0BACvC,cAAc,yBAAyB,CAAC;eACnD,MAAM;UAG+D,CAAC"}
@@ -0,0 +1,8 @@
1
+ import { createContext } from "react";
2
+ const ColumnContext = createContext(null);
3
+ const CustomColumnContext = createContext(null);
4
+ export {
5
+ ColumnContext,
6
+ CustomColumnContext
7
+ };
8
+ //# sourceMappingURL=autogrid-column-context.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["src/autogrid-column-context.tsx"],
4
+ "sourcesContent": ["import type { GridSorterDirection } from '@vaadin/react-components/GridSorter.js';\nimport { type Dispatch, type SetStateAction, createContext, type ComponentType } from 'react';\nimport type { ColumnOptions } from './autogrid-columns';\nimport type { HeaderFilterRendererProps } from './header-filter';\nimport type { PropertyInfo } from './model-info';\nimport type FilterUnion from './types/com/vaadin/hilla/crud/filter/FilterUnion';\n\nexport interface SorterState {\n direction: GridSorterDirection;\n}\n\nexport type SortState = Record<string, SorterState | undefined>;\n\nexport type ColumnContext = Readonly<{\n propertyInfo: PropertyInfo;\n setColumnFilter(filter: FilterUnion, filterKey: string): void;\n sortState: SortState;\n setSortState: Dispatch<SetStateAction<SortState>>;\n customColumnOptions?: ColumnOptions;\n headerFilterRenderer: ComponentType<HeaderFilterRendererProps>;\n filterKey: string;\n}>;\n\nexport const ColumnContext = createContext<ColumnContext | null>(null);\n\nexport type CustomColumnContext = Readonly<{\n setColumnFilter(filter: FilterUnion, filterKey: string): void;\n headerFilterRenderer: ComponentType<HeaderFilterRendererProps>;\n filterKey: string;\n}>;\n\nexport const CustomColumnContext = createContext<CustomColumnContext | null>(null);\n"],
5
+ "mappings": "AACA,SAA6C,qBAAyC;AAsB/E,MAAM,gBAAgB,cAAoC,IAAI;AAQ9D,MAAM,sBAAsB,cAA0C,IAAI;",
6
+ "names": []
7
+ }
@@ -0,0 +1,6 @@
1
+ import type { GridColumnProps } from '@vaadin/react-components/GridColumn.js';
2
+ import { type HeaderFilterProps } from './header-filter';
3
+ import type { PropertyInfo } from './model-info';
4
+ export type ColumnOptions = HeaderFilterProps & Omit<GridColumnProps<any>, 'dangerouslySetInnerHTML'>;
5
+ export declare function getColumnOptions(propertyInfo: PropertyInfo, customColumnOptions: ColumnOptions | undefined): ColumnOptions;
6
+ //# sourceMappingURL=autogrid-columns.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"autogrid-columns.d.ts","sourceRoot":"","sources":["src/autogrid-columns.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,wCAAwC,CAAC;AAW9E,OAAO,EAIL,KAAK,iBAAiB,EAKvB,MAAM,iBAAiB,CAAC;AACzB,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAEjD,MAAM,MAAM,aAAa,GAAG,iBAAiB,GAAG,IAAI,CAAC,eAAe,CAAC,GAAG,CAAC,EAAE,yBAAyB,CAAC,CAAC;AA+EtG,wBAAgB,gBAAgB,CAC9B,YAAY,EAAE,YAAY,EAC1B,mBAAmB,EAAE,aAAa,GAAG,SAAS,GAC7C,aAAa,CAWf"}
@@ -0,0 +1,102 @@
1
+ import {
2
+ AutoGridBooleanRenderer,
3
+ AutoGridDateRenderer,
4
+ AutoGridDateTimeRenderer,
5
+ AutoGridDecimalRenderer,
6
+ AutoGridEnumRenderer,
7
+ AutoGridIntegerRenderer,
8
+ AutoGridJsonRenderer,
9
+ AutoGridTimeRenderer
10
+ } from "./autogrid-renderers";
11
+ import {
12
+ BooleanHeaderFilter,
13
+ DateHeaderFilter,
14
+ EnumHeaderFilter,
15
+ NoHeaderFilter,
16
+ NumberHeaderFilter,
17
+ StringHeaderFilter,
18
+ TimeHeaderFilter
19
+ } from "./header-filter";
20
+ function getTypeColumnOptions(propertyInfo) {
21
+ switch (propertyInfo.type) {
22
+ case "integer":
23
+ return {
24
+ autoWidth: true,
25
+ textAlign: "end",
26
+ flexGrow: 0,
27
+ renderer: AutoGridIntegerRenderer,
28
+ headerFilterRenderer: NumberHeaderFilter
29
+ };
30
+ case "decimal":
31
+ return {
32
+ autoWidth: true,
33
+ textAlign: "end",
34
+ flexGrow: 0,
35
+ renderer: AutoGridDecimalRenderer,
36
+ headerFilterRenderer: NumberHeaderFilter
37
+ };
38
+ case "boolean":
39
+ return {
40
+ autoWidth: true,
41
+ textAlign: "end",
42
+ flexGrow: 0,
43
+ renderer: AutoGridBooleanRenderer,
44
+ headerFilterRenderer: BooleanHeaderFilter
45
+ };
46
+ case "date":
47
+ return {
48
+ autoWidth: true,
49
+ textAlign: "end",
50
+ flexGrow: 0,
51
+ renderer: AutoGridDateRenderer,
52
+ headerFilterRenderer: DateHeaderFilter
53
+ };
54
+ case "time":
55
+ return {
56
+ autoWidth: true,
57
+ textAlign: "end",
58
+ flexGrow: 0,
59
+ renderer: AutoGridTimeRenderer,
60
+ headerFilterRenderer: TimeHeaderFilter
61
+ };
62
+ case "datetime":
63
+ return {
64
+ autoWidth: true,
65
+ textAlign: "end",
66
+ flexGrow: 0,
67
+ renderer: AutoGridDateTimeRenderer,
68
+ headerFilterRenderer: DateHeaderFilter
69
+ };
70
+ case "enum":
71
+ return {
72
+ autoWidth: true,
73
+ renderer: AutoGridEnumRenderer,
74
+ headerFilterRenderer: EnumHeaderFilter
75
+ };
76
+ case "string":
77
+ return {
78
+ autoWidth: true,
79
+ headerFilterRenderer: StringHeaderFilter
80
+ };
81
+ case "object":
82
+ return {
83
+ autoWidth: true,
84
+ renderer: AutoGridJsonRenderer,
85
+ headerFilterRenderer: NoHeaderFilter
86
+ };
87
+ default:
88
+ return {
89
+ autoWidth: true,
90
+ headerFilterRenderer: NoHeaderFilter
91
+ };
92
+ }
93
+ }
94
+ function getColumnOptions(propertyInfo, customColumnOptions) {
95
+ const typeColumnOptions = getTypeColumnOptions(propertyInfo);
96
+ const headerFilterRenderer = customColumnOptions?.filterable === false ? NoHeaderFilter : typeColumnOptions.headerFilterRenderer ?? NoHeaderFilter;
97
+ return customColumnOptions ? { ...typeColumnOptions, headerFilterRenderer, ...customColumnOptions } : typeColumnOptions;
98
+ }
99
+ export {
100
+ getColumnOptions
101
+ };
102
+ //# sourceMappingURL=autogrid-columns.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["src/autogrid-columns.tsx"],
4
+ "sourcesContent": ["import type { GridColumnProps } from '@vaadin/react-components/GridColumn.js';\nimport {\n AutoGridBooleanRenderer,\n AutoGridDateRenderer,\n AutoGridDateTimeRenderer,\n AutoGridDecimalRenderer,\n AutoGridEnumRenderer,\n AutoGridIntegerRenderer,\n AutoGridJsonRenderer,\n AutoGridTimeRenderer,\n} from './autogrid-renderers';\nimport {\n BooleanHeaderFilter,\n DateHeaderFilter,\n EnumHeaderFilter,\n type HeaderFilterProps,\n NoHeaderFilter,\n NumberHeaderFilter,\n StringHeaderFilter,\n TimeHeaderFilter,\n} from './header-filter';\nimport type { PropertyInfo } from './model-info';\n\nexport type ColumnOptions = HeaderFilterProps & Omit<GridColumnProps<any>, 'dangerouslySetInnerHTML'>;\n\n// eslint-disable-next-line consistent-return\nfunction getTypeColumnOptions(propertyInfo: PropertyInfo): ColumnOptions {\n // eslint-disable-next-line default-case\n switch (propertyInfo.type) {\n case 'integer':\n return {\n autoWidth: true,\n textAlign: 'end',\n flexGrow: 0,\n renderer: AutoGridIntegerRenderer,\n headerFilterRenderer: NumberHeaderFilter,\n };\n case 'decimal':\n return {\n autoWidth: true,\n textAlign: 'end',\n flexGrow: 0,\n renderer: AutoGridDecimalRenderer,\n headerFilterRenderer: NumberHeaderFilter,\n };\n case 'boolean':\n return {\n autoWidth: true,\n textAlign: 'end',\n flexGrow: 0,\n renderer: AutoGridBooleanRenderer,\n headerFilterRenderer: BooleanHeaderFilter,\n };\n case 'date':\n return {\n autoWidth: true,\n textAlign: 'end',\n flexGrow: 0,\n renderer: AutoGridDateRenderer,\n headerFilterRenderer: DateHeaderFilter,\n };\n case 'time':\n return {\n autoWidth: true,\n textAlign: 'end',\n flexGrow: 0,\n renderer: AutoGridTimeRenderer,\n headerFilterRenderer: TimeHeaderFilter,\n };\n case 'datetime':\n return {\n autoWidth: true,\n textAlign: 'end',\n flexGrow: 0,\n renderer: AutoGridDateTimeRenderer,\n headerFilterRenderer: DateHeaderFilter,\n };\n case 'enum':\n return {\n autoWidth: true,\n renderer: AutoGridEnumRenderer,\n headerFilterRenderer: EnumHeaderFilter,\n };\n case 'string':\n return {\n autoWidth: true,\n headerFilterRenderer: StringHeaderFilter,\n };\n case 'object':\n return {\n autoWidth: true,\n renderer: AutoGridJsonRenderer,\n headerFilterRenderer: NoHeaderFilter,\n };\n default:\n return {\n autoWidth: true,\n headerFilterRenderer: NoHeaderFilter,\n };\n }\n}\n\nexport function getColumnOptions(\n propertyInfo: PropertyInfo,\n customColumnOptions: ColumnOptions | undefined,\n): ColumnOptions {\n const typeColumnOptions = getTypeColumnOptions(propertyInfo);\n const headerFilterRenderer =\n customColumnOptions?.filterable === false\n ? NoHeaderFilter\n : typeColumnOptions.headerFilterRenderer ?? NoHeaderFilter;\n // TODO: Remove eslint-disable when all TypeScript version issues are resolved\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition\n return customColumnOptions\n ? { ...typeColumnOptions, headerFilterRenderer, ...customColumnOptions }\n : typeColumnOptions;\n}\n"],
5
+ "mappings": "AACA;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EAEA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AAMP,SAAS,qBAAqB,cAA2C;AAEvE,UAAQ,aAAa,MAAM;AAAA,IACzB,KAAK;AACH,aAAO;AAAA,QACL,WAAW;AAAA,QACX,WAAW;AAAA,QACX,UAAU;AAAA,QACV,UAAU;AAAA,QACV,sBAAsB;AAAA,MACxB;AAAA,IACF,KAAK;AACH,aAAO;AAAA,QACL,WAAW;AAAA,QACX,WAAW;AAAA,QACX,UAAU;AAAA,QACV,UAAU;AAAA,QACV,sBAAsB;AAAA,MACxB;AAAA,IACF,KAAK;AACH,aAAO;AAAA,QACL,WAAW;AAAA,QACX,WAAW;AAAA,QACX,UAAU;AAAA,QACV,UAAU;AAAA,QACV,sBAAsB;AAAA,MACxB;AAAA,IACF,KAAK;AACH,aAAO;AAAA,QACL,WAAW;AAAA,QACX,WAAW;AAAA,QACX,UAAU;AAAA,QACV,UAAU;AAAA,QACV,sBAAsB;AAAA,MACxB;AAAA,IACF,KAAK;AACH,aAAO;AAAA,QACL,WAAW;AAAA,QACX,WAAW;AAAA,QACX,UAAU;AAAA,QACV,UAAU;AAAA,QACV,sBAAsB;AAAA,MACxB;AAAA,IACF,KAAK;AACH,aAAO;AAAA,QACL,WAAW;AAAA,QACX,WAAW;AAAA,QACX,UAAU;AAAA,QACV,UAAU;AAAA,QACV,sBAAsB;AAAA,MACxB;AAAA,IACF,KAAK;AACH,aAAO;AAAA,QACL,WAAW;AAAA,QACX,UAAU;AAAA,QACV,sBAAsB;AAAA,MACxB;AAAA,IACF,KAAK;AACH,aAAO;AAAA,QACL,WAAW;AAAA,QACX,sBAAsB;AAAA,MACxB;AAAA,IACF,KAAK;AACH,aAAO;AAAA,QACL,WAAW;AAAA,QACX,UAAU;AAAA,QACV,sBAAsB;AAAA,MACxB;AAAA,IACF;AACE,aAAO;AAAA,QACL,WAAW;AAAA,QACX,sBAAsB;AAAA,MACxB;AAAA,EACJ;AACF;AAEO,SAAS,iBACd,cACA,qBACe;AACf,QAAM,oBAAoB,qBAAqB,YAAY;AAC3D,QAAM,uBACJ,qBAAqB,eAAe,QAChC,iBACA,kBAAkB,wBAAwB;AAGhD,SAAO,sBACH,EAAE,GAAG,mBAAmB,sBAAsB,GAAG,oBAAoB,IACrE;AACN;",
6
+ "names": []
7
+ }
@@ -0,0 +1,4 @@
1
+ import { AutoGrid as _AutoGrid } from './autogrid.js';
2
+ export * from './autogrid.js';
3
+ export declare const AutoGrid: typeof _AutoGrid;
4
+ //# sourceMappingURL=autogrid-feature.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"autogrid-feature.d.ts","sourceRoot":"","sources":["src/autogrid-feature.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,IAAI,SAAS,EAAE,MAAM,eAAe,CAAC;AAGtD,cAAc,eAAe,CAAC;AAE9B,eAAO,MAAM,QAAQ,EAAE,OAAO,SAAsD,CAAC"}
@@ -0,0 +1,8 @@
1
+ import { AutoGrid as _AutoGrid } from "./autogrid.js";
2
+ import { featureRegistration } from "./util";
3
+ export * from "./autogrid.js";
4
+ const AutoGrid = featureRegistration(_AutoGrid, "AutoGrid");
5
+ export {
6
+ AutoGrid
7
+ };
8
+ //# sourceMappingURL=autogrid-feature.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["src/autogrid-feature.ts"],
4
+ "sourcesContent": ["/* eslint-disable import/export */\nimport { AutoGrid as _AutoGrid } from './autogrid.js';\nimport { featureRegistration } from './util';\n\nexport * from './autogrid.js';\n\nexport const AutoGrid: typeof _AutoGrid = featureRegistration(_AutoGrid, 'AutoGrid');\n"],
5
+ "mappings": "AACA,SAAS,YAAY,iBAAiB;AACtC,SAAS,2BAA2B;AAEpC,cAAc;AAEP,MAAM,WAA6B,oBAAoB,WAAW,UAAU;",
6
+ "names": []
7
+ }
@@ -0,0 +1,28 @@
1
+ import type { GridItemModel } from '@vaadin/react-components/Grid.js';
2
+ import type { GridColumnElement } from '@vaadin/react-components/GridColumn.js';
3
+ import { type ComponentType, type JSX } from 'react';
4
+ import type { ItemCounts } from './data-provider';
5
+ import '@vaadin/vaadin-lumo-styles/vaadin-iconset.js';
6
+ export type RendererOptions<TItem> = {
7
+ item: TItem;
8
+ model: GridItemModel<TItem>;
9
+ original: GridColumnElement<TItem>;
10
+ };
11
+ export declare function AutoGridIntegerRenderer<TItem>({ item }: RendererOptions<TItem>): JSX.Element;
12
+ export declare function AutoGridDecimalRenderer<TItem>({ item }: RendererOptions<TItem>): JSX.Element;
13
+ export declare function AutoGridEnumRenderer<TItem>({ item }: RendererOptions<TItem>): JSX.Element;
14
+ export declare function AutoGridBooleanRenderer<TItem>({ item }: RendererOptions<TItem>): JSX.Element;
15
+ export declare function AutoGridDateRenderer<TItem>({ item }: RendererOptions<TItem>): JSX.Element;
16
+ export declare function AutoGridTimeRenderer<TItem>({ item }: RendererOptions<TItem>): JSX.Element;
17
+ export declare function AutoGridDateTimeRenderer<TItem>({ item }: RendererOptions<TItem>): JSX.Element;
18
+ export declare function AutoGridJsonRenderer<TItem>({ item }: RendererOptions<TItem>): JSX.Element;
19
+ export declare function AutoGridRowNumberRenderer<TItem>({ model }: RendererOptions<TItem>): JSX.Element;
20
+ export type FooterContextType = {
21
+ totalCount?: boolean;
22
+ filteredCount?: boolean;
23
+ footerCountRenderer?: ComponentType<ItemCounts>;
24
+ itemCounts?: ItemCounts;
25
+ };
26
+ export declare const FooterContext: import("react").Context<FooterContextType>;
27
+ export declare function AutoGridFooterItemCountRenderer(): JSX.Element;
28
+ //# sourceMappingURL=autogrid-renderers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"autogrid-renderers.d.ts","sourceRoot":"","sources":["src/autogrid-renderers.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kCAAkC,CAAC;AACtE,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,wCAAwC,CAAC;AAEhF,OAAO,EAAE,KAAK,aAAa,EAAqC,KAAK,GAAG,EAAc,MAAM,OAAO,CAAC;AAEpG,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAKlD,OAAO,8CAA8C,CAAC;AAEtD,MAAM,MAAM,eAAe,CAAC,KAAK,IAAI;IACnC,IAAI,EAAE,KAAK,CAAC;IACZ,KAAK,EAAE,aAAa,CAAC,KAAK,CAAC,CAAC;IAC5B,QAAQ,EAAE,iBAAiB,CAAC,KAAK,CAAC,CAAC;CACpC,CAAC;AAUF,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,EAAE,IAAI,EAAE,EAAE,eAAe,CAAC,KAAK,CAAC,GAAG,GAAG,CAAC,OAAO,CAI5F;AAED,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,EAAE,IAAI,EAAE,EAAE,eAAe,CAAC,KAAK,CAAC,GAAG,GAAG,CAAC,OAAO,CAI5F;AAED,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,EAAE,IAAI,EAAE,EAAE,eAAe,CAAC,KAAK,CAAC,GAAG,GAAG,CAAC,OAAO,CAIzF;AAED,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,EAAE,IAAI,EAAE,EAAE,eAAe,CAAC,KAAK,CAAC,GAAG,GAAG,CAAC,OAAO,CAO5F;AAED,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,EAAE,IAAI,EAAE,EAAE,eAAe,CAAC,KAAK,CAAC,GAAG,GAAG,CAAC,OAAO,CAIzF;AAED,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,EAAE,IAAI,EAAE,EAAE,eAAe,CAAC,KAAK,CAAC,GAAG,GAAG,CAAC,OAAO,CAIzF;AAED,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,EAAE,IAAI,EAAE,EAAE,eAAe,CAAC,KAAK,CAAC,GAAG,GAAG,CAAC,OAAO,CAI7F;AAED,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,EAAE,IAAI,EAAE,EAAE,eAAe,CAAC,KAAK,CAAC,GAAG,GAAG,CAAC,OAAO,CAMzF;AAED,wBAAgB,yBAAyB,CAAC,KAAK,EAAE,EAAE,KAAK,EAAE,EAAE,eAAe,CAAC,KAAK,CAAC,GAAG,GAAG,CAAC,OAAO,CAE/F;AAED,MAAM,MAAM,iBAAiB,GAAG;IAC9B,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,mBAAmB,CAAC,EAAE,aAAa,CAAC,UAAU,CAAC,CAAC;IAChD,UAAU,CAAC,EAAE,UAAU,CAAC;CACzB,CAAC;AAEF,eAAO,MAAM,aAAa,4CAA+C,CAAC;AAE1E,wBAAgB,+BAA+B,IAAI,GAAG,CAAC,OAAO,CAqB7D"}
@@ -0,0 +1,92 @@
1
+ import { Fragment, jsx } from "react/jsx-runtime";
2
+ import { Icon } from "@vaadin/react-components/Icon.js";
3
+ import { createContext, useContext } from "react";
4
+ import { ColumnContext } from "./autogrid-column-context";
5
+ import { useLocaleFormatter } from "./locale.js";
6
+ import { convertToTitleCase } from "./util";
7
+ import "@vaadin/vaadin-lumo-styles/vaadin-iconset.js";
8
+ function getColumnValue(context, item) {
9
+ const path = context.propertyInfo.name;
10
+ return path.split(".").reduce((obj, property) => obj ? obj[property] : void 0, item);
11
+ }
12
+ const fontVariantStyle = { fontVariantNumeric: "tabular-nums" };
13
+ function AutoGridIntegerRenderer({ item }) {
14
+ const formatter = useLocaleFormatter();
15
+ const context = useContext(ColumnContext);
16
+ return /* @__PURE__ */ jsx("span", { style: fontVariantStyle, children: formatter.formatInteger(getColumnValue(context, item)) });
17
+ }
18
+ function AutoGridDecimalRenderer({ item }) {
19
+ const formatter = useLocaleFormatter();
20
+ const context = useContext(ColumnContext);
21
+ return /* @__PURE__ */ jsx("span", { style: fontVariantStyle, children: formatter.formatDecimal(getColumnValue(context, item)) });
22
+ }
23
+ function AutoGridEnumRenderer({ item }) {
24
+ const context = useContext(ColumnContext);
25
+ const value = getColumnValue(context, item) || "";
26
+ return /* @__PURE__ */ jsx("span", { children: convertToTitleCase(value) });
27
+ }
28
+ function AutoGridBooleanRenderer({ item }) {
29
+ const context = useContext(ColumnContext);
30
+ const value = getColumnValue(context, item);
31
+ if (value) {
32
+ return /* @__PURE__ */ jsx(Icon, { "aria-label": "false", icon: "lumo:checkmark" });
33
+ }
34
+ return /* @__PURE__ */ jsx(Icon, { "aria-label": "true", style: { color: "var(--lumo-secondary-text-color)" }, icon: "lumo:minus" });
35
+ }
36
+ function AutoGridDateRenderer({ item }) {
37
+ const formatter = useLocaleFormatter();
38
+ const context = useContext(ColumnContext);
39
+ return /* @__PURE__ */ jsx("span", { style: fontVariantStyle, children: formatter.formatDate(getColumnValue(context, item)) });
40
+ }
41
+ function AutoGridTimeRenderer({ item }) {
42
+ const formatter = useLocaleFormatter();
43
+ const context = useContext(ColumnContext);
44
+ return /* @__PURE__ */ jsx("span", { style: fontVariantStyle, children: formatter.formatLocalTime(getColumnValue(context, item)) });
45
+ }
46
+ function AutoGridDateTimeRenderer({ item }) {
47
+ const formatter = useLocaleFormatter();
48
+ const context = useContext(ColumnContext);
49
+ return /* @__PURE__ */ jsx("span", { style: fontVariantStyle, children: formatter.formatLocalDateTime(getColumnValue(context, item)) });
50
+ }
51
+ function AutoGridJsonRenderer({ item }) {
52
+ const context = useContext(ColumnContext);
53
+ const value = getColumnValue(context, item);
54
+ const jsonString = value ? JSON.stringify(value) : "";
55
+ const jsonPreview = jsonString.length > 50 ? `${jsonString.substring(0, 50)}...` : jsonString;
56
+ return /* @__PURE__ */ jsx("span", { children: jsonPreview });
57
+ }
58
+ function AutoGridRowNumberRenderer({ model }) {
59
+ return /* @__PURE__ */ jsx(Fragment, { children: model.index + 1 });
60
+ }
61
+ const FooterContext = createContext(void 0);
62
+ function AutoGridFooterItemCountRenderer() {
63
+ const footerContext = useContext(FooterContext);
64
+ const { totalCount, filteredCount, itemCounts, footerCountRenderer: FooterRenderer } = footerContext;
65
+ if (FooterRenderer) {
66
+ return /* @__PURE__ */ jsx(FooterRenderer, { ...itemCounts });
67
+ }
68
+ let filterCountText;
69
+ if (filteredCount && itemCounts?.filteredCount !== void 0) {
70
+ filterCountText = totalCount && itemCounts.totalCount !== void 0 ? `Showing: ${itemCounts.filteredCount} out of ${itemCounts.totalCount}` : `Showing: ${itemCounts.filteredCount}`;
71
+ } else if (totalCount && itemCounts?.totalCount !== void 0) {
72
+ filterCountText = `Total: ${itemCounts.totalCount}`;
73
+ }
74
+ if (filterCountText) {
75
+ return /* @__PURE__ */ jsx("p", { children: filterCountText });
76
+ }
77
+ return /* @__PURE__ */ jsx(Fragment, {});
78
+ }
79
+ export {
80
+ AutoGridBooleanRenderer,
81
+ AutoGridDateRenderer,
82
+ AutoGridDateTimeRenderer,
83
+ AutoGridDecimalRenderer,
84
+ AutoGridEnumRenderer,
85
+ AutoGridFooterItemCountRenderer,
86
+ AutoGridIntegerRenderer,
87
+ AutoGridJsonRenderer,
88
+ AutoGridRowNumberRenderer,
89
+ AutoGridTimeRenderer,
90
+ FooterContext
91
+ };
92
+ //# sourceMappingURL=autogrid-renderers.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["src/autogrid-renderers.tsx"],
4
+ "sourcesContent": ["import type { GridItemModel } from '@vaadin/react-components/Grid.js';\nimport type { GridColumnElement } from '@vaadin/react-components/GridColumn.js';\nimport { Icon } from '@vaadin/react-components/Icon.js';\nimport { type ComponentType, createContext, type CSSProperties, type JSX, useContext } from 'react';\nimport { ColumnContext } from './autogrid-column-context';\nimport type { ItemCounts } from './data-provider';\nimport { useLocaleFormatter } from './locale.js';\nimport { convertToTitleCase } from './util';\n\n// eslint-disable-next-line\nimport '@vaadin/vaadin-lumo-styles/vaadin-iconset.js';\n\nexport type RendererOptions<TItem> = {\n item: TItem;\n model: GridItemModel<TItem>;\n original: GridColumnElement<TItem>;\n};\n\nfunction getColumnValue<TItem>(context: ColumnContext, item: TItem): any {\n const path = context.propertyInfo.name;\n // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access\n return path.split('.').reduce<any>((obj, property) => (obj ? obj[property] : undefined), item);\n}\n\nconst fontVariantStyle: CSSProperties = { fontVariantNumeric: 'tabular-nums' };\n\nexport function AutoGridIntegerRenderer<TItem>({ item }: RendererOptions<TItem>): JSX.Element {\n const formatter = useLocaleFormatter();\n const context = useContext(ColumnContext)!;\n return <span style={fontVariantStyle}>{formatter.formatInteger(getColumnValue(context, item))}</span>;\n}\n\nexport function AutoGridDecimalRenderer<TItem>({ item }: RendererOptions<TItem>): JSX.Element {\n const formatter = useLocaleFormatter();\n const context = useContext(ColumnContext)!;\n return <span style={fontVariantStyle}>{formatter.formatDecimal(getColumnValue(context, item))}</span>;\n}\n\nexport function AutoGridEnumRenderer<TItem>({ item }: RendererOptions<TItem>): JSX.Element {\n const context = useContext(ColumnContext)!;\n const value = getColumnValue(context, item) || '';\n return <span>{convertToTitleCase(value)}</span>;\n}\n\nexport function AutoGridBooleanRenderer<TItem>({ item }: RendererOptions<TItem>): JSX.Element {\n const context = useContext(ColumnContext)!;\n const value = getColumnValue(context, item);\n if (value) {\n return <Icon aria-label=\"false\" icon=\"lumo:checkmark\" />;\n }\n return <Icon aria-label=\"true\" style={{ color: 'var(--lumo-secondary-text-color)' }} icon=\"lumo:minus\" />;\n}\n\nexport function AutoGridDateRenderer<TItem>({ item }: RendererOptions<TItem>): JSX.Element {\n const formatter = useLocaleFormatter();\n const context = useContext(ColumnContext)!;\n return <span style={fontVariantStyle}>{formatter.formatDate(getColumnValue(context, item))}</span>;\n}\n\nexport function AutoGridTimeRenderer<TItem>({ item }: RendererOptions<TItem>): JSX.Element {\n const formatter = useLocaleFormatter();\n const context = useContext(ColumnContext)!;\n return <span style={fontVariantStyle}>{formatter.formatLocalTime(getColumnValue(context, item))}</span>;\n}\n\nexport function AutoGridDateTimeRenderer<TItem>({ item }: RendererOptions<TItem>): JSX.Element {\n const formatter = useLocaleFormatter();\n const context = useContext(ColumnContext)!;\n return <span style={fontVariantStyle}>{formatter.formatLocalDateTime(getColumnValue(context, item))}</span>;\n}\n\nexport function AutoGridJsonRenderer<TItem>({ item }: RendererOptions<TItem>): JSX.Element {\n const context = useContext(ColumnContext)!;\n const value = getColumnValue(context, item);\n const jsonString = value ? JSON.stringify(value) : '';\n const jsonPreview = jsonString.length > 50 ? `${jsonString.substring(0, 50)}...` : jsonString;\n return <span>{jsonPreview}</span>;\n}\n\nexport function AutoGridRowNumberRenderer<TItem>({ model }: RendererOptions<TItem>): JSX.Element {\n return <>{model.index + 1}</>;\n}\n\nexport type FooterContextType = {\n totalCount?: boolean;\n filteredCount?: boolean;\n footerCountRenderer?: ComponentType<ItemCounts>;\n itemCounts?: ItemCounts;\n};\n\nexport const FooterContext = createContext<FooterContextType>(undefined!);\n\nexport function AutoGridFooterItemCountRenderer(): JSX.Element {\n const footerContext = useContext(FooterContext);\n const { totalCount, filteredCount, itemCounts, footerCountRenderer: FooterRenderer } = footerContext;\n\n if (FooterRenderer) {\n return <FooterRenderer {...itemCounts} />;\n }\n\n let filterCountText: string | undefined;\n if (filteredCount && itemCounts?.filteredCount !== undefined) {\n filterCountText =\n totalCount && itemCounts.totalCount !== undefined\n ? `Showing: ${itemCounts.filteredCount} out of ${itemCounts.totalCount}`\n : `Showing: ${itemCounts.filteredCount}`;\n } else if (totalCount && itemCounts?.totalCount !== undefined) {\n filterCountText = `Total: ${itemCounts.totalCount}`;\n }\n if (filterCountText) {\n return <p>{filterCountText}</p>;\n }\n return <></>;\n}\n"],
5
+ "mappings": "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",
6
+ "names": []
7
+ }