DynamicTable, sort does not work :(

Hi,

Using my own data, I could not make work the sort feature on the new DynamicTable. Weird behaviour.

So I checked it starting from the Hello World app, with the example provided in https://developer.atlassian.com/platform/forge/ui-kit/components/dynamic-table/
And it does not work. Or not always.

Using the whole set of data of the example, search by term has just 1 anomaly (1697 is placed by mistake between 1789 and 1801.

With a smaller set of data, it’s easier to see the problem: using the code below, sorted by Party, I get Democrat, aDemocrat and then Democrat.

This is the code I use:

import React from 'react';
import ForgeReconciler, { Text } from '@forge/react';

import { DynamicTable, Link } from "@forge/react";

const App = () => {
  const presidents = [
    {
      id: 7,
      name: "Andrew Jackson",
      party: "Democrat",
      term: "1829-1837",
    },
    {
      id: 8,
      name: "Martin van Buren",
      party: "aDemocrat",
      term: "1837-1841",
    },
    {
      id: 11,
      name: "James K. Polk",
      party: "Democrat",
      term: "1845-1849",
    },
  ];

  const createKey = (input) => {
    return input ? input.replace(/^(the|a|an)/, "").replace(/\s/g, "") : input;
  }
  // applied as rows in the form
  const rows = presidents.map((president, index) => ({
    key: `row-${index}-${president.name}`,
    cells: [
      {
        key: createKey(president.name),
        content: <Link href="">{president.name}</Link>,
      },
      {
        key: createKey(president.party),
        content: president.party,
      },
      {
        key: president.id,
        content: president.term,
      },
    ],
  }));

  const head = {
    cells: [
      {
        key: "name",
        content: "Name",
        isSortable: true,
      },
      {
        key: "party",
        content: "Party",
        shouldTruncate: true,
        isSortable: true,
      },
      {
        key: "term",
        content: "Term",
        shouldTruncate: true,
        isSortable: true,
      },
    ],
  };

  return (
    <>
      <Text>Hello world!</Text>
      <DynamicTable
        caption="List of US Presidents"
        head={head}
        rows={rows}
      />
    </>
  );
};

ForgeReconciler.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>
);

Anyone else who could confirm that it does not work as is? @YY1 , I think you also had this problem. Is it a known bug at Atlassian?

In the meantime, I think I will disallow the sorting feature using a flag and an environment variable, so it will be easier to enable it when this problem is solved.

2 Likes

createKey looks suspicious here. AFAIK DynamicTable sorts over cell’s key field. And in your case, the “party” cells will be:

createKey("Democrat") -> "Democrat"
createKey("aDemocrat") -> also "Democrat" (review the regexp inside createKey)
createKey("Democrat") -> "Democrat"

…so it makes some sense you receive the “Democrat” “aDemocrat” “Democrat” sorting order. Maybe remove that createKey( part from key computation?

3 Likes

Hi @BertrandDrouhard1
I’ve got the same sorting issue: Dynamic table order incorrectly for decimal points columns
And haven’t been resolved yet.

1 Like

I’ve also seen the problem with dynamic table sorting - some columns works but not others. I couldn’t really spot the patterns of what works and what not. In my case, each row is associated with a content ID and the key of the cell is ${column_name}-${content.id}, so I think I can exclude the key of the cells as a possible cause.

I spoke too soon and it turns out @stefan-ok’s answer above is spot-on.

I didn’t realize the role of ‘key’ for each cell plays in sorting. According to the documentation of Dynamic table :

Sorting a dynamic table is done based on the key set on each cell.

This means I had to include the actual differentiating value of the cell content in the keys in order for sorting to work properly.

3 Likes

Thanks to all of you! That was a real team work :heart_eyes:

I think I get it now: as @shushen and @stefan-ok said, the table is sorted over the key field, the value is not taken into account. The documentation is not so clear, but once you know it, it is clear :smiley: .

I was sent on a wrong path both because of the mistake on the term (1697 instead of 1797) that Atlassian did on their example, and also because of their createKey that removes the ‘a’ at the beginning of the value (instead of removing 'a ').

What is really interesting with that feature of having a displayed value and a sort key is that you can decide to sort on any criteria. That’s great :slight_smile: .

So to make the example work, the easiest way is to remove the (stupid :smiley: ) createKey and just use the value. I add the name of the president at the end as a second sort level. And the id to make sure not to have 2 identical values.

  const rows = presidents.map((president, index) => ({
    key: `row-${index}-${president.name}`,
    cells: [
      {
        key: `${president.name}-${president.id}`,
        content: <Link href="">{president.name}</Link>,
      },
      {
        key: `${president.party}-${president.name}-${president.id}`,
        content: president.party,
      },
      {
        key: `${president.term}-${president.id}`,
        content: president.term,
      },
    ],
  }));

Thanks again for your help.

2 Likes

By the way, if you use defaultSortKey, default value for defaultSortOrder does not work, and the table is sorted DESC by default. Is this THE bug? :rofl: