feat(logic): implement filter bar / filter item selection logic

This commit is contained in:
Raito Bezarius 2022-03-05 04:32:49 +01:00
parent cfe3956c98
commit 3fee527be1
5 changed files with 3754 additions and 36 deletions

3726
package-lock.json generated

File diff suppressed because it is too large Load diff

View file

@ -27,6 +27,8 @@
"svelte-fullcalendar": "^1.1.1" "svelte-fullcalendar": "^1.1.1"
}, },
"dependencies": { "dependencies": {
"@fullcalendar/adaptive": "^5.10.1",
"@fullcalendar/list": "^5.10.1",
"@fullcalendar/rrule": "^5.10.1", "@fullcalendar/rrule": "^5.10.1",
"@nextcloud/cdav-library": "^1.0.0", "@nextcloud/cdav-library": "^1.0.0",
"ical.js": "^1.5.0", "ical.js": "^1.5.0",

View file

@ -3,8 +3,10 @@
import { writable } from 'svelte/store'; import { writable } from 'svelte/store';
import FullCalendar from 'svelte-fullcalendar'; import FullCalendar from 'svelte-fullcalendar';
import timeGridPlugin from '@fullcalendar/timegrid'; import timeGridPlugin from '@fullcalendar/timegrid';
import adaptivePlugin from '@fullcalendar/adaptive';
import rrulePlugin from '@fullcalendar/rrule'; import rrulePlugin from '@fullcalendar/rrule';
import dayGridPlugin from '@fullcalendar/daygrid'; import dayGridPlugin from '@fullcalendar/daygrid';
import listPlugin from '@fullcalendar/list';
import frLocale from '@fullcalendar/core/locales/fr'; import frLocale from '@fullcalendar/core/locales/fr';
import Modal, { bind } from 'svelte-simple-modal'; import Modal, { bind } from 'svelte-simple-modal';
import EventDetails from './EventDetails.svelte'; import EventDetails from './EventDetails.svelte';
@ -12,11 +14,17 @@
import { refreshEvents, calendarTree } from './calendar'; import { refreshEvents, calendarTree } from './calendar';
const modal = writable(null); const modal = writable(null);
let calendar;
let options = { let options = {
initialView: 'timeGridWeek', initialView: 'timeGridWeek',
plugins: [timeGridPlugin, dayGridPlugin, rrulePlugin], plugins: [timeGridPlugin, dayGridPlugin, rrulePlugin, listPlugin, adaptivePlugin],
locale: frLocale, locale: frLocale,
headerToolbar: {
left: 'prev,next today',
center: 'title',
right: 'dayGridMonth,timeGridWeek,listWeek'
},
height: "100%", height: "100%",
schedulerLicenseKey: 'CC-Attribution-NonCommercial-NoDerivatives', schedulerLicenseKey: 'CC-Attribution-NonCommercial-NoDerivatives',
nowIndicator: true, nowIndicator: true,
@ -34,8 +42,6 @@
options.events = evts.flat(); options.events = evts.flat();
options = { ...options }; options = { ...options };
}); });
$: console.log(options);
</script> </script>
<div class="app-container"> <div class="app-container">
@ -44,7 +50,7 @@
<Modal show={$modal}> <Modal show={$modal}>
<FilterBar {calendarTree} {selectedCalendars} /> <FilterBar {calendarTree} {selectedCalendars} />
<div style="flex: 1;"> <div style="flex: 1;">
<FullCalendar {options} /> <FullCalendar bind:this={calendar} {options} />
</div> </div>
</Modal> </Modal>
</div> </div>

View file

@ -2,10 +2,13 @@
import FilterItem from './FilterItem.svelte'; import FilterItem from './FilterItem.svelte';
export let calendarTree = []; export let calendarTree = [];
export let selectedCalendars = null; export let selectedCalendars = null;
let subSelections = Array(Object.keys(calendarTree).length).fill([]);
$: selectedCalendars = subSelections.flat();
</script> </script>
<ul> <ul>
{#each Object.entries(calendarTree) as [toplevel, subtrees]} {#each Object.entries(calendarTree) as [toplevel, subtrees], i}
<FilterItem item={toplevel} children={subtrees} /> <FilterItem item={toplevel} children={subtrees} bind:selected={subSelections[i]} />
{/each} {/each}
</ul> </ul>

View file

@ -1,15 +1,44 @@
<script> <script>
export let item = null; export let item = null;
export let children = []; export let children = [];
export let filtering = true;
export let selected = [];
let subfiltering = Object.entries(children).map(([k, v]) => v ? true : false);
function setAllSubFilters(value) {
subfiltering = Object.entries(children).map(([k, v]) => value);
}
function handleClick(evt) {
setAllSubFilters(evt.target.checked);
}
$: if (subfiltering.length > 0) {
filtering = subfiltering.every(Boolean);
}
$: {
const subselected = Object.entries(children).flatMap(([toplevel, _], index) => subfiltering[index] ? [toplevel] : []);
if (item != null && filtering) {
selected = [item, ...subselected];
} else {
selected = subselected;
}
}
</script> </script>
{#if item != null} {#if item != null}
<li> <li>
<input type="checkbox" value={item}><span>{item}</span> <input type="checkbox" bind:checked={filtering} on:click={handleClick} value={item}><span>{item}</span>
<ul> <ul>
{#each Object.entries(children) as [toplevel, subchildren]} {#each Object.entries(children) as [toplevel, subchildren], i}
<svelte:self item={toplevel} children={subchildren} /> {#if subchildren}
{/each} <svelte:self item={toplevel} children={subchildren} bind:filtering={subfiltering[i]} />
</ul> {:else}
<svelte:self item={toplevel} />
{/if}
{/each}
</ul>
</li> </li>
{/if} {/if}