From 2676d8d045533e142b21d03f34944514e6c7b606 Mon Sep 17 00:00:00 2001 From: Khiman Louer <30343764+alkanna@users.noreply.github.com> Date: Sat, 24 Apr 2021 18:20:06 +0200 Subject: [PATCH] Add support for nested object fields in DataTable (#602) * feature: Add support for nested object fields in Data Table feature: Add support for nested object fields in Data Table * fix can't open dropdown with keyboard (#610) * fix(Dropdown): update selectedId when selectedIndex changes. (#611) * chore(deps-dev): patch carbon-components@10.32.1 (#613) * v0.32.2 * feature: Add support for nested object fields in Data Table feature: Add support for nested object fields in Data Table * chore: Added example for nested object values into the documentation Co-authored-by: Lyu, Wei-Da <36730922+jasonlyu123@users.noreply.github.com> Co-authored-by: David Espinosa Co-authored-by: Eric Liu --- docs/src/pages/components/DataTable.svx | 79 +++++++++++++++++++++++++ src/DataTable/DataTable.svelte | 18 +++++- 2 files changed, 94 insertions(+), 3 deletions(-) diff --git a/docs/src/pages/components/DataTable.svx b/docs/src/pages/components/DataTable.svx index 7b173627..10272cbc 100644 --- a/docs/src/pages/components/DataTable.svx +++ b/docs/src/pages/components/DataTable.svx @@ -676,6 +676,85 @@ In the example below, the "Protocol" column is not sortable. ]}" /> +### Sortable with nested object values + + cost + " €" }, + { + key: "expireDate", + value: "Expire date", + display: (date) => new Date(date).toLocaleString(), + sort: (a, b) => new Date(a) - new Date(b), + }, + ]}" + rows="{[ + { + id: "a", + name: "Load Balancer 3", + network: { + protocol: "HTTP", + port: 3000, + }, + cost: 100, + expireDate: "2020-10-21", + }, + { + id: "b", + name: "Load Balancer 1", + network: { + protocol: "HTTP", + port: 443, + }, + cost: 200, + expireDate: "2020-09-10", + }, + { + id: "c", + name: "Load Balancer 2", + network: { + protocol: "HTTP", + port: 80, + }, + cost: 150, + expireDate: "2020-11-24", + }, + { + id: "d", + name: "Load Balancer 6", + network: { + protocol: "HTTP", + port: 3000, + }, + cost: 250, + expireDate: "2020-12-01", + }, + { + id: "e", + name: "Load Balancer 4", + network: { + protocol: "HTTP", + port: 443, + }, + cost: 550, + expireDate: "2021-03-21", + }, + { + id: "f", + name: "Load Balancer 5", + network: { + protocol: "HTTP", + port: 80, + }, + cost: 400, + expireDate: "2020-11-14", + }, + ]}" +/> + ### Empty column with overflow menu Some use cases require an empty column in the table body without a corresponding table header. diff --git a/src/DataTable/DataTable.svelte b/src/DataTable/DataTable.svelte index 540ce72a..06ced220 100644 --- a/src/DataTable/DataTable.svelte +++ b/src/DataTable/DataTable.svelte @@ -124,6 +124,14 @@ .map(({ key }, i) => ({ key, id: $headerItems[i] })) .reduce((a, c) => ({ ...a, [c.key]: c.id }), {}) ); + const resolvePath = (object, path, defaultValue) => + path + .split(/[\.\[\]\'\"]/) + .filter((p) => p) + .reduce( + (o, p) => (o && typeof o === "object" && o[p] ? o[p] : defaultValue), + object + ); setContext("DataTable", { sortHeader, @@ -159,7 +167,7 @@ $: headerKeys = headers.map(({ key }) => key); $: rows = rows.map((row) => ({ ...row, - cells: headerKeys.map((key) => ({ key, value: row[key] })), + cells: headerKeys.map((key) => ({ key, value: resolvePath(row, key, "") })), })); $: sortedRows = rows; $: ascending = $sortHeader.sortDirection === "ascending"; @@ -170,8 +178,12 @@ sortedRows = rows; } else { sortedRows = [...rows].sort((a, b) => { - const itemA = ascending ? a[sortKey] : b[sortKey]; - const itemB = ascending ? b[sortKey] : a[sortKey]; + const itemA = ascending + ? resolvePath(a, sortKey, "") + : resolvePath(b, sortKey, ""); + const itemB = ascending + ? resolvePath(b, sortKey, "") + : resolvePath(a, sortKey, ""); if ($sortHeader.sort) return $sortHeader.sort(itemA, itemB);