|
| 1 | +import type { ReactNode } from "react"; |
1 | 2 | import { get } from "react-hook-form"; |
2 | 3 | import type { Control } from "react-hook-form"; |
3 | 4 | import { toast } from "sonner"; |
@@ -36,11 +37,13 @@ import { sanitizeId, toTitleCase } from "@/utils"; |
36 | 37 | import { useArfRelation } from "../hooks/use-arf-relation"; |
37 | 38 | import { useArfRelationMutation } from "../hooks/use-arf-relation-mutation"; |
38 | 39 | import { useArfSheet } from "../hooks/use-arf-sheet"; |
| 40 | +import { getItemPivotOrder } from "../utils/get-item-pivot-order"; |
39 | 41 | import { getMutationConfig } from "../utils/get-mutation-config"; |
40 | 42 | import { isExistingItem } from "../utils/is-existing-item"; |
41 | 43 | import { ArfInput } from "./arf-input"; |
42 | 44 | import { ArfPivotData } from "./arf-pivot-data"; |
43 | 45 | import { OrderableMultiSelect } from "./orderable-multi-select"; |
| 46 | +import { OrderablePivotMultiSelect } from "./orderable-pivot-multi-select"; |
44 | 47 |
|
45 | 48 | export function ArfRelationInput< |
46 | 49 | T extends Resource, |
@@ -145,11 +148,23 @@ export function ArfRelationInput< |
145 | 148 | const isRelationOrderable = |
146 | 149 | isOrderableResource(resourceRelation) && |
147 | 150 | relationDefinition.type !== RelationType.ManyToMany; |
| 151 | + const isPivotOrderable = |
| 152 | + relationDefinition.type === RelationType.ManyToMany && |
| 153 | + relationDefinition.orderable === true; |
148 | 154 | const sortedQueriedRelations = isRelationOrderable |
149 | 155 | ? [...queriedRelations].toSorted((a, b) => |
150 | 156 | "order" in a && "order" in b ? a.order - b.order : 1, |
151 | 157 | ) |
152 | | - : queriedRelations; |
| 158 | + : isPivotOrderable |
| 159 | + ? [...queriedRelations].toSorted((a, b) => { |
| 160 | + const orderA = getItemPivotOrder(a); |
| 161 | + const orderB = getItemPivotOrder(b); |
| 162 | + if (orderA !== undefined && orderB !== undefined) { |
| 163 | + return orderA - orderB; |
| 164 | + } |
| 165 | + return 1; |
| 166 | + }) |
| 167 | + : queriedRelations; |
153 | 168 | const selectedValues = sortedQueriedRelations.flatMap((item) => { |
154 | 169 | const value = get(item, primaryKeyField, null) as ResourcePk | null; |
155 | 170 | return value == null ? [] : String(value); |
@@ -264,16 +279,29 @@ export function ArfRelationInput< |
264 | 279 | defaultValue: [...new Set(selectedValues)], |
265 | 280 | } satisfies React.ComponentProps<typeof MultiSelect>; |
266 | 281 |
|
267 | | - const multiselect = isRelationOrderable ? ( |
268 | | - <OrderableMultiSelect |
269 | | - // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion -- type guard doesn't narrow generics |
270 | | - resourceRelation={resourceRelation as OrderableResource} |
271 | | - items={sortedQueriedRelations as ResourceDataType<OrderableResource>[]} |
272 | | - multiSelectProps={multiSelectProps} |
273 | | - /> |
274 | | - ) : ( |
275 | | - <MultiSelect {...multiSelectProps} /> |
276 | | - ); |
| 282 | + let multiselect: ReactNode; |
| 283 | + if (isRelationOrderable) { |
| 284 | + multiselect = ( |
| 285 | + <OrderableMultiSelect |
| 286 | + resourceRelation={resourceRelation as OrderableResource} |
| 287 | + items={sortedQueriedRelations as ResourceDataType<OrderableResource>[]} |
| 288 | + multiSelectProps={multiSelectProps} |
| 289 | + /> |
| 290 | + ); |
| 291 | + } else if (isPivotOrderable && relationDefinition.pivotData != null) { |
| 292 | + multiselect = ( |
| 293 | + <OrderablePivotMultiSelect |
| 294 | + resource={resource} |
| 295 | + resourceRelation={resourceRelation} |
| 296 | + endpoint={endpoint} |
| 297 | + pivotData={relationDefinition.pivotData} |
| 298 | + items={sortedQueriedRelations} |
| 299 | + multiSelectProps={multiSelectProps} |
| 300 | + /> |
| 301 | + ); |
| 302 | + } else { |
| 303 | + multiselect = <MultiSelect {...multiSelectProps} />; |
| 304 | + } |
277 | 305 | return relationDefinition.type === RelationType.ManyToMany ? ( |
278 | 306 | // TODO: allow m:n relation inputs to be immutable |
279 | 307 | <Label className="flex-col items-start"> |
|
0 commit comments