@goplusvn/core 0.1.8 → 0.1.9
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/package.json
CHANGED
|
@@ -23,6 +23,40 @@ import {
|
|
|
23
23
|
} from "../../ui/primitives/client";
|
|
24
24
|
import { DataTable } from "../../ui/data-display/data-table/data-table";
|
|
25
25
|
|
|
26
|
+
/**
|
|
27
|
+
* Resolve a relation FK column's label from the relation object the server already
|
|
28
|
+
* included on the row (e.g. `branchId` → `row.branch.name`).
|
|
29
|
+
*
|
|
30
|
+
* Relation columns are configured as a `select` field whose `dataSource` points at
|
|
31
|
+
* `/api/<relation>`; the client resolves the id → label by fetching that endpoint
|
|
32
|
+
* asynchronously. That secondary fetch is the only label source, so the column shows
|
|
33
|
+
* the raw FK id whenever it hasn't resolved yet (first paint), fails, is slow, or is
|
|
34
|
+
* capped by pagination (the endpoint's default page size). A per-config `renderCell`
|
|
35
|
+
* that reads `row.branch?.name` can't help — render functions are stripped when the
|
|
36
|
+
* config is serialized for Client Components.
|
|
37
|
+
*
|
|
38
|
+
* When the entity `include`s the relation, the row already carries the related record,
|
|
39
|
+
* so we can render its label directly with no secondary fetch and no race. The relation
|
|
40
|
+
* key is inferred from the field name (`branchId` → `branch`) and the label field from
|
|
41
|
+
* the `dataSource` (default `name`).
|
|
42
|
+
*/
|
|
43
|
+
function resolveIncludedRelationLabel(
|
|
44
|
+
field: { name?: string; dataSource?: { labelField?: string } },
|
|
45
|
+
row: Record<string, unknown> | undefined,
|
|
46
|
+
): string | undefined {
|
|
47
|
+
const name = field?.name;
|
|
48
|
+
if (!field?.dataSource || !row || !name || !name.endsWith("Id")) {
|
|
49
|
+
return undefined;
|
|
50
|
+
}
|
|
51
|
+
const relationKey = name.slice(0, -2);
|
|
52
|
+
if (!relationKey) return undefined;
|
|
53
|
+
const rel = row[relationKey];
|
|
54
|
+
if (!rel || typeof rel !== "object" || Array.isArray(rel)) return undefined;
|
|
55
|
+
const labelField = field.dataSource.labelField || "name";
|
|
56
|
+
const label = (rel as Record<string, unknown>)[labelField];
|
|
57
|
+
return label != null && label !== "" ? String(label) : undefined;
|
|
58
|
+
}
|
|
59
|
+
|
|
26
60
|
interface CrudTableProps<TData = Record<string, unknown>> {
|
|
27
61
|
data: CrudResponse<TData>;
|
|
28
62
|
loading?: boolean;
|
|
@@ -196,7 +230,8 @@ export function CrudTable<TData extends Record<string, unknown>>({
|
|
|
196
230
|
);
|
|
197
231
|
content = option
|
|
198
232
|
? option.label
|
|
199
|
-
:
|
|
233
|
+
: (resolveIncludedRelationLabel(field, row.original) ??
|
|
234
|
+
formatFieldValue(value, field));
|
|
200
235
|
}
|
|
201
236
|
} else {
|
|
202
237
|
content = formatFieldValue(value, field);
|