@byline/admin 3.20.1 → 3.20.2
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/fields/relation/relation-field.js +56 -54
- package/dist/fields/relation/relation-field.module.js +2 -2
- package/dist/fields/relation/relation-field_module.css +27 -6
- package/dist/fields/relation/relation-many-field.js +51 -47
- package/package.json +5 -5
- package/src/fields/relation/relation-field.module.css +38 -8
- package/src/fields/relation/relation-field.tsx +58 -46
- package/src/fields/relation/relation-many-field.tsx +50 -46
|
@@ -2,7 +2,7 @@ import { jsx, jsxs } from "react/jsx-runtime";
|
|
|
2
2
|
import { useState } from "react";
|
|
3
3
|
import { getCollectionAdminConfig, getCollectionDefinition } from "@byline/core";
|
|
4
4
|
import { useTranslation } from "@byline/i18n/react";
|
|
5
|
-
import { Button, CloseIcon, EditIcon, ErrorText, IconButton, Label } from "@byline/ui/react";
|
|
5
|
+
import { Button, CloseIcon, EditIcon, ErrorText, HelpText, IconButton, Label } from "@byline/ui/react";
|
|
6
6
|
import classnames from "classnames";
|
|
7
7
|
import { useFieldError, useFieldValue } from "../../forms/form-context.js";
|
|
8
8
|
import relation_field_module from "./relation-field.module.js";
|
|
@@ -48,10 +48,6 @@ const RelationField = ({ field, value, defaultValue, onChange, id, path })=>{
|
|
|
48
48
|
required: !field.optional
|
|
49
49
|
})
|
|
50
50
|
}),
|
|
51
|
-
field.helpText && /*#__PURE__*/ jsx("div", {
|
|
52
|
-
className: classnames('byline-field-relation-help', relation_field_module.help),
|
|
53
|
-
children: field.helpText
|
|
54
|
-
}),
|
|
55
51
|
isUnknown ? /*#__PURE__*/ jsxs("div", {
|
|
56
52
|
className: classnames('byline-field-relation-error-tile', relation_field_module["error-tile"]),
|
|
57
53
|
children: [
|
|
@@ -66,60 +62,66 @@ const RelationField = ({ field, value, defaultValue, onChange, id, path })=>{
|
|
|
66
62
|
children: t('fields.relation.unknownHint')
|
|
67
63
|
})
|
|
68
64
|
]
|
|
69
|
-
}) :
|
|
70
|
-
className: classnames('byline-field-relation-
|
|
71
|
-
children:
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
type: "button",
|
|
98
|
-
intent: "noeffect",
|
|
99
|
-
size: "xs",
|
|
100
|
-
"aria-label": t('fields.relation.removeAriaLabel', {
|
|
101
|
-
label: targetDef.labels.singular
|
|
65
|
+
}) : /*#__PURE__*/ jsx("div", {
|
|
66
|
+
className: classnames('byline-field-relation-frame', relation_field_module.frame),
|
|
67
|
+
children: incomingValue ? /*#__PURE__*/ jsxs("div", {
|
|
68
|
+
className: classnames('byline-field-relation-tile', relation_field_module.tile),
|
|
69
|
+
children: [
|
|
70
|
+
/*#__PURE__*/ jsx(RelationSummary, {
|
|
71
|
+
targetDefinition: targetDef,
|
|
72
|
+
targetAdminConfig: targetAdminConfig,
|
|
73
|
+
displayField: field.displayField,
|
|
74
|
+
value: incomingValue,
|
|
75
|
+
cachedRecord: cachedRecord
|
|
76
|
+
}),
|
|
77
|
+
/*#__PURE__*/ jsxs("div", {
|
|
78
|
+
className: classnames('byline-field-relation-actions', relation_field_module.actions),
|
|
79
|
+
children: [
|
|
80
|
+
/*#__PURE__*/ jsx(IconButton, {
|
|
81
|
+
id: htmlId,
|
|
82
|
+
type: "button",
|
|
83
|
+
intent: "noeffect",
|
|
84
|
+
size: "xs",
|
|
85
|
+
"aria-label": t('fields.relation.changeAriaLabel', {
|
|
86
|
+
label: targetDef.labels.singular
|
|
87
|
+
}),
|
|
88
|
+
onClick: ()=>setPickerOpen(true),
|
|
89
|
+
children: /*#__PURE__*/ jsx(EditIcon, {
|
|
90
|
+
width: "15px",
|
|
91
|
+
height: "15px"
|
|
92
|
+
})
|
|
102
93
|
}),
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
94
|
+
/*#__PURE__*/ jsx(IconButton, {
|
|
95
|
+
type: "button",
|
|
96
|
+
intent: "noeffect",
|
|
97
|
+
size: "xs",
|
|
98
|
+
"aria-label": t('fields.relation.removeAriaLabel', {
|
|
99
|
+
label: targetDef.labels.singular
|
|
100
|
+
}),
|
|
101
|
+
onClick: handleRemove,
|
|
102
|
+
children: /*#__PURE__*/ jsx(CloseIcon, {
|
|
103
|
+
width: "15px",
|
|
104
|
+
height: "15px"
|
|
105
|
+
})
|
|
107
106
|
})
|
|
108
|
-
|
|
109
|
-
|
|
107
|
+
]
|
|
108
|
+
})
|
|
109
|
+
]
|
|
110
|
+
}) : /*#__PURE__*/ jsx(Button, {
|
|
111
|
+
id: htmlId,
|
|
112
|
+
size: "xs",
|
|
113
|
+
variant: "outlined",
|
|
114
|
+
intent: "noeffect",
|
|
115
|
+
type: "button",
|
|
116
|
+
onClick: ()=>setPickerOpen(true),
|
|
117
|
+
children: t('fields.relation.selectButton', {
|
|
118
|
+
label: targetDef.labels.singular
|
|
110
119
|
})
|
|
111
|
-
]
|
|
112
|
-
}) : /*#__PURE__*/ jsx(Button, {
|
|
113
|
-
id: htmlId,
|
|
114
|
-
size: "xs",
|
|
115
|
-
variant: "outlined",
|
|
116
|
-
intent: "noeffect",
|
|
117
|
-
type: "button",
|
|
118
|
-
onClick: ()=>setPickerOpen(true),
|
|
119
|
-
children: t('fields.relation.selectButton', {
|
|
120
|
-
label: targetDef.labels.singular
|
|
121
120
|
})
|
|
122
121
|
}),
|
|
122
|
+
null != field.helpText && /*#__PURE__*/ jsx(HelpText, {
|
|
123
|
+
text: field.helpText
|
|
124
|
+
}),
|
|
123
125
|
fieldError && /*#__PURE__*/ jsx(ErrorText, {
|
|
124
126
|
id: `${field.name}-error`,
|
|
125
127
|
text: fieldError
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import "./relation-field_module.css";
|
|
2
2
|
const relation_field_module = {
|
|
3
3
|
header: "header-y7lSnb",
|
|
4
|
-
help: "help-DEGVPH",
|
|
5
4
|
"error-tile": "error-tile-y2kiiq",
|
|
6
5
|
errorTile: "error-tile-y2kiiq",
|
|
7
6
|
"error-text": "error-text-jHQh34",
|
|
@@ -23,6 +22,7 @@ const relation_field_module = {
|
|
|
23
22
|
"many-remove": "many-remove-fuuKiO",
|
|
24
23
|
manyRemove: "many-remove-fuuKiO",
|
|
25
24
|
"many-add": "many-add-c5uQ7B",
|
|
26
|
-
manyAdd: "many-add-c5uQ7B"
|
|
25
|
+
manyAdd: "many-add-c5uQ7B",
|
|
26
|
+
frame: "frame-uo2RPX"
|
|
27
27
|
};
|
|
28
28
|
export default relation_field_module;
|
|
@@ -5,12 +5,6 @@
|
|
|
5
5
|
display: flex;
|
|
6
6
|
}
|
|
7
7
|
|
|
8
|
-
:is(.help-DEGVPH, .byline-field-relation-help) {
|
|
9
|
-
color: var(--gray-400);
|
|
10
|
-
font-size: var(--font-size-xs);
|
|
11
|
-
margin-bottom: .25rem;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
8
|
:is(.error-tile-y2kiiq, .byline-field-relation-error-tile) {
|
|
15
9
|
padding: var(--spacing-8);
|
|
16
10
|
border: var(--border-width-thin) var(--border-style-solid) var(--red-700);
|
|
@@ -124,3 +118,30 @@
|
|
|
124
118
|
display: flex;
|
|
125
119
|
}
|
|
126
120
|
|
|
121
|
+
:is(.frame-uo2RPX, .byline-field-relation-frame) {
|
|
122
|
+
border: var(--border-width-thin) var(--border-style-solid) var(--field-border);
|
|
123
|
+
border-radius: var(--border-radius-md, 6px);
|
|
124
|
+
margin-top: .25rem;
|
|
125
|
+
padding: .5rem;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
.frame-uo2RPX > .tile-Y3_yre, .frame-uo2RPX > .many-ohEmr7 {
|
|
129
|
+
margin-top: 0;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
.byline-field-relation-frame > .byline-field-relation-tile {
|
|
133
|
+
margin-top: 0;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
.byline-field-relation-frame > .byline-field-relation-many {
|
|
137
|
+
margin-top: 0;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
.frame-uo2RPX > .many-empty-T0OJd9 {
|
|
141
|
+
margin-top: 0;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
.byline-field-relation-frame > .byline-field-relation-many-empty {
|
|
145
|
+
margin-top: 0;
|
|
146
|
+
}
|
|
147
|
+
|
|
@@ -2,7 +2,7 @@ import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
|
2
2
|
import { useState } from "react";
|
|
3
3
|
import { getCollectionAdminConfig, getCollectionDefinition } from "@byline/core";
|
|
4
4
|
import { useTranslation } from "@byline/i18n/react";
|
|
5
|
-
import { Button, CloseIcon, DraggableSortable, ErrorText, GripperVerticalIcon, IconButton, Label, PlusIcon, moveItem, useSortable } from "@byline/ui/react";
|
|
5
|
+
import { Button, CloseIcon, DraggableSortable, ErrorText, GripperVerticalIcon, HelpText, IconButton, Label, PlusIcon, moveItem, useSortable } from "@byline/ui/react";
|
|
6
6
|
import classnames from "classnames";
|
|
7
7
|
import { useFieldError, useFieldValue, useFormContext } from "../../forms/form-context.js";
|
|
8
8
|
import relation_field_module from "./relation-field.module.js";
|
|
@@ -115,10 +115,6 @@ const RelationManyField = ({ field, defaultValue, id, path })=>{
|
|
|
115
115
|
required: !field.optional
|
|
116
116
|
})
|
|
117
117
|
}),
|
|
118
|
-
field.helpText && /*#__PURE__*/ jsx("div", {
|
|
119
|
-
className: classnames('byline-field-relation-help', relation_field_module.help),
|
|
120
|
-
children: field.helpText
|
|
121
|
-
}),
|
|
122
118
|
isUnknown ? /*#__PURE__*/ jsxs("div", {
|
|
123
119
|
className: classnames('byline-field-relation-error-tile', relation_field_module["error-tile"]),
|
|
124
120
|
children: [
|
|
@@ -135,54 +131,62 @@ const RelationManyField = ({ field, defaultValue, id, path })=>{
|
|
|
135
131
|
]
|
|
136
132
|
}) : /*#__PURE__*/ jsxs(Fragment, {
|
|
137
133
|
children: [
|
|
138
|
-
|
|
139
|
-
className: classnames('byline-field-relation-
|
|
140
|
-
children:
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
onDragEnd: handleDragEnd,
|
|
146
|
-
className: classnames('byline-field-relation-many', relation_field_module.many),
|
|
147
|
-
children: items.map((value)=>/*#__PURE__*/ jsx(RelationManyTile, {
|
|
148
|
-
id: value.targetDocumentId,
|
|
149
|
-
onRemove: ()=>handleRemove(value.targetDocumentId),
|
|
150
|
-
removeAriaLabel: t('fields.relation.removeAriaLabel', {
|
|
151
|
-
label: targetLabel
|
|
152
|
-
}),
|
|
153
|
-
children: /*#__PURE__*/ jsx(RelationSummary, {
|
|
154
|
-
targetDefinition: targetDef,
|
|
155
|
-
targetAdminConfig: targetAdminConfig,
|
|
156
|
-
displayField: field.displayField,
|
|
157
|
-
value: value,
|
|
158
|
-
cachedRecord: pickedRecords[value.targetDocumentId] ?? null
|
|
134
|
+
/*#__PURE__*/ jsxs("div", {
|
|
135
|
+
className: classnames('byline-field-relation-frame', relation_field_module.frame),
|
|
136
|
+
children: [
|
|
137
|
+
0 === items.length ? /*#__PURE__*/ jsx("p", {
|
|
138
|
+
className: classnames('byline-field-relation-many-empty', relation_field_module["many-empty"]),
|
|
139
|
+
children: t('fields.relation.manyEmpty', {
|
|
140
|
+
label: targetDef.labels.plural
|
|
159
141
|
})
|
|
160
|
-
},
|
|
142
|
+
}) : /*#__PURE__*/ jsx(DraggableSortable, {
|
|
143
|
+
ids: items.map((v)=>v.targetDocumentId),
|
|
144
|
+
onDragEnd: handleDragEnd,
|
|
145
|
+
className: classnames('byline-field-relation-many', relation_field_module.many),
|
|
146
|
+
children: items.map((value)=>/*#__PURE__*/ jsx(RelationManyTile, {
|
|
147
|
+
id: value.targetDocumentId,
|
|
148
|
+
onRemove: ()=>handleRemove(value.targetDocumentId),
|
|
149
|
+
removeAriaLabel: t('fields.relation.removeAriaLabel', {
|
|
150
|
+
label: targetLabel
|
|
151
|
+
}),
|
|
152
|
+
children: /*#__PURE__*/ jsx(RelationSummary, {
|
|
153
|
+
targetDefinition: targetDef,
|
|
154
|
+
targetAdminConfig: targetAdminConfig,
|
|
155
|
+
displayField: field.displayField,
|
|
156
|
+
value: value,
|
|
157
|
+
cachedRecord: pickedRecords[value.targetDocumentId] ?? null
|
|
158
|
+
})
|
|
159
|
+
}, value.targetDocumentId))
|
|
160
|
+
}),
|
|
161
|
+
/*#__PURE__*/ jsx("div", {
|
|
162
|
+
className: classnames('byline-field-relation-many-add', relation_field_module["many-add"]),
|
|
163
|
+
children: /*#__PURE__*/ jsxs(Button, {
|
|
164
|
+
id: htmlId,
|
|
165
|
+
size: "xs",
|
|
166
|
+
variant: "outlined",
|
|
167
|
+
intent: "noeffect",
|
|
168
|
+
type: "button",
|
|
169
|
+
onClick: ()=>setPickerOpen(true),
|
|
170
|
+
children: [
|
|
171
|
+
/*#__PURE__*/ jsx(PlusIcon, {
|
|
172
|
+
width: "14px",
|
|
173
|
+
height: "14px"
|
|
174
|
+
}),
|
|
175
|
+
t('fields.relation.addButton', {
|
|
176
|
+
label: targetLabel
|
|
177
|
+
})
|
|
178
|
+
]
|
|
179
|
+
})
|
|
180
|
+
})
|
|
181
|
+
]
|
|
182
|
+
}),
|
|
183
|
+
null != field.helpText && /*#__PURE__*/ jsx(HelpText, {
|
|
184
|
+
text: field.helpText
|
|
161
185
|
}),
|
|
162
186
|
fieldError && /*#__PURE__*/ jsx(ErrorText, {
|
|
163
187
|
id: `${field.name}-error`,
|
|
164
188
|
text: fieldError
|
|
165
189
|
}),
|
|
166
|
-
/*#__PURE__*/ jsx("div", {
|
|
167
|
-
className: classnames('byline-field-relation-many-add', relation_field_module["many-add"]),
|
|
168
|
-
children: /*#__PURE__*/ jsxs(Button, {
|
|
169
|
-
id: htmlId,
|
|
170
|
-
size: "xs",
|
|
171
|
-
variant: "outlined",
|
|
172
|
-
intent: "noeffect",
|
|
173
|
-
type: "button",
|
|
174
|
-
onClick: ()=>setPickerOpen(true),
|
|
175
|
-
children: [
|
|
176
|
-
/*#__PURE__*/ jsx(PlusIcon, {
|
|
177
|
-
width: "14px",
|
|
178
|
-
height: "14px"
|
|
179
|
-
}),
|
|
180
|
-
t('fields.relation.addButton', {
|
|
181
|
-
label: targetLabel
|
|
182
|
-
})
|
|
183
|
-
]
|
|
184
|
-
})
|
|
185
|
-
}),
|
|
186
190
|
/*#__PURE__*/ jsx(RelationPicker, {
|
|
187
191
|
multiple: true,
|
|
188
192
|
targetCollectionPath: field.targetCollection,
|
package/package.json
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
"name": "@byline/admin",
|
|
3
3
|
"private": false,
|
|
4
4
|
"license": "MPL-2.0",
|
|
5
|
-
"version": "3.20.
|
|
5
|
+
"version": "3.20.2",
|
|
6
6
|
"engines": {
|
|
7
7
|
"node": ">=20.9.0"
|
|
8
8
|
},
|
|
@@ -155,10 +155,10 @@
|
|
|
155
155
|
"react-diff-viewer-continued": "^4.2.2",
|
|
156
156
|
"uuid": "^14.0.1",
|
|
157
157
|
"zod": "^4.4.3",
|
|
158
|
-
"@byline/auth": "3.20.
|
|
159
|
-
"@byline/
|
|
160
|
-
"@byline/
|
|
161
|
-
"@byline/core": "3.20.
|
|
158
|
+
"@byline/auth": "3.20.2",
|
|
159
|
+
"@byline/ui": "3.20.2",
|
|
160
|
+
"@byline/i18n": "3.20.2",
|
|
161
|
+
"@byline/core": "3.20.2"
|
|
162
162
|
},
|
|
163
163
|
"peerDependencies": {
|
|
164
164
|
"react": "^19.0.0",
|
|
@@ -4,12 +4,16 @@
|
|
|
4
4
|
* Override handles:
|
|
5
5
|
* .byline-field-relation — outer wrapper
|
|
6
6
|
* .byline-field-relation-header — label row
|
|
7
|
-
* .byline-field-relation-
|
|
7
|
+
* .byline-field-relation-frame — rounded border around the interactive body
|
|
8
8
|
* .byline-field-relation-error-tile — wrapper shown when target collection is unknown
|
|
9
9
|
* .byline-field-relation-error-text — secondary error message below the title
|
|
10
10
|
* .byline-field-relation-tile — bordered selected-value + actions container
|
|
11
11
|
* .byline-field-relation-actions — top-right icon-button group (edit + remove)
|
|
12
12
|
* .byline-field-relation-mono — monospace `<code>` for field/collection names
|
|
13
|
+
*
|
|
14
|
+
* Help text renders BELOW the frame via the ui-kit `HelpText` component
|
|
15
|
+
* (mirroring composite inputs like the partial-date widget), so there is no
|
|
16
|
+
* relation-specific help class.
|
|
13
17
|
*/
|
|
14
18
|
|
|
15
19
|
.header,
|
|
@@ -20,13 +24,6 @@
|
|
|
20
24
|
margin-bottom: 0.25rem;
|
|
21
25
|
}
|
|
22
26
|
|
|
23
|
-
.help,
|
|
24
|
-
:global(.byline-field-relation-help) {
|
|
25
|
-
margin-bottom: 0.25rem;
|
|
26
|
-
color: var(--gray-400);
|
|
27
|
-
font-size: var(--font-size-xs);
|
|
28
|
-
}
|
|
29
|
-
|
|
30
27
|
.error-tile,
|
|
31
28
|
:global(.byline-field-relation-error-tile) {
|
|
32
29
|
display: flex;
|
|
@@ -162,3 +159,36 @@
|
|
|
162
159
|
display: flex;
|
|
163
160
|
margin-top: 0.25rem;
|
|
164
161
|
}
|
|
162
|
+
|
|
163
|
+
/* ---------------------------------------------------------------------------
|
|
164
|
+
* Frame — rounded border around the field's interactive body (tiles and/or
|
|
165
|
+
* buttons), rendered BELOW the label / help text, mirroring the framing
|
|
166
|
+
* convention of composite inputs like the partial-date widget. Bordered with
|
|
167
|
+
* `--field-border`, the same theme-aware token the Input / Select widgets
|
|
168
|
+
* use, so it matches them and flips automatically between light and dark.
|
|
169
|
+
*
|
|
170
|
+
* Override handle:
|
|
171
|
+
* .byline-field-relation-frame — the framing box
|
|
172
|
+
* --------------------------------------------------------------------------- */
|
|
173
|
+
|
|
174
|
+
.frame,
|
|
175
|
+
:global(.byline-field-relation-frame) {
|
|
176
|
+
margin-top: 0.25rem;
|
|
177
|
+
border: var(--border-width-thin) var(--border-style-solid) var(--field-border);
|
|
178
|
+
border-radius: var(--border-radius-md, 6px);
|
|
179
|
+
padding: 0.5rem;
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
/* The frame now supplies the label → content separation, so zero the legacy
|
|
183
|
+
top margins on children rendered inside it. */
|
|
184
|
+
.frame > .tile,
|
|
185
|
+
.frame > .many,
|
|
186
|
+
:global(.byline-field-relation-frame > .byline-field-relation-tile),
|
|
187
|
+
:global(.byline-field-relation-frame > .byline-field-relation-many) {
|
|
188
|
+
margin-top: 0;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
.frame > .many-empty,
|
|
192
|
+
:global(.byline-field-relation-frame > .byline-field-relation-many-empty) {
|
|
193
|
+
margin-top: 0;
|
|
194
|
+
}
|
|
@@ -16,7 +16,15 @@ import type {
|
|
|
16
16
|
} from '@byline/core'
|
|
17
17
|
import { getCollectionAdminConfig, getCollectionDefinition } from '@byline/core'
|
|
18
18
|
import { useTranslation } from '@byline/i18n/react'
|
|
19
|
-
import {
|
|
19
|
+
import {
|
|
20
|
+
Button,
|
|
21
|
+
CloseIcon,
|
|
22
|
+
EditIcon,
|
|
23
|
+
ErrorText,
|
|
24
|
+
HelpText,
|
|
25
|
+
IconButton,
|
|
26
|
+
Label,
|
|
27
|
+
} from '@byline/ui/react'
|
|
20
28
|
import cx from 'classnames'
|
|
21
29
|
|
|
22
30
|
import { useFieldError, useFieldValue } from '../../forms/form-context'
|
|
@@ -130,10 +138,6 @@ export const RelationField = ({
|
|
|
130
138
|
required={!field.optional}
|
|
131
139
|
/>
|
|
132
140
|
</div>
|
|
133
|
-
{field.helpText && (
|
|
134
|
-
<div className={cx('byline-field-relation-help', styles.help)}>{field.helpText}</div>
|
|
135
|
-
)}
|
|
136
|
-
|
|
137
141
|
{isUnknown ? (
|
|
138
142
|
<div className={cx('byline-field-relation-error-tile', styles['error-tile'])}>
|
|
139
143
|
<span>
|
|
@@ -146,54 +150,62 @@ export const RelationField = ({
|
|
|
146
150
|
{t('fields.relation.unknownHint')}
|
|
147
151
|
</span>
|
|
148
152
|
</div>
|
|
149
|
-
) :
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
153
|
+
) : (
|
|
154
|
+
// Rounded frame below the label wrapping the interactive body
|
|
155
|
+
// (selected tile or select button) — see `.frame` in the CSS module.
|
|
156
|
+
<div className={cx('byline-field-relation-frame', styles.frame)}>
|
|
157
|
+
{incomingValue ? (
|
|
158
|
+
<div className={cx('byline-field-relation-tile', styles.tile)}>
|
|
159
|
+
<RelationSummary
|
|
160
|
+
targetDefinition={targetDef}
|
|
161
|
+
targetAdminConfig={targetAdminConfig}
|
|
162
|
+
displayField={field.displayField}
|
|
163
|
+
value={incomingValue}
|
|
164
|
+
cachedRecord={cachedRecord}
|
|
165
|
+
/>
|
|
166
|
+
<div className={cx('byline-field-relation-actions', styles.actions)}>
|
|
167
|
+
<IconButton
|
|
168
|
+
id={htmlId}
|
|
169
|
+
type="button"
|
|
170
|
+
intent="noeffect"
|
|
171
|
+
size="xs"
|
|
172
|
+
aria-label={t('fields.relation.changeAriaLabel', {
|
|
173
|
+
label: targetDef.labels.singular,
|
|
174
|
+
})}
|
|
175
|
+
onClick={() => setPickerOpen(true)}
|
|
176
|
+
>
|
|
177
|
+
<EditIcon width="15px" height="15px" />
|
|
178
|
+
</IconButton>
|
|
179
|
+
<IconButton
|
|
180
|
+
type="button"
|
|
181
|
+
intent="noeffect"
|
|
182
|
+
size="xs"
|
|
183
|
+
aria-label={t('fields.relation.removeAriaLabel', {
|
|
184
|
+
label: targetDef.labels.singular,
|
|
185
|
+
})}
|
|
186
|
+
onClick={handleRemove}
|
|
187
|
+
>
|
|
188
|
+
<CloseIcon width="15px" height="15px" />
|
|
189
|
+
</IconButton>
|
|
190
|
+
</div>
|
|
191
|
+
</div>
|
|
192
|
+
) : (
|
|
193
|
+
<Button
|
|
160
194
|
id={htmlId}
|
|
161
|
-
type="button"
|
|
162
|
-
intent="noeffect"
|
|
163
195
|
size="xs"
|
|
164
|
-
|
|
165
|
-
label: targetDef.labels.singular,
|
|
166
|
-
})}
|
|
167
|
-
onClick={() => setPickerOpen(true)}
|
|
168
|
-
>
|
|
169
|
-
<EditIcon width="15px" height="15px" />
|
|
170
|
-
</IconButton>
|
|
171
|
-
<IconButton
|
|
172
|
-
type="button"
|
|
196
|
+
variant="outlined"
|
|
173
197
|
intent="noeffect"
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
label: targetDef.labels.singular,
|
|
177
|
-
})}
|
|
178
|
-
onClick={handleRemove}
|
|
198
|
+
type="button"
|
|
199
|
+
onClick={() => setPickerOpen(true)}
|
|
179
200
|
>
|
|
180
|
-
|
|
181
|
-
</
|
|
182
|
-
|
|
201
|
+
{t('fields.relation.selectButton', { label: targetDef.labels.singular })}
|
|
202
|
+
</Button>
|
|
203
|
+
)}
|
|
183
204
|
</div>
|
|
184
|
-
) : (
|
|
185
|
-
<Button
|
|
186
|
-
id={htmlId}
|
|
187
|
-
size="xs"
|
|
188
|
-
variant="outlined"
|
|
189
|
-
intent="noeffect"
|
|
190
|
-
type="button"
|
|
191
|
-
onClick={() => setPickerOpen(true)}
|
|
192
|
-
>
|
|
193
|
-
{t('fields.relation.selectButton', { label: targetDef.labels.singular })}
|
|
194
|
-
</Button>
|
|
195
205
|
)}
|
|
196
206
|
|
|
207
|
+
{field.helpText != null && <HelpText text={field.helpText} />}
|
|
208
|
+
|
|
197
209
|
{fieldError && <ErrorText id={`${field.name}-error`} text={fieldError} />}
|
|
198
210
|
|
|
199
211
|
{!isUnknown && (
|
|
@@ -22,6 +22,7 @@ import {
|
|
|
22
22
|
DraggableSortable,
|
|
23
23
|
ErrorText,
|
|
24
24
|
GripperVerticalIcon,
|
|
25
|
+
HelpText,
|
|
25
26
|
IconButton,
|
|
26
27
|
Label,
|
|
27
28
|
moveItem,
|
|
@@ -201,10 +202,6 @@ export const RelationManyField = ({ field, defaultValue, id, path }: RelationMan
|
|
|
201
202
|
required={!field.optional}
|
|
202
203
|
/>
|
|
203
204
|
</div>
|
|
204
|
-
{field.helpText && (
|
|
205
|
-
<div className={cx('byline-field-relation-help', styles.help)}>{field.helpText}</div>
|
|
206
|
-
)}
|
|
207
|
-
|
|
208
205
|
{isUnknown ? (
|
|
209
206
|
<div className={cx('byline-field-relation-error-tile', styles['error-tile'])}>
|
|
210
207
|
<span>
|
|
@@ -219,51 +216,58 @@ export const RelationManyField = ({ field, defaultValue, id, path }: RelationMan
|
|
|
219
216
|
</div>
|
|
220
217
|
) : (
|
|
221
218
|
<>
|
|
222
|
-
{
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
219
|
+
{/* Rounded frame below the label wrapping the interactive
|
|
220
|
+
body (tile list and add button) — see `.frame` in the CSS
|
|
221
|
+
module. */}
|
|
222
|
+
<div className={cx('byline-field-relation-frame', styles.frame)}>
|
|
223
|
+
{items.length === 0 ? (
|
|
224
|
+
<p className={cx('byline-field-relation-many-empty', styles['many-empty'])}>
|
|
225
|
+
{t('fields.relation.manyEmpty', { label: targetDef.labels.plural })}
|
|
226
|
+
</p>
|
|
227
|
+
) : (
|
|
228
|
+
<DraggableSortable
|
|
229
|
+
ids={items.map((v) => v.targetDocumentId)}
|
|
230
|
+
onDragEnd={handleDragEnd}
|
|
231
|
+
className={cx('byline-field-relation-many', styles.many)}
|
|
232
|
+
>
|
|
233
|
+
{items.map((value) => (
|
|
234
|
+
<RelationManyTile
|
|
235
|
+
key={value.targetDocumentId}
|
|
236
|
+
id={value.targetDocumentId}
|
|
237
|
+
onRemove={() => handleRemove(value.targetDocumentId)}
|
|
238
|
+
removeAriaLabel={t('fields.relation.removeAriaLabel', { label: targetLabel })}
|
|
239
|
+
>
|
|
240
|
+
<RelationSummary
|
|
241
|
+
targetDefinition={targetDef}
|
|
242
|
+
targetAdminConfig={targetAdminConfig}
|
|
243
|
+
displayField={field.displayField}
|
|
244
|
+
value={value}
|
|
245
|
+
cachedRecord={pickedRecords[value.targetDocumentId] ?? null}
|
|
246
|
+
/>
|
|
247
|
+
</RelationManyTile>
|
|
248
|
+
))}
|
|
249
|
+
</DraggableSortable>
|
|
250
|
+
)}
|
|
252
251
|
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
252
|
+
<div className={cx('byline-field-relation-many-add', styles['many-add'])}>
|
|
253
|
+
<Button
|
|
254
|
+
id={htmlId}
|
|
255
|
+
size="xs"
|
|
256
|
+
variant="outlined"
|
|
257
|
+
intent="noeffect"
|
|
258
|
+
type="button"
|
|
259
|
+
onClick={() => setPickerOpen(true)}
|
|
260
|
+
>
|
|
261
|
+
<PlusIcon width="14px" height="14px" />
|
|
262
|
+
{t('fields.relation.addButton', { label: targetLabel })}
|
|
263
|
+
</Button>
|
|
264
|
+
</div>
|
|
265
265
|
</div>
|
|
266
266
|
|
|
267
|
+
{field.helpText != null && <HelpText text={field.helpText} />}
|
|
268
|
+
|
|
269
|
+
{fieldError && <ErrorText id={`${field.name}-error`} text={fieldError} />}
|
|
270
|
+
|
|
267
271
|
<RelationPicker
|
|
268
272
|
multiple
|
|
269
273
|
targetCollectionPath={field.targetCollection}
|