New filterbar

This commit is contained in:
Tom Hubrecht 2022-03-06 15:07:50 +01:00
parent d31a4bbcc4
commit 22c1b4a784
3 changed files with 81 additions and 28 deletions

View file

@ -35,6 +35,7 @@
bootstrap5Plugin
],
locale: frLocale,
allDayContent: '',
headerToolbar: {
left: 'prev,next today',
center: 'title',
@ -48,6 +49,7 @@
openModal = true;
event.set(info.event);
},
titleFormat: { year: '2-digit', month: 'numeric', day: 'numeric' },
events: [],
themeSystem: 'bootstrap5'
});
@ -82,13 +84,16 @@
<div class="app-container">
<h1 class="title">Calendrier de la vie étudiante à l'ENS</h1>
<div style="height: 100%; display: flex;">
<FilterBar {calendarTree} bind:selected={selectedCalendars} />
<div style="flex: 1;">
<FilterBar {calendarTree} bind:selected={selectedCalendars} />
<div class="h-100 d-flex">
<div class="flex-grow-1">
<FullCalendar bind:this={calendar} options={$options} />
</div>
<EventModal event={$event} open={openModal} {toggle} />
</div>
<EventModal event={$event} open={openModal} {toggle} />
</div>
<style>

View file

@ -1,14 +1,29 @@
<script>
import { Button, Offcanvas, Icon } from 'sveltestrap';
import FilterItem from './FilterItem.svelte';
export let calendarTree = [];
export let selected = null;
let subSelections = Array.from({length: Object.keys(calendarTree).length}, e => []);
let subSelections = Array.from({ length: Object.keys(calendarTree).length }, _ => []);
$: selected = subSelections.flat();
let open = true;
const toggle = () => (open = !open);
</script>
<ul>
{#each Object.entries(calendarTree) as [toplevel, subtrees], i}
<FilterItem item={toplevel} children={subtrees} bind:selected={subSelections[i]} />
{/each}
</ul>
<Button on:click={toggle} class="my-2">
<span class="me-2">Sélection des calendriers</span>
<Icon name="chevron-double-right" />
</Button>
<Offcanvas
isOpen={open}
{toggle}
scroll
placement="start"
header="Sélection des calendriers"
>
{#each Object.entries(calendarTree) as [toplevel, subtrees], i}
<FilterItem item={toplevel} children={subtrees} bind:selected={subSelections[i]} />
{/each}
</Offcanvas>

View file

@ -4,6 +4,7 @@
import TriStateCheckbox from './TriStateCheckbox.svelte';
import { createTriState, createTriStates, UNCHECKED, CHECKED, WEIRD } from './stores';
import { Icon } from 'sveltestrap';
export let item = null;
@ -11,12 +12,12 @@
export let selected = [];
export let filtering = createTriState(CHECKED);
let subfiltering = createTriStates(CHECKED, Object.entries(children).length);
let subselected = Array.from({length: Object.entries(children).length}, e => []);
let subselected = Array.from({ length: Object.entries(children).length }, e => []);
function isVal(val) {
return function (other) {
return other === val;
}
};
}
function areAllChecked(values) {
@ -30,7 +31,7 @@
function handleChildChange(i) {
return function handler(evt) {
subfiltering.setAt(i, evt.detail.value);
}
};
}
subfiltering.subscribe(subvalues => {
@ -38,7 +39,11 @@
filtering.setChecked();
} else if (areAllUnchecked(subvalues) && $filtering !== UNCHECKED) {
filtering.setUnchecked();
} else if (!areAllChecked(subvalues) && !areAllUnchecked(subvalues) && $filtering !== WEIRD) {
} else if (
!areAllChecked(subvalues) &&
!areAllUnchecked(subvalues) &&
$filtering !== WEIRD
) {
filtering.setWeird();
}
});
@ -62,21 +67,49 @@
dispatch('change', { value: evt.detail.value });
}
$: selected = $filtering === CHECKED ? [item, ...subselected.flat()] : subselected.flat();
$: icon = () => {
switch ($filtering) {
case UNCHECKED:
return 'circle';
case WEIRD:
return 'circle-half';
case CHECKED:
return 'check-circle-fill';
}
};
$: selected =
$filtering === CHECKED ? [item, ...subselected.flat()] : subselected.flat();
</script>
{#if item != null}
<li>
<TriStateCheckbox state={$filtering} on:change={handleChange} value={item} initialValue={true} />
<span>{item}</span>
<ul>
{#each Object.entries(children) as [toplevel, subchildren], i}
{#if subchildren}
<svelte:self item={toplevel} children={subchildren} on:change={handleChildChange(i)} filtering={subfiltering.storeAt(i)} bind:selected={subselected[i]} />
{:else}
<svelte:self item={toplevel} on:change={handleChildChange(i)} filtering={subfiltering.storeAt(i)} bind:selected={subselected[i]} />
{/if}
{/each}
</ul>
</li>
<li>
<TriStateCheckbox
state={$filtering}
on:change={handleChange}
value={item}
initialValue={true}
/>
<span><Icon name={icon()} />{item}</span>
<ul>
{#each Object.entries(children) as [toplevel, subchildren], i}
{#if subchildren}
<svelte:self
item={toplevel}
children={subchildren}
on:change={handleChildChange(i)}
filtering={subfiltering.storeAt(i)}
bind:selected={subselected[i]}
/>
{:else}
<svelte:self
item={toplevel}
on:change={handleChildChange(i)}
filtering={subfiltering.storeAt(i)}
bind:selected={subselected[i]}
/>
{/if}
{/each}
</ul>
</li>
{/if}