forked from DGNum/metis
feat(logic): implement filter bar / filter item selection logic
This commit is contained in:
parent
cfe3956c98
commit
3fee527be1
5 changed files with 3754 additions and 36 deletions
3726
package-lock.json
generated
3726
package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
@ -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",
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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}
|
||||||
|
|
Loading…
Reference in a new issue