Skip to content

Instantly share code, notes, and snippets.

@CroquetMickael
Last active August 18, 2021 19:41
Show Gist options
  • Save CroquetMickael/a945d4e5c4a7578dd558c4dbddf53e49 to your computer and use it in GitHub Desktop.
Save CroquetMickael/a945d4e5c4a7578dd558c4dbddf53e49 to your computer and use it in GitHub Desktop.
recursiveFilteringWithReact
import React from "react";
const mapCheckBox = [
{ label: "Draft", value: "draft" },
{ label: "Published", value: "published" },
];
const Filters = ({ setSearch, setStatus, status, setLastVersionAsk }) => {
const handleSearchChange = (event) => {
event.persist();
let timeoutId = null;
window.clearTimeout(timeoutId);
timeoutId = window.setTimeout(() => {
setSearch(event.target.value);
}, 500);
};
const handleCheckboxChange = React.useCallback((event) => {
const copyOfStatus = status;
if (event.target.checked) {
copyOfStatus.push(event.target.value);
} else {
const ElementCheckedIndexOf = status.indexOf(event.target.value);
copyOfStatus.splice(ElementCheckedIndexOf, 1);
}
setStatus([...copyOfStatus]);
}, []);
return (
<div className="flex flex-col my-8">
<div class="relative mr-6 my-2">
<input
type="text"
class="bg-purple-white shadow rounded border-0 p-1"
placeholder="Search by project..."
onChange={handleSearchChange}
/>
</div>
<div className="flex flex-col">
{mapCheckBox.map(({ label, value }) => (
<div>
<label htmlFor={value} className="mx-2" key={label}>
{label}
</label>
<input
id={value}
type="checkbox"
value={value}
onChange={handleCheckboxChange}
/>
</div>
))}
<div>
<label htmlFor="lastVersion" className="mx-2">
Only last version
</label>
<input
id="lastVersion"
type="checkbox"
onChange={(event) => setLastVersionAsk(event.target.checked)}
/>
</div>
</div>
</div>
);
};
export { Filters };
import React, { useState } from "react";
import useFilters from "../hooks/useFilters";
import { Filters } from "./Filters";
import ResultTable from "./ResultTable";
import values from "./values.json";
const ListWithFilters = () => {
const [search, setSearch] = useState("");
const [status, setStatus] = useState([]);
const [isLastVersionAsk, setLastVersionAsk] = useState(false);
const { filteredValues } = useFilters(values, [
{
field: "status",
predicate: ({ value }) =>
status.length > 0 ? status.includes(value.status) : true,
},
{
field: "libelle",
predicate: ({ value }) => new RegExp(search, "i").test(value.libelle),
},
...(isLastVersionAsk
? [
{
field: "version",
predicate: ({ value, values }) =>
values
.filter((v) => v.libelle === value.libelle)
.sort((a, b) => b.version - a.version)[0].version ===
value.version,
},
]
: []),
]);
return (
<div className="flex flex-row">
<Filters
setSearch={setSearch}
setStatus={setStatus}
status={status}
setLastVersionAsk={setLastVersionAsk}
/>
<div className="w-full">
<ResultTable values={filteredValues} />
</div>
</div>
);
};
export default ListWithFilters;
import React from "react";
const ResultTable = ({ values }) => (
<table class="min-w-max w-full table-auto">
<thead>
<tr class="bg-gray-200 text-gray-600 uppercase text-sm leading-normal">
<th class="py-3 px-6 text-left">Project</th>
<th class="py-3 px-6 text-left">Status</th>
<th class="py-3 px-6 text-left">Version</th>
</tr>
</thead>
<tbody class="text-gray-600 text-sm font-light">
{values.map((value) => (
<tr class="border-b border-gray-200 hover:bg-gray-100">
<td class="py-3 px-6 text-left whitespace-nowrap">
<div class="flex items-center">
<span class="font-medium">{value.libelle}</span>
</div>
</td>
<td class="py-3 px-6 text-left whitespace-nowrap">
<div class="flex items-center">
<span class="font-medium">{value.status}</span>
</div>
</td>
<td class="py-3 px-6 text-left whitespace-nowrap">
<div class="flex items-center">
<span class="font-medium">{value.version}</span>
</div>
</td>
</tr>
))}
</tbody>
</table>
);
export default ResultTable;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment