Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ca 419 persist applied filters in url params #1074

Open
wants to merge 13 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 26 additions & 2 deletions frontend/src/lib/components/Filters/SelectFilter.svelte
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<script lang="ts">
import { safeTranslate } from '$lib/utils/i18n';

export let value: string;
export let value: { label: string; value: string }[];

export let field: string;
export let helpText: string | undefined = undefined;
Expand All @@ -17,7 +17,7 @@
export let translateOptions = true;

export let options: string[];
options = [...new Set(options.flat())];
options = [...new Set(options ? options.flat() : [])];
options = options.filter((option) => option !== '');

const selectOptions = options
Expand All @@ -33,6 +33,7 @@
hide = hide || !(selectOptions && Object.entries(selectOptions).length > 1);

import * as m from '$paraglide/messages';
import { beforeUpdate, onMount } from 'svelte';

export let multiSelectOptions = {
maxSelect: multiple ? undefined : 1,
Expand All @@ -43,6 +44,29 @@
};

import MultiSelect from 'svelte-multiselect';

let initialValue: typeof value;
let isInitialized = false;

beforeUpdate(() => {
// Capture the initial value if we haven't already
if (!isInitialized && value) {
initialValue = Array.isArray(value) ? [...value] : value;
isInitialized = true;
}
});

onMount(() => {
// Restore the initial value if it was lost
if (initialValue && (!value || (Array.isArray(value) && value.length === 0))) {
value = initialValue;
}
});

$: value =
value && Array.isArray(value)
? value.map((v) => (v.label ? v : { label: v.value, value: v.value }))
: value;
</script>

{#if !hide}
Expand Down
47 changes: 28 additions & 19 deletions frontend/src/lib/components/ModelTable/ModelTable.svelte
Original file line number Diff line number Diff line change
@@ -1,26 +1,25 @@
<script lang="ts">
import { safeTranslate, unsafeTranslate } from '$lib/utils/i18n';
import { page } from '$app/stores';
import TableRowActions from '$lib/components/TableRowActions/TableRowActions.svelte';
import {
CUSTOM_ACTIONS_COMPONENT,
FIELD_COLORED_TAG_MAP,
FIELD_COMPONENT_MAP,
CUSTOM_ACTIONS_COMPONENT
FIELD_COMPONENT_MAP
} from '$lib/utils/crud';
import { createEventDispatcher, onMount } from 'svelte';
import { stringify } from '$lib/utils/helpers';
import { safeTranslate, unsafeTranslate } from '$lib/utils/i18n';
import { createEventDispatcher, onMount } from 'svelte';

import { tableA11y } from './actions';
// Types
import { ISO_8601_REGEX } from '$lib/utils/constants';
import type { urlModel } from '$lib/utils/types.js';
import * as m from '$paraglide/messages';
import { languageTag } from '$paraglide/runtime';
import type { CssClasses, SvelteEvent } from '@skeletonlabs/skeleton';
import type { SuperValidated } from 'sveltekit-superforms';
import type { AnyZodObject } from 'zod';
import type { TableSource } from './types';
import * as m from '$paraglide/messages';
import { toCamelCase } from '$lib/utils/locales';
import { languageTag } from '$paraglide/runtime';
import { ISO_8601_REGEX } from '$lib/utils/constants';
// Event Dispatcher
type TableEvent = {
selected: string[];
Expand Down Expand Up @@ -100,14 +99,14 @@
$: classesTable = `${element} ${text} ${color}`;

import { goto } from '$app/navigation';
import { formatDateOrDateTime } from '$lib/utils/datetime';
import { DataHandler } from '@vincjo/datatables';
import Pagination from './Pagination.svelte';
import RowCount from './RowCount.svelte';
import RowsPerPage from './RowsPerPage.svelte';
import Search from './Search.svelte';
import Th from './Th.svelte';
import ThFilter from './ThFilter.svelte';
import { formatDateOrDateTime } from '$lib/utils/datetime';

$: data = source.body.map((item: Record<string, any>, index: number) => {
return { ...item, meta: source.meta ? { ...source.meta[index] } : undefined };
Expand All @@ -118,7 +117,6 @@
rowsPerPage: pagination ? numberRowsPerPage : undefined
});
$: hasRows = data.length > 0;
const allRows = handler.getAllRows();
const tableURLModel = source.meta?.urlmodel ?? URLModel;
const filters =
tableURLModel && Object.hasOwn(listViewFields[tableURLModel], 'filters')
Expand All @@ -144,6 +142,10 @@
return value.includes(stringify(entry));
}

// Initialize filter values from URL search params
for (const field of filteredFields)
filterValues[field] = $page.url.searchParams.getAll(field).map((value) => ({ value }));

$: {
for (const field of filteredFields) {
handler.filter(
Expand All @@ -155,18 +157,24 @@
? filters[field].filter
: defaultFilterFunction
);
$page.url.searchParams.delete(field);
if (filterValues[field] && filterValues[field].length > 0) {
for (const value of filterValues[field]) {
$page.url.searchParams.append(field, value.value);
}
}
}
if (browser) goto($page.url);
}

let allowOptionsUpdate = true;
allRows.subscribe((rows) => {
if (!allowOptionsUpdate) return;
$: {
for (const key of filteredFields) {
filterProps[key] = (filters[key].filterProps ?? defaultFilterProps)(rows, key);
filterProps[key] = (filters[key].filterProps ?? defaultFilterProps)(
Object.values(source.meta),
key
);
}
if (rows.length > 0) allowOptionsUpdate = false;
});

}
const rows = handler.getRows();
const _filters = handler.getFilters();

Expand Down Expand Up @@ -203,9 +211,10 @@
(URLModel !== 'libraries' && Object.hasOwn(row.meta, 'urn') && row.meta.urn) ||
(Object.hasOwn(row.meta, 'reference_count') && row.meta.reference_count > 0);

import { popup } from '@skeletonlabs/skeleton';
import type { PopupSettings } from '@skeletonlabs/skeleton';
import { isDark } from '$lib/utils/helpers';
import type { PopupSettings } from '@skeletonlabs/skeleton';
import { popup } from '@skeletonlabs/skeleton';
import { browser } from '$app/environment';

const popupFilter: PopupSettings = {
event: 'click',
Expand Down
Loading
Loading