ding-react-admin 2.4.0 → 2.5.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/index.js +278 -232
- package/dist/src/crud/HiddenSources.d.ts +9 -0
- package/dist/src/crud/HiddenSources.d.ts.map +1 -0
- package/dist/src/crud/InlineFormSet.d.ts.map +1 -1
- package/dist/src/crud/columns/BooleanColumn.d.ts.map +1 -1
- package/dist/src/crud/columns/DateColumn.d.ts.map +1 -1
- package/dist/src/crud/columns/ImageColumn.d.ts.map +1 -1
- package/dist/src/crud/columns/NumberColumn.d.ts.map +1 -1
- package/dist/src/crud/columns/ReferenceColumn.d.ts.map +1 -1
- package/dist/src/crud/columns/ReferenceManyColumn.d.ts.map +1 -1
- package/dist/src/crud/columns/TextColumn.d.ts.map +1 -1
- package/dist/src/crud/fields/BooleanField.d.ts +3 -3
- package/dist/src/crud/fields/BooleanField.d.ts.map +1 -1
- package/dist/src/crud/fields/DateField.d.ts +3 -3
- package/dist/src/crud/fields/DateField.d.ts.map +1 -1
- package/dist/src/crud/fields/FieldWrapper.d.ts +3 -1
- package/dist/src/crud/fields/FieldWrapper.d.ts.map +1 -1
- package/dist/src/crud/fields/FileField.d.ts +3 -3
- package/dist/src/crud/fields/FileField.d.ts.map +1 -1
- package/dist/src/crud/fields/ImageField.d.ts +3 -3
- package/dist/src/crud/fields/ImageField.d.ts.map +1 -1
- package/dist/src/crud/fields/NumberField.d.ts +3 -3
- package/dist/src/crud/fields/NumberField.d.ts.map +1 -1
- package/dist/src/crud/fields/PasswordField.d.ts +3 -3
- package/dist/src/crud/fields/PasswordField.d.ts.map +1 -1
- package/dist/src/crud/fields/ReferenceField.d.ts +3 -3
- package/dist/src/crud/fields/ReferenceField.d.ts.map +1 -1
- package/dist/src/crud/fields/ReferenceManyField.d.ts +3 -3
- package/dist/src/crud/fields/ReferenceManyField.d.ts.map +1 -1
- package/dist/src/crud/fields/SelectField.d.ts +3 -3
- package/dist/src/crud/fields/SelectField.d.ts.map +1 -1
- package/dist/src/crud/fields/TextAreaField.d.ts +3 -3
- package/dist/src/crud/fields/TextAreaField.d.ts.map +1 -1
- package/dist/src/crud/fields/TextField.d.ts +3 -3
- package/dist/src/crud/fields/TextField.d.ts.map +1 -1
- package/dist/src/crud/fields/TimeField.d.ts +3 -3
- package/dist/src/crud/fields/TimeField.d.ts.map +1 -1
- package/dist/src/crud/index.d.ts +3 -1
- package/dist/src/crud/index.d.ts.map +1 -1
- package/dist/src/crud/types.d.ts +5 -0
- package/dist/src/crud/types.d.ts.map +1 -1
- package/dist/src/crud/utils/buildInlineRowsPayload.d.ts.map +1 -1
- package/dist/src/crud/utils/columnDataIndex.d.ts +5 -0
- package/dist/src/crud/utils/columnDataIndex.d.ts.map +1 -0
- package/dist/src/crud/utils/shouldRegisterSourceInPayload.d.ts +6 -0
- package/dist/src/crud/utils/shouldRegisterSourceInPayload.d.ts.map +1 -0
- package/dist/src/index.d.ts +2 -2
- package/dist/src/index.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/crud/HiddenSources.tsx +37 -0
- package/src/crud/InlineFormSet.tsx +4 -1
- package/src/crud/columns/BooleanColumn.tsx +2 -1
- package/src/crud/columns/DateColumn.tsx +2 -1
- package/src/crud/columns/ImageColumn.tsx +2 -1
- package/src/crud/columns/NumberColumn.tsx +2 -1
- package/src/crud/columns/ReferenceColumn.tsx +2 -1
- package/src/crud/columns/ReferenceManyColumn.tsx +2 -1
- package/src/crud/columns/TextColumn.tsx +3 -2
- package/src/crud/fields/BooleanField.tsx +4 -2
- package/src/crud/fields/DateField.tsx +4 -2
- package/src/crud/fields/FieldWrapper.tsx +20 -7
- package/src/crud/fields/FileField.tsx +4 -2
- package/src/crud/fields/ImageField.tsx +4 -2
- package/src/crud/fields/NumberField.tsx +4 -2
- package/src/crud/fields/PasswordField.tsx +8 -2
- package/src/crud/fields/ReferenceField.tsx +8 -4
- package/src/crud/fields/ReferenceManyField.tsx +5 -3
- package/src/crud/fields/SelectField.tsx +5 -3
- package/src/crud/fields/TextAreaField.tsx +4 -2
- package/src/crud/fields/TextField.tsx +4 -2
- package/src/crud/fields/TimeField.tsx +4 -2
- package/src/crud/index.ts +3 -0
- package/src/crud/types.ts +6 -0
- package/src/crud/utils/buildInlineRowsPayload.ts +5 -2
- package/src/crud/utils/columnDataIndex.ts +6 -0
- package/src/crud/utils/shouldRegisterSourceInPayload.ts +10 -0
- package/src/data/dataUtils.test.ts +52 -1
- package/src/index.ts +3 -0
|
@@ -7,6 +7,8 @@ import type {
|
|
|
7
7
|
InlineRowContext,
|
|
8
8
|
} from "./types";
|
|
9
9
|
import { nestedFieldPath } from "./utils/nestedFieldPath";
|
|
10
|
+
import { getFormValue } from "./utils/getFormValue";
|
|
11
|
+
import { setFormValue } from "./utils/setFormValue";
|
|
10
12
|
import { useRegisterInlineField } from "./context/InlineFieldsRegistry";
|
|
11
13
|
import { useRegisterPayloadField } from "./context/PayloadFieldsContext";
|
|
12
14
|
|
|
@@ -29,7 +31,8 @@ export type InlineFormSetStackedProps = InlineFormSetBaseProps & {
|
|
|
29
31
|
function emptyRow(sources: string[], defaults?: Record<string, unknown>) {
|
|
30
32
|
const row: Record<string, unknown> = {};
|
|
31
33
|
for (const source of sources) {
|
|
32
|
-
|
|
34
|
+
const value = defaults ? getFormValue(defaults, source) : undefined;
|
|
35
|
+
setFormValue(row, source, value);
|
|
33
36
|
}
|
|
34
37
|
return row;
|
|
35
38
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { useMemo } from "react";
|
|
2
2
|
import type { BaseSourceProps } from "../types";
|
|
3
|
+
import { columnDataIndex } from "../utils/columnDataIndex";
|
|
3
4
|
import { useRegisterColumn } from "../context/ListContext";
|
|
4
5
|
|
|
5
6
|
export type BooleanColumnProps = BaseSourceProps & {
|
|
@@ -19,7 +20,7 @@ export function BooleanColumn({
|
|
|
19
20
|
sortable,
|
|
20
21
|
buildColumn: () => ({
|
|
21
22
|
title: label ?? source,
|
|
22
|
-
dataIndex: source,
|
|
23
|
+
dataIndex: columnDataIndex(source),
|
|
23
24
|
key: source,
|
|
24
25
|
sorter: sortable ? true : undefined,
|
|
25
26
|
render: (v: boolean) => (v ? "Yes" : "No"),
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { useMemo } from "react";
|
|
2
2
|
import type { BaseSourceProps } from "../types";
|
|
3
|
+
import { columnDataIndex } from "../utils/columnDataIndex";
|
|
3
4
|
import { useRegisterColumn } from "../context/ListContext";
|
|
4
5
|
|
|
5
6
|
export type DateColumnProps = BaseSourceProps & {
|
|
@@ -15,7 +16,7 @@ export function DateColumn({ source, label, sortable = true }: DateColumnProps)
|
|
|
15
16
|
sortable,
|
|
16
17
|
buildColumn: () => ({
|
|
17
18
|
title: label ?? source,
|
|
18
|
-
dataIndex: source,
|
|
19
|
+
dataIndex: columnDataIndex(source),
|
|
19
20
|
key: source,
|
|
20
21
|
sorter: sortable ? true : undefined,
|
|
21
22
|
render: (v: string) => (v ? String(v).slice(0, 10) : "—"),
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { useMemo, type CSSProperties } from "react";
|
|
2
2
|
import type { BaseSourceProps } from "../types";
|
|
3
|
+
import { columnDataIndex } from "../utils/columnDataIndex";
|
|
3
4
|
import { useRegisterColumn } from "../context/ListContext";
|
|
4
5
|
|
|
5
6
|
export type ImageColumnProps = BaseSourceProps & {
|
|
@@ -31,7 +32,7 @@ export function ImageColumn({
|
|
|
31
32
|
sortable,
|
|
32
33
|
buildColumn: () => ({
|
|
33
34
|
title: label ?? source,
|
|
34
|
-
dataIndex: source,
|
|
35
|
+
dataIndex: columnDataIndex(source),
|
|
35
36
|
key: source,
|
|
36
37
|
sorter: sortable ? true : undefined,
|
|
37
38
|
render: (value: unknown) => {
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { useMemo } from "react";
|
|
2
2
|
import type { BaseSourceProps } from "../types";
|
|
3
|
+
import { columnDataIndex } from "../utils/columnDataIndex";
|
|
3
4
|
import { useRegisterColumn } from "../context/ListContext";
|
|
4
5
|
|
|
5
6
|
export type NumberColumnProps = BaseSourceProps & {
|
|
@@ -19,7 +20,7 @@ export function NumberColumn({
|
|
|
19
20
|
sortable,
|
|
20
21
|
buildColumn: () => ({
|
|
21
22
|
title: label ?? source,
|
|
22
|
-
dataIndex: source,
|
|
23
|
+
dataIndex: columnDataIndex(source),
|
|
23
24
|
key: source,
|
|
24
25
|
sorter: sortable ? true : undefined,
|
|
25
26
|
}),
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { useMemo } from "react";
|
|
2
2
|
import type { BaseSourceProps, DisplayProps, ReferenceProps } from "../types";
|
|
3
3
|
import { useRegisterColumn } from "../context/ListContext";
|
|
4
|
+
import { getFormValue } from "../utils/getFormValue";
|
|
4
5
|
import { useChoices } from "../utils/useChoices";
|
|
5
6
|
import { renderDisplayValue } from "./TextColumn";
|
|
6
7
|
|
|
@@ -25,7 +26,7 @@ function ReferenceColumnCell({
|
|
|
25
26
|
optionLabel,
|
|
26
27
|
optionValue,
|
|
27
28
|
);
|
|
28
|
-
const raw = record
|
|
29
|
+
const raw = getFormValue(record, source);
|
|
29
30
|
if (typeof display === "function") return <>{display(record)}</>;
|
|
30
31
|
if (display && display !== source) {
|
|
31
32
|
const nested = renderDisplayValue(record, source, display);
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { useMemo } from "react";
|
|
2
2
|
import type { BaseSourceProps, DisplayProps, ReferenceProps } from "../types";
|
|
3
3
|
import { useRegisterColumn } from "../context/ListContext";
|
|
4
|
+
import { getFormValue } from "../utils/getFormValue";
|
|
4
5
|
import { useChoices } from "../utils/useChoices";
|
|
5
6
|
|
|
6
7
|
export type ReferenceManyColumnProps = BaseSourceProps &
|
|
@@ -23,7 +24,7 @@ function ReferenceManyColumnCell({
|
|
|
23
24
|
optionLabel,
|
|
24
25
|
optionValue,
|
|
25
26
|
);
|
|
26
|
-
const raw = record
|
|
27
|
+
const raw = getFormValue(record, source);
|
|
27
28
|
const values = Array.isArray(raw) ? raw : [];
|
|
28
29
|
return <>{labelsForValues(values)}</>;
|
|
29
30
|
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { useMemo } from "react";
|
|
2
2
|
import type { BaseSourceProps } from "../types";
|
|
3
|
+
import { columnDataIndex } from "../utils/columnDataIndex";
|
|
3
4
|
import { getFormValue } from "../utils/getFormValue";
|
|
4
5
|
import { useRegisterColumn } from "../context/ListContext";
|
|
5
6
|
|
|
@@ -16,7 +17,7 @@ export function TextColumn({ source, label, sortable = true }: TextColumnProps)
|
|
|
16
17
|
sortable,
|
|
17
18
|
buildColumn: () => ({
|
|
18
19
|
title: label ?? source,
|
|
19
|
-
dataIndex: source,
|
|
20
|
+
dataIndex: columnDataIndex(source),
|
|
20
21
|
key: source,
|
|
21
22
|
sorter: sortable ? true : undefined,
|
|
22
23
|
}),
|
|
@@ -34,5 +35,5 @@ export function renderDisplayValue(
|
|
|
34
35
|
): unknown {
|
|
35
36
|
if (typeof display === "function") return display(record);
|
|
36
37
|
if (display) return getFormValue(record, display);
|
|
37
|
-
return record
|
|
38
|
+
return getFormValue(record, source);
|
|
38
39
|
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { Switch } from "antd";
|
|
2
|
-
import type {
|
|
2
|
+
import type { FieldSourceProps, FieldRules } from "../types";
|
|
3
3
|
import { FieldWrapper } from "./FieldWrapper";
|
|
4
4
|
|
|
5
|
-
export type BooleanFieldProps =
|
|
5
|
+
export type BooleanFieldProps = FieldSourceProps & {
|
|
6
6
|
name?: string;
|
|
7
7
|
required?: boolean;
|
|
8
8
|
rules?: FieldRules;
|
|
@@ -17,6 +17,7 @@ export function BooleanField({
|
|
|
17
17
|
required,
|
|
18
18
|
rules,
|
|
19
19
|
hideLabel,
|
|
20
|
+
hidden,
|
|
20
21
|
disabled: disabledProp,
|
|
21
22
|
}: BooleanFieldProps) {
|
|
22
23
|
return (
|
|
@@ -27,6 +28,7 @@ export function BooleanField({
|
|
|
27
28
|
required={required}
|
|
28
29
|
rules={rules}
|
|
29
30
|
hideLabel={hideLabel}
|
|
31
|
+
hidden={hidden}
|
|
30
32
|
>
|
|
31
33
|
{({ value, onChange, disabled }) => (
|
|
32
34
|
<Switch
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { DatePicker } from "antd";
|
|
2
|
-
import type {
|
|
2
|
+
import type { FieldSourceProps, FieldRules } from "../types";
|
|
3
3
|
import { parseDayjsValue } from "../utils/parseDayjsValue";
|
|
4
4
|
import { FieldWrapper } from "./FieldWrapper";
|
|
5
5
|
|
|
@@ -7,7 +7,7 @@ const DATE_FORMAT = "YYYY-MM-DD";
|
|
|
7
7
|
const DATE_TIME_FORMAT = `${DATE_FORMAT} HH:mm:ss`;
|
|
8
8
|
const PARSE_FORMATS = [DATE_FORMAT, DATE_TIME_FORMAT, "YYYY-MM-DDTHH:mm:ss", "YYYY-MM-DDTHH:mm:ssZ"];
|
|
9
9
|
|
|
10
|
-
export type DateFieldProps =
|
|
10
|
+
export type DateFieldProps = FieldSourceProps & {
|
|
11
11
|
name?: string;
|
|
12
12
|
required?: boolean;
|
|
13
13
|
rules?: FieldRules;
|
|
@@ -23,6 +23,7 @@ export function DateField({
|
|
|
23
23
|
rules,
|
|
24
24
|
showTime,
|
|
25
25
|
hideLabel,
|
|
26
|
+
hidden,
|
|
26
27
|
}: DateFieldProps) {
|
|
27
28
|
return (
|
|
28
29
|
<FieldWrapper
|
|
@@ -32,6 +33,7 @@ export function DateField({
|
|
|
32
33
|
required={required}
|
|
33
34
|
rules={rules}
|
|
34
35
|
hideLabel={hideLabel}
|
|
36
|
+
hidden={hidden}
|
|
35
37
|
>
|
|
36
38
|
{({ value, onChange, onBlur, disabled }) => (
|
|
37
39
|
<DatePicker
|
|
@@ -7,6 +7,8 @@ import {
|
|
|
7
7
|
useRegisterPayloadField,
|
|
8
8
|
useRegisterSectionField,
|
|
9
9
|
} from "../context/PayloadFieldsContext";
|
|
10
|
+
import { shouldRegisterSourceInPayload } from "../utils/shouldRegisterSourceInPayload";
|
|
11
|
+
import { isSourceHidden, useHiddenSources } from "../HiddenSources";
|
|
10
12
|
|
|
11
13
|
export type FieldWrapperProps = {
|
|
12
14
|
/** Logical field name — used for submit payload tracking on top-level fields. */
|
|
@@ -18,6 +20,8 @@ export type FieldWrapperProps = {
|
|
|
18
20
|
rules?: FieldRules;
|
|
19
21
|
/** Tabular inline cells: column header replaces the label. */
|
|
20
22
|
hideLabel?: boolean;
|
|
23
|
+
/** Hide the control but keep the value in the form and save payload. */
|
|
24
|
+
hidden?: boolean;
|
|
21
25
|
children: (props: {
|
|
22
26
|
value: unknown;
|
|
23
27
|
onChange: (value: unknown) => void;
|
|
@@ -34,10 +38,12 @@ export function FieldWrapper({
|
|
|
34
38
|
required,
|
|
35
39
|
rules,
|
|
36
40
|
hideLabel,
|
|
41
|
+
hidden,
|
|
37
42
|
children,
|
|
38
43
|
}: FieldWrapperProps) {
|
|
39
44
|
const fieldName = name ?? source;
|
|
40
|
-
const
|
|
45
|
+
const registerSource = shouldRegisterSourceInPayload(source, name);
|
|
46
|
+
const isHidden = isSourceHidden(source, hidden, useHiddenSources());
|
|
41
47
|
|
|
42
48
|
// react-hook-form: connect this field to the form from <ResourceForm>'s FormProvider.
|
|
43
49
|
// `control` is passed to <Controller> below so value, onChange, and validation work.
|
|
@@ -49,13 +55,20 @@ export function FieldWrapper({
|
|
|
49
55
|
const fieldLabel = hideLabel ? undefined : (label ?? source);
|
|
50
56
|
const requiredMessage = label ?? source;
|
|
51
57
|
|
|
52
|
-
//
|
|
53
|
-
// `
|
|
54
|
-
|
|
55
|
-
|
|
58
|
+
// Nested parent fields (`source="address.city"`) register; inline cells
|
|
59
|
+
// (`name="lines.0.label"`, `source="label"`) do not — those go through the inline array.
|
|
60
|
+
useRegisterPayloadField(source, registerSource);
|
|
61
|
+
useRegisterSectionField(source, registerSource);
|
|
56
62
|
|
|
57
|
-
|
|
58
|
-
|
|
63
|
+
if (isHidden) {
|
|
64
|
+
return (
|
|
65
|
+
<Controller
|
|
66
|
+
name={fieldName}
|
|
67
|
+
control={control}
|
|
68
|
+
render={() => <></>}
|
|
69
|
+
/>
|
|
70
|
+
);
|
|
71
|
+
}
|
|
59
72
|
|
|
60
73
|
return (
|
|
61
74
|
<Controller
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { DeleteOutlined, PaperClipOutlined, UploadOutlined } from "@ant-design/icons";
|
|
2
2
|
import { Button, Space, Typography } from "antd";
|
|
3
3
|
import { useRef } from "react";
|
|
4
|
-
import type {
|
|
4
|
+
import type { FieldSourceProps, FieldRules } from "../types";
|
|
5
5
|
import { FieldWrapper } from "./FieldWrapper";
|
|
6
6
|
import {
|
|
7
7
|
getUploadFileName,
|
|
@@ -9,7 +9,7 @@ import {
|
|
|
9
9
|
type UploadFieldValue,
|
|
10
10
|
} from "./uploadFieldUtils";
|
|
11
11
|
|
|
12
|
-
export type FileFieldProps =
|
|
12
|
+
export type FileFieldProps = FieldSourceProps & {
|
|
13
13
|
name?: string;
|
|
14
14
|
required?: boolean;
|
|
15
15
|
rules?: FieldRules;
|
|
@@ -97,6 +97,7 @@ export function FileField({
|
|
|
97
97
|
required,
|
|
98
98
|
rules,
|
|
99
99
|
hideLabel,
|
|
100
|
+
hidden,
|
|
100
101
|
clearable,
|
|
101
102
|
accept,
|
|
102
103
|
}: FileFieldProps) {
|
|
@@ -108,6 +109,7 @@ export function FileField({
|
|
|
108
109
|
required={required}
|
|
109
110
|
rules={rules}
|
|
110
111
|
hideLabel={hideLabel}
|
|
112
|
+
hidden={hidden}
|
|
111
113
|
>
|
|
112
114
|
{({ value, onChange, disabled }) => (
|
|
113
115
|
<FileFieldInput
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { DeleteOutlined, UploadOutlined } from "@ant-design/icons";
|
|
2
2
|
import { Button, Image, Space } from "antd";
|
|
3
3
|
import { useRef } from "react";
|
|
4
|
-
import type {
|
|
4
|
+
import type { FieldSourceProps, FieldRules } from "../types";
|
|
5
5
|
import { FieldWrapper } from "./FieldWrapper";
|
|
6
6
|
import { hasUploadValue, type UploadFieldValue } from "./uploadFieldUtils";
|
|
7
7
|
import { useUploadPreviewUrl } from "./useUploadPreviewUrl";
|
|
8
8
|
|
|
9
|
-
export type ImageFieldProps =
|
|
9
|
+
export type ImageFieldProps = FieldSourceProps & {
|
|
10
10
|
name?: string;
|
|
11
11
|
required?: boolean;
|
|
12
12
|
rules?: FieldRules;
|
|
@@ -92,6 +92,7 @@ export function ImageField({
|
|
|
92
92
|
required,
|
|
93
93
|
rules,
|
|
94
94
|
hideLabel,
|
|
95
|
+
hidden,
|
|
95
96
|
clearable,
|
|
96
97
|
accept,
|
|
97
98
|
previewWidth,
|
|
@@ -104,6 +105,7 @@ export function ImageField({
|
|
|
104
105
|
required={required}
|
|
105
106
|
rules={rules}
|
|
106
107
|
hideLabel={hideLabel}
|
|
108
|
+
hidden={hidden}
|
|
107
109
|
>
|
|
108
110
|
{({ value, onChange, disabled }) => (
|
|
109
111
|
<ImageFieldInput
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { InputNumber } from "antd";
|
|
2
2
|
import type { CSSProperties } from "react";
|
|
3
|
-
import type {
|
|
3
|
+
import type { FieldSourceProps, FieldRules } from "../types";
|
|
4
4
|
import { FieldWrapper } from "./FieldWrapper";
|
|
5
5
|
|
|
6
|
-
export type NumberFieldProps =
|
|
6
|
+
export type NumberFieldProps = FieldSourceProps & {
|
|
7
7
|
name?: string;
|
|
8
8
|
required?: boolean;
|
|
9
9
|
rules?: FieldRules;
|
|
@@ -25,6 +25,7 @@ export function NumberField({
|
|
|
25
25
|
step,
|
|
26
26
|
inputStyle,
|
|
27
27
|
hideLabel,
|
|
28
|
+
hidden,
|
|
28
29
|
}: NumberFieldProps) {
|
|
29
30
|
return (
|
|
30
31
|
<FieldWrapper
|
|
@@ -34,6 +35,7 @@ export function NumberField({
|
|
|
34
35
|
required={required}
|
|
35
36
|
rules={rules}
|
|
36
37
|
hideLabel={hideLabel}
|
|
38
|
+
hidden={hidden}
|
|
37
39
|
>
|
|
38
40
|
{({ value, onChange, onBlur, disabled }) => (
|
|
39
41
|
<InputNumber
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { Input } from "antd";
|
|
2
2
|
import { useWatch } from "react-hook-form";
|
|
3
|
-
import type {
|
|
3
|
+
import type { FieldSourceProps, FieldRules } from "../types";
|
|
4
4
|
import { FieldWrapper } from "./FieldWrapper";
|
|
5
5
|
|
|
6
|
-
export type PasswordFieldProps =
|
|
6
|
+
export type PasswordFieldProps = FieldSourceProps & {
|
|
7
7
|
name?: string;
|
|
8
8
|
required?: boolean;
|
|
9
9
|
rules?: FieldRules;
|
|
@@ -22,6 +22,7 @@ function PasswordInputField({
|
|
|
22
22
|
rules,
|
|
23
23
|
autoComplete,
|
|
24
24
|
hideLabel,
|
|
25
|
+
hidden,
|
|
25
26
|
}: PasswordFieldProps) {
|
|
26
27
|
return (
|
|
27
28
|
<FieldWrapper
|
|
@@ -31,6 +32,7 @@ function PasswordInputField({
|
|
|
31
32
|
required={required}
|
|
32
33
|
rules={rules}
|
|
33
34
|
hideLabel={hideLabel}
|
|
35
|
+
hidden={hidden}
|
|
34
36
|
>
|
|
35
37
|
{({ value, onChange, onBlur, disabled }) => (
|
|
36
38
|
<Input.Password
|
|
@@ -55,6 +57,7 @@ export function PasswordField({
|
|
|
55
57
|
confirmLabel = "Confirm password",
|
|
56
58
|
autoComplete = "new-password",
|
|
57
59
|
hideLabel,
|
|
60
|
+
hidden,
|
|
58
61
|
}: PasswordFieldProps) {
|
|
59
62
|
const password = useWatch({ name: name ?? source, disabled: !confirmSource });
|
|
60
63
|
|
|
@@ -68,6 +71,7 @@ export function PasswordField({
|
|
|
68
71
|
rules={rules}
|
|
69
72
|
autoComplete={autoComplete}
|
|
70
73
|
hideLabel={hideLabel}
|
|
74
|
+
hidden={hidden}
|
|
71
75
|
/>
|
|
72
76
|
);
|
|
73
77
|
}
|
|
@@ -82,6 +86,7 @@ export function PasswordField({
|
|
|
82
86
|
rules={rules}
|
|
83
87
|
autoComplete={autoComplete}
|
|
84
88
|
hideLabel={hideLabel}
|
|
89
|
+
hidden={hidden}
|
|
85
90
|
/>
|
|
86
91
|
<PasswordInputField
|
|
87
92
|
source={confirmSource}
|
|
@@ -93,6 +98,7 @@ export function PasswordField({
|
|
|
93
98
|
validate: (value: string) =>
|
|
94
99
|
!password || value === password || "Passwords do not match",
|
|
95
100
|
}}
|
|
101
|
+
hidden={hidden}
|
|
96
102
|
/>
|
|
97
103
|
</>
|
|
98
104
|
);
|
|
@@ -3,7 +3,7 @@ import type { CSSProperties } from "react";
|
|
|
3
3
|
import { useMemo, useState } from "react";
|
|
4
4
|
import { useWatch } from "react-hook-form";
|
|
5
5
|
import type {
|
|
6
|
-
|
|
6
|
+
FieldSourceProps,
|
|
7
7
|
ChoiceOption,
|
|
8
8
|
FieldRules,
|
|
9
9
|
ReferenceProps,
|
|
@@ -21,7 +21,7 @@ import { ReferenceInputActions } from "./ReferenceInputActions";
|
|
|
21
21
|
import type { ResourcePermissions } from "../../permissions/resourcePermissions";
|
|
22
22
|
import type { ReactNode } from "react";
|
|
23
23
|
|
|
24
|
-
export type ReferenceFieldProps =
|
|
24
|
+
export type ReferenceFieldProps = FieldSourceProps &
|
|
25
25
|
ReferenceProps & {
|
|
26
26
|
name?: string;
|
|
27
27
|
required?: boolean;
|
|
@@ -142,8 +142,10 @@ function ReferenceFieldSelect({
|
|
|
142
142
|
{...referenceSelectDropdownProps({ popupMatchSelectWidth, popupMinWidth })}
|
|
143
143
|
value={referenceSelectDisplayValue(selectedLoading, selectValue, undefined)}
|
|
144
144
|
onChange={(next) => {
|
|
145
|
-
|
|
146
|
-
|
|
145
|
+
// Ant Design clear emits undefined; RHF Controller ignores that.
|
|
146
|
+
const value = next ?? null;
|
|
147
|
+
onChange(value);
|
|
148
|
+
onValueChange?.(value, optionForValue(next), { name: fieldName });
|
|
147
149
|
}}
|
|
148
150
|
options={selectOptions}
|
|
149
151
|
loading={selectState.loading}
|
|
@@ -197,6 +199,7 @@ export function ReferenceField({
|
|
|
197
199
|
allowClear,
|
|
198
200
|
disabled: disabledProp,
|
|
199
201
|
hideLabel,
|
|
202
|
+
hidden,
|
|
200
203
|
inputStyle,
|
|
201
204
|
onValueChange,
|
|
202
205
|
lazy = true,
|
|
@@ -224,6 +227,7 @@ export function ReferenceField({
|
|
|
224
227
|
required={required}
|
|
225
228
|
rules={rules}
|
|
226
229
|
hideLabel={hideLabel}
|
|
230
|
+
hidden={hidden}
|
|
227
231
|
>
|
|
228
232
|
{({ value, onChange, disabled, name: fieldName }) => (
|
|
229
233
|
<ReferenceFieldSelect
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Select } from "antd";
|
|
2
2
|
import { useMemo, useState } from "react";
|
|
3
3
|
import { useWatch } from "react-hook-form";
|
|
4
|
-
import type {
|
|
4
|
+
import type { FieldSourceProps, FieldRules, ReferenceProps } from "../types";
|
|
5
5
|
import { valuesAsIds } from "../utils/choiceSelectionUtils";
|
|
6
6
|
import { referenceSelectDropdownProps } from "../utils/referenceSelectDropdownProps";
|
|
7
7
|
import { referenceSelectNotFoundContent } from "../utils/referenceSelectNotFoundContent";
|
|
@@ -15,7 +15,7 @@ import { ReferenceInputActions } from "./ReferenceInputActions";
|
|
|
15
15
|
import type { ResourcePermissions } from "../../permissions/resourcePermissions";
|
|
16
16
|
import type { ReactNode } from "react";
|
|
17
17
|
|
|
18
|
-
export type ReferenceManyFieldProps =
|
|
18
|
+
export type ReferenceManyFieldProps = FieldSourceProps &
|
|
19
19
|
ReferenceProps & {
|
|
20
20
|
name?: string;
|
|
21
21
|
required?: boolean;
|
|
@@ -106,7 +106,7 @@ function ReferenceManyFieldSelect({
|
|
|
106
106
|
{...referenceSelectDropdownProps({ popupMatchSelectWidth, popupMinWidth })}
|
|
107
107
|
mode="multiple"
|
|
108
108
|
value={referenceSelectDisplayValue(selectedLoading, selectValue, [])}
|
|
109
|
-
onChange={onChange}
|
|
109
|
+
onChange={(next) => onChange(next ?? [])}
|
|
110
110
|
options={selectOptions}
|
|
111
111
|
loading={selectState.loading}
|
|
112
112
|
notFoundContent={referenceSelectNotFoundContent(selectState.loading)}
|
|
@@ -165,6 +165,7 @@ export function ReferenceManyField({
|
|
|
165
165
|
search,
|
|
166
166
|
allowClear = true,
|
|
167
167
|
hideLabel,
|
|
168
|
+
hidden,
|
|
168
169
|
disabled: disabledProp,
|
|
169
170
|
lazy = true,
|
|
170
171
|
recordSource,
|
|
@@ -191,6 +192,7 @@ export function ReferenceManyField({
|
|
|
191
192
|
required={required}
|
|
192
193
|
rules={rules}
|
|
193
194
|
hideLabel={hideLabel}
|
|
195
|
+
hidden={hidden}
|
|
194
196
|
>
|
|
195
197
|
{({ value, onChange, disabled }) => (
|
|
196
198
|
<ReferenceManyFieldSelect
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { Select } from "antd";
|
|
2
|
-
import type {
|
|
2
|
+
import type { FieldSourceProps, ChoiceOption, FieldRules } from "../types";
|
|
3
3
|
import { FieldWrapper } from "./FieldWrapper";
|
|
4
4
|
|
|
5
|
-
export type SelectFieldProps =
|
|
5
|
+
export type SelectFieldProps = FieldSourceProps & {
|
|
6
6
|
name?: string;
|
|
7
7
|
required?: boolean;
|
|
8
8
|
rules?: FieldRules;
|
|
@@ -22,6 +22,7 @@ export function SelectField({
|
|
|
22
22
|
mode,
|
|
23
23
|
allowClear,
|
|
24
24
|
hideLabel,
|
|
25
|
+
hidden,
|
|
25
26
|
}: SelectFieldProps) {
|
|
26
27
|
return (
|
|
27
28
|
<FieldWrapper
|
|
@@ -31,11 +32,12 @@ export function SelectField({
|
|
|
31
32
|
required={required}
|
|
32
33
|
rules={rules}
|
|
33
34
|
hideLabel={hideLabel}
|
|
35
|
+
hidden={hidden}
|
|
34
36
|
>
|
|
35
37
|
{({ value, onChange, disabled }) => (
|
|
36
38
|
<Select
|
|
37
39
|
value={value as string | number | (string | number)[] | undefined}
|
|
38
|
-
onChange={onChange}
|
|
40
|
+
onChange={(next) => onChange(next ?? null)}
|
|
39
41
|
options={choices}
|
|
40
42
|
mode={mode}
|
|
41
43
|
allowClear={allowClear}
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { Input } from "antd";
|
|
2
2
|
import type { CSSProperties } from "react";
|
|
3
|
-
import type {
|
|
3
|
+
import type { FieldSourceProps, FieldRules } from "../types";
|
|
4
4
|
import { FieldWrapper } from "./FieldWrapper";
|
|
5
5
|
|
|
6
|
-
export type TextAreaFieldProps =
|
|
6
|
+
export type TextAreaFieldProps = FieldSourceProps & {
|
|
7
7
|
name?: string;
|
|
8
8
|
required?: boolean;
|
|
9
9
|
rules?: FieldRules;
|
|
@@ -25,6 +25,7 @@ export function TextAreaField({
|
|
|
25
25
|
placeholder,
|
|
26
26
|
inputStyle,
|
|
27
27
|
hideLabel,
|
|
28
|
+
hidden,
|
|
28
29
|
rows = 4,
|
|
29
30
|
maxLength,
|
|
30
31
|
showCount,
|
|
@@ -38,6 +39,7 @@ export function TextAreaField({
|
|
|
38
39
|
required={required}
|
|
39
40
|
rules={rules}
|
|
40
41
|
hideLabel={hideLabel}
|
|
42
|
+
hidden={hidden}
|
|
41
43
|
>
|
|
42
44
|
{({ value, onChange, onBlur, disabled }) => (
|
|
43
45
|
<Input.TextArea
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { Input } from "antd";
|
|
2
2
|
import type { CSSProperties } from "react";
|
|
3
|
-
import type {
|
|
3
|
+
import type { FieldSourceProps, FieldRules } from "../types";
|
|
4
4
|
import { FieldWrapper } from "./FieldWrapper";
|
|
5
5
|
|
|
6
|
-
export type TextFieldProps =
|
|
6
|
+
export type TextFieldProps = FieldSourceProps & {
|
|
7
7
|
name?: string;
|
|
8
8
|
required?: boolean;
|
|
9
9
|
rules?: FieldRules;
|
|
@@ -21,6 +21,7 @@ export function TextField({
|
|
|
21
21
|
placeholder,
|
|
22
22
|
inputStyle,
|
|
23
23
|
hideLabel,
|
|
24
|
+
hidden,
|
|
24
25
|
}: TextFieldProps) {
|
|
25
26
|
return (
|
|
26
27
|
<FieldWrapper
|
|
@@ -30,6 +31,7 @@ export function TextField({
|
|
|
30
31
|
required={required}
|
|
31
32
|
rules={rules}
|
|
32
33
|
hideLabel={hideLabel}
|
|
34
|
+
hidden={hidden}
|
|
33
35
|
>
|
|
34
36
|
{({ value, onChange, onBlur, disabled }) => (
|
|
35
37
|
<Input
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { TimePicker } from "antd";
|
|
2
|
-
import type {
|
|
2
|
+
import type { FieldSourceProps, FieldRules } from "../types";
|
|
3
3
|
import { parseDayjsValue } from "../utils/parseDayjsValue";
|
|
4
4
|
import { FieldWrapper } from "./FieldWrapper";
|
|
5
5
|
|
|
6
6
|
const DEFAULT_TIME_FORMAT = "HH:mm:ss";
|
|
7
7
|
const PARSE_FORMATS = [DEFAULT_TIME_FORMAT, "HH:mm", "H:mm:ss", "H:mm"];
|
|
8
8
|
|
|
9
|
-
export type TimeFieldProps =
|
|
9
|
+
export type TimeFieldProps = FieldSourceProps & {
|
|
10
10
|
name?: string;
|
|
11
11
|
required?: boolean;
|
|
12
12
|
rules?: FieldRules;
|
|
@@ -22,6 +22,7 @@ export function TimeField({
|
|
|
22
22
|
required,
|
|
23
23
|
rules,
|
|
24
24
|
hideLabel,
|
|
25
|
+
hidden,
|
|
25
26
|
format = DEFAULT_TIME_FORMAT,
|
|
26
27
|
}: TimeFieldProps) {
|
|
27
28
|
return (
|
|
@@ -32,6 +33,7 @@ export function TimeField({
|
|
|
32
33
|
required={required}
|
|
33
34
|
rules={rules}
|
|
34
35
|
hideLabel={hideLabel}
|
|
36
|
+
hidden={hidden}
|
|
35
37
|
>
|
|
36
38
|
{({ value, onChange, onBlur, disabled }) => (
|
|
37
39
|
<TimePicker
|
package/src/crud/index.ts
CHANGED
|
@@ -5,6 +5,7 @@ export { ResourceForm } from "./ResourceForm";
|
|
|
5
5
|
export type { ResourceFormProps } from "./ResourceForm";
|
|
6
6
|
export { ResourceFormModal } from "./ResourceFormModal";
|
|
7
7
|
export type { ResourceFormModalProps } from "./ResourceFormModal";
|
|
8
|
+
export { HiddenSources } from "./HiddenSources";
|
|
8
9
|
export { InlineFormSet, InlineFormSetStacked } from "./InlineFormSet";
|
|
9
10
|
export type {
|
|
10
11
|
InlineFormSetProps,
|
|
@@ -75,6 +76,7 @@ export { getFormValue } from "./utils/getFormValue";
|
|
|
75
76
|
export { setFormValue } from "./utils/setFormValue";
|
|
76
77
|
export { buildFormPayload } from "./utils/buildFormPayload";
|
|
77
78
|
export { buildInlineRowsPayload } from "./utils/buildInlineRowsPayload";
|
|
79
|
+
export { columnDataIndex } from "./utils/columnDataIndex";
|
|
78
80
|
export { buildResourceFormSubmitBody } from "./utils/buildResourceFormSubmitBody";
|
|
79
81
|
export { prepareFormSubmitBody } from "./utils/prepareFormSubmitBody";
|
|
80
82
|
export { toFormData } from "./utils/toFormData";
|
|
@@ -90,6 +92,7 @@ export type { InlineFieldRegistration } from "./context/InlineFieldsRegistry";
|
|
|
90
92
|
|
|
91
93
|
export type {
|
|
92
94
|
BaseSourceProps,
|
|
95
|
+
FieldSourceProps,
|
|
93
96
|
ChoiceOption,
|
|
94
97
|
ChoicesLoader,
|
|
95
98
|
ReferenceProps,
|
package/src/crud/types.ts
CHANGED
|
@@ -8,6 +8,12 @@ export type BaseSourceProps = {
|
|
|
8
8
|
label?: string;
|
|
9
9
|
};
|
|
10
10
|
|
|
11
|
+
/** Form fields only — columns and filters do not hide-and-keep a value. */
|
|
12
|
+
export type FieldSourceProps = BaseSourceProps & {
|
|
13
|
+
/** Hide the control but keep the value in the form and save payload. */
|
|
14
|
+
hidden?: boolean;
|
|
15
|
+
};
|
|
16
|
+
|
|
11
17
|
export type ChoiceOption = {
|
|
12
18
|
label: string;
|
|
13
19
|
value: unknown;
|