Skip to content

Commit

Permalink
Adding sortable tables (#6338)
Browse files Browse the repository at this point in the history
## What are you changing in this pull request and why?

Adding sortable tables by wrapping markdown in react.

Static tables function the same. To make a sortable table would wrap
markdown table with :

```
<SortableTable>

{`

Markdown table here

`}

</SortableTable>

```

I couldn't successfully format this so that the {` `} are not required. 

I also couldn't figure out how to enforce this globally (which was a
request). It has to be implemented purposefully.

In the UI this will put light grey arrows to the right of the headers.
When users click the arrows it will sort the table according to the
column and the directional arrow will be darker. There is no "reset,"
but if the user reloads the page, the table will be in the original
order if it wasn't alphabetical by the first column already (which it
really should be unless it's a connections config table).

## Checklist
- [ ] I have reviewed the [Content style
guide](https://github.com/dbt-labs/docs.getdbt.com/blob/current/contributing/content-style-guide.md)
so my content adheres to these guidelines.
- [ ] The topic I'm writing about is for specific dbt version(s) and I
have versioned it according to the [version a whole
page](https://github.com/dbt-labs/docs.getdbt.com/blob/current/contributing/single-sourcing-content.md#adding-a-new-version)
and/or [version a block of
content](https://github.com/dbt-labs/docs.getdbt.com/blob/current/contributing/single-sourcing-content.md#versioning-blocks-of-content)
guidelines.
- [ ] I have added checklist item(s) to this list for anything anything
that needs to happen before this PR is merged, such as "needs technical
review" or "change base branch."
- [ ] The content in this PR requires a dbt release note, so I added one
to the [release notes
page](https://docs.getdbt.com/docs/dbt-versions/dbt-cloud-release-notes).
<!--
PRE-RELEASE VERSION OF dbt (if so, uncomment):
- [ ] Add a note to the prerelease version [Migration
Guide](https://github.com/dbt-labs/docs.getdbt.com/tree/current/website/docs/docs/dbt-versions/core-upgrade)
-->
<!-- 
ADDING OR REMOVING PAGES (if so, uncomment):
- [ ] Add/remove page in `website/sidebars.js`
- [ ] Provide a unique filename for new pages
- [ ] Add an entry for deleted pages in `website/vercel.json`
- [ ] Run link testing locally with `npm run build` to update the links
that point to deleted pages
-->

---------

Co-authored-by: Mirna Wong <[email protected]>
  • Loading branch information
matthewshaver and mirnawong1 authored Nov 13, 2024
1 parent 6810e18 commit 53df291
Show file tree
Hide file tree
Showing 4 changed files with 129 additions and 0 deletions.
12 changes: 12 additions & 0 deletions website/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions website/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
"gray-matter": "^4.0.3",
"hast-util-is-element": "^1.1.0",
"js-yaml": "^4.1.0",
"markdown-to-jsx": "^7.5.0",
"mobx": "^6.3.9",
"node-polyfill-webpack-plugin": "^1.1.4",
"papaparse": "^5.3.2",
Expand Down
114 changes: 114 additions & 0 deletions website/src/components/sortableTable/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
import React, { useState, useMemo } from 'react';
import Markdown from 'markdown-to-jsx';

const stripMarkdown = (text) => {
let strippedText = text.replace(/\[([^\]]+)\]\([^)]+\)/g, '$1');
strippedText = strippedText.replace(/[_*`~]/g, '');
return strippedText;
};

const parseMarkdownTable = (markdown) => {
const rows = markdown.trim().split('\n');
const headers = rows[0].split('|').map((header) => header.trim()).filter(Boolean);

const alignmentsRow = rows[1].split('|').map((align) => align.trim()).filter(Boolean);
const columnAlignments = alignmentsRow.map((alignment) => {
if (alignment.startsWith(':') && alignment.endsWith(':')) {
return 'center';
} else if (alignment.startsWith(':')) {
return 'left';
} else if (alignment.endsWith(':')) {
return 'right';
} else {
return 'left';
}
});

const data = rows.slice(2).map(row => row.split('|').map(cell => cell.trim()).filter(Boolean));

return { headers, data, columnAlignments };
};

const SortableTable = ({ children }) => {
const { headers, data: initialData, columnAlignments } = useMemo(
() => parseMarkdownTable(children),
[children]
);

const [data, setData] = useState(initialData);
const [sortConfig, setSortConfig] = useState({ key: '', direction: 'asc' });

const sortTable = (keyIndex) => {
const newDirection = (sortConfig.key === keyIndex && sortConfig.direction === 'asc') ? 'desc' : 'asc';
setSortConfig({ key: keyIndex, direction: newDirection });

const sortedData = [...data].sort((a, b) => {
const aVal = stripMarkdown(a[keyIndex]);
const bVal = stripMarkdown(b[keyIndex]);
if (aVal < bVal) return newDirection === 'asc' ? -1 : 1;
if (aVal > bVal) return newDirection === 'asc' ? 1 : -1;
return 0;
});

setData(sortedData);
};

return (
<table>
<thead>
<tr>
{headers.map((header, index) => (
<th
key={index}
onClick={() => sortTable(index)}
style={{
cursor: 'pointer',
position: 'relative',
textAlign: columnAlignments[index],
padding: '10px'
}}
>
<div style={{
display: 'flex',
alignItems: 'center',
justifyContent: columnAlignments[index] === 'center' ? 'center' : columnAlignments[index]
}}>
<span style={{ marginRight: '5px' }}>{header}</span>
<span style={{
opacity: sortConfig.key === index && sortConfig.direction === 'asc' ? 1 : (sortConfig.key === index ? 0.5 : 0.5)
}}>
</span>
<span style={{
marginLeft: '5px',
opacity: sortConfig.key === index && sortConfig.direction === 'desc' ? 1 : (sortConfig.key === index ? 0.5 : 0.5)
}}>
</span>
</div>
</th>
))}
</tr>
</thead>
<tbody>
{data.map((row, rowIndex) => (
<tr key={rowIndex}>
{row.map((cell, cellIndex) => (
<td
key={cellIndex}
style={{
textAlign: columnAlignments[cellIndex],
padding: '8px'
}}
>
<Markdown>{cell || '\u00A0'}</Markdown>
</td>
))}
</tr>
))}
</tbody>
</table>
);
};

export default SortableTable;
2 changes: 2 additions & 0 deletions website/src/theme/MDXComponents/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import Mermaid from '@theme/Mermaid';
/* dbt Customizations:
* Imports the following components below for export
*/
import SortableTable from '@site/src/components/sortableTable';
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem'
import Changelog from '@site/src/components/changelog';
Expand Down Expand Up @@ -95,5 +96,6 @@ const MDXComponents = {
DetailsToggle: DetailsToggle,
Expandable: Expandable,
ConfettiTrigger: ConfettiTrigger,
SortableTable: SortableTable,
};
export default MDXComponents;

0 comments on commit 53df291

Please sign in to comment.