Combobox fix, map fix, tag search

pull/22/head
Nilesh 2022-06-03 14:35:57 +01:00
rodzic b420ed03ca
commit 7c1ab1afb7
8 zmienionych plików z 45 dodań i 53 usunięć

Wyświetl plik

@ -10,28 +10,27 @@
let query = {
text: "",
topic: "",
format: "",
level: "",
tags: "",
tag: "",
sortby: "rating"
};
$: fetch(`/learn/items.json?_shape=array&links__contains=${format}|`)
$: query && fetch(`/learn/items.json?_shape=array&_size=100&links__contains=${format}|&topics__contains=${query.topic}`)
.then(r => r.json())
.then(data => {
items = data;
});
function handleQueryChanged(event){
console.log("queryChanged: ", event.detail);
// console.log("queryChanged: ", event.detail);
query = event.detail;
}
$: filteredItems = items.filter(item => {
if(query.text && !item.name.toLowerCase().includes(query.text.toLowerCase())){ return false; }
if(query.format && !item.links.includes(query.format)) { return false; }
if(query.topic && !item.topics.includes(query.topic)){ return false; }
if(query.level && item.difficulty != query.level){ return false; }
// TODO Apply tags filter
if(query.tag && !item.tags.includes(query.tag)){ return false; }
return true;
}).sort((a,b) => {
if(query.sortby == 'rating') { return (a.rating - b.rating) };

Wyświetl plik

@ -3,16 +3,12 @@
import { createEventDispatcher } from 'svelte';
export let alltopics;
export let hideFormat = false;
export let hideTopic = false;
export let hideQuality = true;
let query = {
text: "",
topic: "",
format: "",
level: "",
quality: "",
sortby: "rating",
tag: ""
};
@ -24,24 +20,19 @@
</script>
<form class="w-full p-2 inline-flex flex-wrap" on:submit|preventDefault>
<sl-input type="search" placeholder="Type something to search items by keywords" size="medium" clearable class="flex-1 border-0 p-0 focus:ring-0" value={query.text} on:sl-input="{e => query.text = e.target.value}">
<sl-input type="search" placeholder="Search by keywords" size="medium" clearable class="flex-1 border-0 p-0 focus:ring-0" value={query.text} on:sl-input="{e => query.text = e.target.value}">
<sl-icon name="search" slot="prefix"></sl-icon>
</sl-input>
{#if !hideTopic}
<ComboBox options={alltopics.map(t => { return {label: t.display_name, value: t.name}; }).sort((a,b) => a.label.localeCompare(b.label)).slice(0,10)} selected={null}/>
<fluent-combobox autocomplete="both" placeholder="Any topic" class="ml-2 mt-1 outline-none border-2 border-grey-600" on:change="{e => query.topic = e.target.value}">
{#each alltopics.sort((a,b) => a.display_name.localeCompare(b.display_name)) as topic}
<fluent-option value={topic.name}>{topic.display_name}</fluent-option>
{/each}
</fluent-combobox>
{/if}
{#if !hideFormat}
<sl-select class="ml-2 w-44" on:sl-change="{e => query.format = e.target.value}" value={query.format}>
<sl-menu-item value="">Any format</sl-menu-item>
<sl-menu-item value="book">Books</sl-menu-item>
<sl-menu-item value="video">Videos</sl-menu-item>
<sl-menu-item value="audio">Podcasts</sl-menu-item>
</sl-select>
{/if}
<sl-select class="ml-2 w-44" on:sl-change="{e => query.tag = e.target.value}" value={query.tag}>
<sl-select class="ml-2 w-52" on:sl-change="{e => query.tag = e.target.value}" value={query.tag}>
<sl-menu-item value="">Any tag</sl-menu-item>
<sl-menu-item value="inspirational">Inspirational</sl-menu-item>
<sl-menu-item value="educational">Educational</sl-menu-item>
@ -49,6 +40,7 @@
<sl-menu-item value="entertaining">Entertaining</sl-menu-item>
<sl-menu-item value="visual">Visual</sl-menu-item>
<sl-menu-item value="interactive">Interactive</sl-menu-item>
<sl-menu-item value="oer">Open (no login or pay)</sl-menu-item>
</sl-select>
<sl-select class="ml-2 w-44" on:sl-change="{e => query.level = e.target.value}" value={query.level}>
@ -60,15 +52,6 @@
<sl-menu-item value="research">Research</sl-menu-item>
</sl-select>
{#if !hideQuality}
<sl-select class="ml-2 w-44" on:sl-change="{e => query.quality = e.target.value}" value={query.quality}>
<sl-menu-item value="">Any quality</sl-menu-item>
<sl-menu-item value="visual">Visual</sl-menu-item>
<sl-menu-item value="interactive">Interactive</sl-menu-item>
<sl-menu-item value="entertaining">Entertaining</sl-menu-item>
</sl-select>
{/if}
<sl-select class="ml-2 w-52" on:sl-change="{e => query.sortby = e.target.value}" value={query.sortby}>
<sl-icon name="sort-down-alt" slot="prefix"></sl-icon>
<sl-menu-item value="rating">Sort by Rating</sl-menu-item>

Wyświetl plik

@ -14,9 +14,8 @@
let query = {
text: "",
topic: "",
format: "",
level: "",
tags: "",
tag: "",
sortby: "rating"
};
@ -28,15 +27,14 @@
});
function handleQueryChanged(event){
console.log("queryChanged: ", event.detail);
// console.log("queryChanged: ", event.detail);
query = event.detail;
}
$: filteredItems = items.filter(item => {
if(query.text && !item.name.toLowerCase().includes(query.text.toLowerCase())){ return false; }
if(query.format && !item.links.includes(query.format)) { return false; }
if(query.level && item.difficulty != query.level){ return false; }
// TODO: apply tags filter
if(query.tag && !item.tags.includes(query.tag)){ return false; }
return true;
}).sort((a,b) => {
if(query.sortby == 'rating') { return (a.rating - b.rating) };

Wyświetl plik

@ -5,6 +5,6 @@
</script>
<div class="flex justify-end">
<a href="#/map" class="underline hover:scale-110 px-3 py-2 hover:ease-in-out transition duration-200">Try mapview (beta)</a>
<a href="#/map" class="font-semibold bg-lightTertiary text-lightBg rounded-lg hover:scale-110 px-3 py-2 hover:ease-in-out transition duration-200">Explore Map</a>
</div>
<TopicMasonryGrid {alltopics}/>

Wyświetl plik

@ -84,7 +84,7 @@
</sl-breadcrumb>
</div>
<div class="gap-8 columns-1 sm:columns-2 lg:columns-3 xl:columns-4 2xl:columns-5 mb-8">
<div class="gap-8 columns-1 sm:columns-2 lg:columns-3 xl:columns-4 3xl:columns-5 mb-8">
{#each [...map.entries()].sort((t1,t2) => (t1[0].sort_index || 100) - (t2[0].sort_index || 100)) as parent}
<a href={"#/topic/" + parent[0].name}>
<div class="rounded-lg shadow-md p-4 break-inside-avoid mb-4 border-8 border-lightPrimCont dark:border-darkPrimCont hover:bg-lightPrimCont dark:bg-darkPrimCont ">

Wyświetl plik

@ -1,15 +1,24 @@
<script>
export let options = [];
let userInput = '3';
export let userInput = '';
$: filteredOptions = options.filter(x => x.label.startsWith(userInput))
$: console.log(userInput)
$: console.log({options})
$: console.log(filteredOptions)
$: console.log({userInput})
</script>
<sl-dropdown>
<sl-input slot="trigger" on:change="{e => userInput = e.target.value}" value={userInput}></sl-input>
<sl-dropdown class="ml-2">
<sl-input
slot="trigger"
class="p-0 m-0 border-0"
on:sl-input="{e => userInput = e.target.value}"
value={userInput}
placeholder="select topic">
</sl-input>
<sl-menu>
{#each filteredOptions as opt (opt.value)}
<sl-menu-item>{opt.label}</sl-menu-item>
<sl-menu-item on:click="{e => userInput = opt.value}">{opt.label}</sl-menu-item>
{/each}
</sl-menu>
</sl-dropdown>

Wyświetl plik

@ -23,6 +23,8 @@ body {
text {
cursor: pointer;
fill: #7a28cb;
}
.grandparent text {
@ -40,11 +42,11 @@ rect.parent,
}
.grandparent rect {
fill: rgb(232, 255, 0);
fill: #f4b393;
}
.grandparent:hover rect {
fill: rgb(202, 225, 0);
fill: #f4d393;
}
.children rect.parent,
@ -54,21 +56,21 @@ rect.parent,
.leaf rect.parent {
cursor: pointer;
fill: #c9d9ff;
fill: #ffdbd1;
}
.leaf rect.parent:hover {
cursor: pointer;
fill: #d9e9ff;
fill: #ffcfd4;
}
.children rect.parent {
fill: #99F6E4;
fill: #ceec97;
fill-opacity: .5;
}
.children:hover rect.child {
fill: #D7CBFA;
fill: #deec97;
}
</style>
@ -88,8 +90,8 @@ function hierarchy(topic_array, parent_id){
.map(item => ({ ...item, children: nest(items, item.name), value: 100 }))
.map(item => {
return item.children.length == 0 ?
{id: item.name, name: item.name.split("/").reverse()[0], value: 100} :
{id: item.name, name: item.name.split("/").reverse()[0], children: item.children}
{id: item.name, name: item.name, value: 100} :
{id: item.name, name: item.name, children: item.children}
});
let topnodes = nest(topic_array, ''); // includes childless nodes
@ -98,7 +100,7 @@ function hierarchy(topic_array, parent_id){
let misc = {id: 'misc', name: 'Misc', children: topnodes.filter(t => t.value).slice(0,15)};
return {name: "·", children: [...topnodes.filter(t => t.children), misc]};
return {name: "", children: [...topnodes.filter(t => t.children), misc]};
}
d3.json("/learn/topics.json?_shape=array&_size=5000", function(alltopics){
@ -232,7 +234,7 @@ grandparent.append("text")
g.append("text")
.attr("dy", ".75em")
.on("click", (n) => { window.parent.location.href = "/#/topic/" + n.name;})
.text(function(d) { return d.name.split('{')[0].split('(')[0]
.text(function(d) { return d.name.split('/').reverse()[0].split('{')[0].split('(')[0]
.split('[')[0]; })
.call(text);

Wyświetl plik

@ -46,6 +46,7 @@
<link href="/static/bundle.css" rel="stylesheet" />
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/@shoelace-style/shoelace@2.0.0-beta.73/dist/themes/light.css" />
<script type="module" src="https://cdn.jsdelivr.net/npm/@shoelace-style/shoelace@2.0.0-beta.73/dist/shoelace.js"></script>
<script type="module" src="https://unpkg.com/@fluentui/web-components"></script>
<title>LearnAwesome</title>
<!-- fonts -->