Skip to content
Snippets Groups Projects
Commit 53de4389 authored by Christophe's avatar Christophe
Browse files

feat(index): sorting

parent 9a34685b
No related branches found
No related tags found
1 merge request!10Update ai4eosc branch with recent main (multiple templates)
import { ChangeEventHandler, FC } from 'react';
import Ordering from 'lib/Ordering';
type OrderingSelectorProps = {
onChange: (ordering: Ordering | undefined) => void;
};
const OrderingSelector: FC<OrderingSelectorProps> = ({ onChange }) => {
const _onChange: ChangeEventHandler<HTMLSelectElement> = (e) => {
if (e.target.value.trim().length === 0) {
onChange(undefined);
return;
}
onChange(e.target.value as Ordering);
};
return (
<div>
<label htmlFor="ordering" className="mr-2 text-lg">
Ordering:
</label>
<select
className="rounded-md w-60 disabled:opacity-50"
id="ordering"
onChange={_onChange}
>
<option></option>
<option value={Ordering.TITLE_ASC}>Title Ascending</option>
<option value={Ordering.TITLE_DES}>Title Descending</option>
<option value={Ordering.SCORE_ASC}>Score Ascending</option>
<option value={Ordering.SCORE_DES}>Score Descending</option>
</select>
</div>
);
};
export default OrderingSelector;
const Ordering = {
ID_ASC: '+id',
ID_DES: '-id',
SCORE_ASC: '+score',
SCORE_DES: '-score',
TITLE_ASC: '+title',
TITLE_DES: '-title',
} as const;
type Ordering = typeof Ordering[keyof typeof Ordering];
export default Ordering;
......@@ -8,15 +8,18 @@ import ErrorBox from 'components/ErrorBox';
import { useMemo, useState } from 'react';
import { difference } from 'lodash';
import SelectedTag from 'components/SelectedTag';
import Ordering from 'lib/Ordering';
import OrderingSelector from 'components/OrderingSelector';
// TODO: SSR?
const Templates: NextPage = () => {
const api = useTemplateApi();
const [selectedTags, setSelectedTags] = useState<string[]>([]);
const [ordering, setOrdering] = useState<Ordering | undefined>(undefined);
const templates = useQuery(
['templates', selectedTags],
() => api.listTemplates(undefined, selectedTags),
['templates', selectedTags, ordering],
() => api.listTemplates(undefined, selectedTags, undefined, ordering),
{
keepPreviousData: true,
}
......@@ -58,41 +61,45 @@ const Templates: NextPage = () => {
{templates.data && (
<>
<div className="flex flex-row items-center mb-2">
<label htmlFor="tag-select" className="mr-2 text-lg">
Filter by tags:
</label>
<select
onChange={(e) => select(e.currentTarget.value)}
className="rounded-md w-60 disabled:opacity-50"
id="tag-select"
disabled={availableTags.length === selectedTags.length}
value={''}
>
{availableTags.length === selectedTags.length ? (
<option>No more tags available.</option>
) : (
<>
<option selected></option>
{difference(availableTags, selectedTags)
.sort()
.map((tag) => (
<option key={tag} value={tag}>
{tag}
</option>
))}
</>
)}
</select>
<div className="ml-2 flex flex-row flex-wrap gap-1">
{selectedTags.map((tag) => (
<SelectedTag
key={tag}
tag={tag}
onDelete={(tag) => unselect(tag)}
/>
))}
<div className="flex flex-row">
<div className="flex flex-row items-center mb-2">
<label htmlFor="tag-select" className="mr-2 text-lg">
Filter by tags:
</label>
<select
onChange={(e) => select(e.currentTarget.value)}
className="rounded-md w-60 disabled:opacity-50"
id="tag-select"
disabled={availableTags.length === selectedTags.length}
value={''}
>
{availableTags.length === selectedTags.length ? (
<option>No more tags available.</option>
) : (
<>
<option selected></option>
{difference(availableTags, selectedTags)
.sort()
.map((tag) => (
<option key={tag} value={tag}>
{tag}
</option>
))}
</>
)}
</select>
<div className="ml-2 flex flex-row flex-wrap gap-1">
{selectedTags.map((tag) => (
<SelectedTag
key={tag}
tag={tag}
onDelete={(tag) => unselect(tag)}
/>
))}
</div>
</div>
<div className="flex-grow" />
<OrderingSelector onChange={setOrdering} />
</div>
<div className="grid grid-cols-1 md:grid-cols-2 xl:grid-cols-3 gap-4 auto-rows-fr">
{templates.data.data.map((template) => (
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment