Commit 127074d0 authored by alain's avatar alain 🐙
Browse files

filter and sort improvents

parent 909d977a
......@@ -11,6 +11,12 @@
</head>
<body>
<style>
body {
margin: 0;
font-size: 18px;
}
</style>
<noscript>
You need to enable JavaScript to run this app.
</noscript>
......
......@@ -19,7 +19,7 @@ export default function App() {
}, []);
return (
<div className="App">
<div id="databronnen">
{ items ? <Table items={items} /> : <p>Bezig met laden...</p> }
</div>
);
......
import React from 'react';
export default function FilterButton(props) {
return (
<svg className={`filter-button ${props.classes}`} xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100" onClick={() => props.clickHandler(props.column)}>
<path d="M91.2 5H8.8c-1.2 0-2 1.3-1.2 2.5l30.2 42.4c1.3 1.8 2.1 4.2 2.1 6.5v37c.1 1.2 1.1 2 2.1 1.6l17.2-6.5c.6-.1.9-.8.9-1.3V56.3c0-2.4.8-4.6 2.1-6.5L92.5 7.5c.8-1.2 0-2.5-1.3-2.5z"/>
</svg>
)
}
\ No newline at end of file
import React from 'react';
export default function SortButton(props) {
return (
<svg className={`sort-button ${props.classes}`} xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100" >
<path className="desc" d="M47.7 6L21.2 32.5c-.6.6-1 1.4-1 2.3 0 .9.3 1.7 1 2.3l2 2a3.2 3.2 0 004.6 0L50 16.8 72.3 39c.6.6 1.4 1 2.3 1 .9 0 1.7-.3 2.3-1l2-2c.6-.6 1-1.4 1-2.3 0-.9-.3-1.7-1-2.3L52.3 6c-.6-.6-1.4-1-2.3-1-.9 0-1.7.3-2.3 1z"/>
<path className="asc" d="M52.3 94l26.5-26.5c.6-.6 1-1.4 1-2.3s-.3-1.7-1-2.3l-2-2a3.2 3.2 0 00-4.6 0L50 83.2 27.7 61c-.6-.6-1.4-1-2.3-1-.9 0-1.7.3-2.3 1l-2 2c-.6.6-1 1.4-1 2.3 0 .9.3 1.7 1 2.3L47.7 94c.6.6 1.4 1 2.3 1 .9 0 1.7-.3 2.3-1z"/>
</svg>
)
}
\ No newline at end of file
import React from 'react';
import { useSortableData } from './util/util';
export default function Table(props) {
const [filter, setFilter] = React.useState({ omschrijving: '' });
import SortButton from './SortButton';
import FilterButton from './FilterButton';
// const filter = {
// omschrijving: "kaart"
// }
export default function Table(props) {
const columns = Object.keys(props.items[0])
const filterInitial = {}
columns.forEach(column => { filterInitial[column] = '' })
const activeFilterInitial = {}
columns.forEach(column => { activeFilterInitial[column] = false })
const [filter, setFilter] = React.useState(filterInitial);
const [activeFilter, setActiveFilter] = React.useState(activeFilterInitial);
const { items, requestSort, sortConfig } = useSortableData(props.items, filter);
const getClassNamesFor = (name) => {
const getSortState = (name) => {
if (!sortConfig) {
return;
}
return sortConfig.key === name ? sortConfig.direction : undefined;
return sortConfig.key === name ? sortConfig.direction : '';
};
const handleInputChange = (e) => {
console.log(e.target.value)
setFilter({
omschrijving: e.target.value
})
const handleInputChange = (value, column) => {
const newFilter = { ...filter }
newFilter[column] = value
setFilter(newFilter)
}
const handleFilterButtonClick = (column) => {
if(activeFilter[column]) handleInputChange('', column)
const newActiveFilter = { ...activeFilter }
newActiveFilter[column] = !activeFilter[column]
setActiveFilter(newActiveFilter)
}
return (
<>
<input value={filter.omschrijving} onChange={(e) => { handleInputChange(e) }} />
<table>
<thead>
<tr>
{ columns.map(column => <th key={column}><button type="button" onClick={() => requestSort(column)} className={getClassNamesFor(column)}>{column}</button></th>) }
{ columns.map(column => (
<th key={column} className={column}>
<div>
<span onClick={ () => { requestSort(column) } }>
<SortButton column={column} classes={getSortState(column)} />
{column}
</span>
<FilterButton column={column} classes={ activeFilter[column] ? 'active' : '' } clickHandler={handleFilterButtonClick} />
</div>
{ activeFilter[column] && <input value={filter[column]} onChange={(e) => { handleInputChange(e.target.value, column) }} autoFocus placeholder="filtertekst" /> }
</th>
)) }
</tr>
</thead>
<tbody>
{items.map((item) => (
<tr key={item['url']}>
{ columns.map(column => <td key={column} className={column}>
{ column === 'url' ? <a target="_blank" href={item[column]} rel="noopener noreferrer">{item[column]}</a> : item[column] }
</td>) }
{ columns.map(column => (
<td key={column} className={column}>
{ column === 'url' ? <a target="_blank" href={item[column]} rel="noopener noreferrer">{item[column]}</a> : <span>{ item[column] }</span> }
</td>
)) }
</tr>
))}
</tbody>
</table>
</>
);
};
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
import './styles.css';
import './styles.scss';
ReactDOM.render(
<React.StrictMode>
......
body {
font-family: 'Maax', sans-serif;
font-size: 16px;
}
table {
width: 100%;
border-collapse: collapse;
}
th, td {
max-width: 300px;
line-height: 1.4;
}
td.url {
min-width: 200px;
word-break: break-all;
}
thead th {
text-align: left;
border-bottom: 2px solid black;
font-weight: 500;
}
thead button {
border: 0;
border-radius: none;
font-family: inherit;
font-weight: 700;
font-size: inherit;
padding: 0.5em;
margin-bottom: 1px;
background: none;
cursor: pointer;
outline: none;
}
thead button.ascending::after {
content: '↓';
display: inline-block;
margin-left: 0.5em;
}
thead button.descending::after {
content: '↑';
display: inline-block;
margin-left: 0.5em;
}
tbody td {
padding: 0.5em;
border-bottom: 1px dashed #ccc;
}
/* tbody tr:hover {
background-color: #f9f9f9;
} */
body {
margin: 0
}
#databronnen {
font-family: "Maax", Arial, Helvetica, sans-serif;
padding: 1rem;
overflow: auto;
width: 100%;
height: 100%;
font-size: 18px;
box-sizing: border-box;
table {
//width: 100%;
border-collapse: collapse;
}
th, td {
line-height: 1.25rem;
vertical-align: top;
font-size: 0.8rem;
&:not(:last-child) {
border-right: 1px dashed #ccc;
}
&.url { min-width: 14rem; max-width: 14rem; }
&.titel { min-width: 14rem; max-width: 14rem; }
&.omschrijving { min-width: 14rem; max-width: 14rem; }
&.scope { min-width: 6rem; max-width: 6rem; }
&.toegang { min-width: 6rem; max-width: 6rem; }
&.type { min-width: 6rem; max-width: 6rem; }
&.formaat { min-width: 6rem; max-width: 6rem; }
&.thema { min-width: 8rem; max-width: 8rem; }
&.subthema { min-width: 8rem; max-width: 8rem; }
}
thead {
th {
text-align: left;
border-bottom: 2px solid black;
font-weight: 500;
min-width: 7em;
> div {
display: flex;
justify-content: space-between;
}
}
span {
padding: 0 0.25em;
vertical-align: middle;
cursor: pointer;
white-space: nowrap;
}
svg {
display: inline-block;
width: 1rem;
height: 1rem;
vertical-align: middle;
cursor: pointer;
path {
pointer-events: auto;
fill: #ccc;
}
}
.sort-button {
margin-right: 0.25em;
&.ascending path.asc { fill: #000; }
&.descending path.desc { fill: #000; }
}
.filter-button {
margin-right: 0.5rem;
&.active path {
fill: #000;
}
}
}
tbody td {
padding: 0.5em;
border-bottom: 1px dashed #ccc;
font-size: 0.75rem;
&.url {
word-break: break-all;
}
&.titel {
font-weight: 500;
}
&.omschrijving {
span {
display: block;
max-height: 4.25rem;
overflow: hidden;
transition: max-height 200ms ease;
&:hover {
max-height: 15rem;
}
}
}
}
input {
display: block;
width: calc(100% - 1rem);
margin: 0.25rem;
outline: none;
border: none;
background-color: #eee;
font-family: "Maax", Arial, Helvetica, sans-serif;
padding: 0.25rem;
line-height: 1rem;
}
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment