Skip to content
Merged
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: 19 additions & 9 deletions src/lib/components/bottom-nav-namespaces.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,22 @@
import type { NamespaceListItem } from '$lib/types/global';
import { sortAlphabetically } from '$lib/utilities/sort-alphabetically';

export let open = false;
export let namespaceList: NamespaceListItem[] = [];
interface Props {
open?: boolean;
namespaceList?: NamespaceListItem[];
}

let { open = false, namespaceList = [] }: Props = $props();

let search = '';
let search = $state('');

$: namespaces = sortAlphabetically(
search
? namespaceList.filter(({ namespace }) => namespace.includes(search))
: namespaceList,
(ns) => ns.namespace,
const namespaces = $derived(
sortAlphabetically(
search
? namespaceList.filter(({ namespace }) => namespace.includes(search))
: namespaceList,
(ns) => ns.namespace,
),
);
</script>

Expand All @@ -35,7 +41,11 @@
<button
class="namespace"
class:selected={namespace === $lastUsedNamespace}
on:click|preventDefault|stopPropagation={() => onClick(namespace)}
onclick={(e) => {
e.preventDefault();
e.stopPropagation();
onClick(namespace);
}}
>
{namespace}
</button>
Expand Down
68 changes: 38 additions & 30 deletions src/lib/components/lines-and-dots/event-type-filter.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import { writable } from 'svelte/store';

import { goto } from '$app/navigation';
import { page } from '$app/stores';
import { page } from '$app/state';

import Checkbox from '$lib/holocene/checkbox.svelte';
import Icon from '$lib/holocene/icon/icon.svelte';
Expand All @@ -26,43 +26,46 @@

import { CategoryIcon } from './constants';

export let compact = false;
interface Props {
compact?: boolean;
}

let open = writable(false);
let { compact = false }: Props = $props();

$: defaultOptions = compact
? compactEventTypeOptions.map((o) => o.value)
: allEventTypeOptions.map((o) => o.value);
const open = writable(false);

$: options = [
...(compact ? compactEventTypeOptions : allEventTypeOptions).map((o) => ({
...o,
label: translate(o.label),
icon: CategoryIcon[o.value],
description: translate(o.description),
})),
];
const defaultOptions = $derived(
compact
? compactEventTypeOptions.map((o) => o.value)
: allEventTypeOptions.map((o) => o.value),
);

$: {
const options = $derived.by(() => {
let list = (compact ? compactEventTypeOptions : allEventTypeOptions).map(
(o) => ({
...o,
label: translate(o.label),
icon: CategoryIcon[o.value],
description: o.description ? translate(o.description) : '',
}),
);
if (isVersionNewer('1.21.0', $temporalVersion)) {
options = options.filter(({ value }) => value !== 'update');
list = list.filter(({ value }) => value !== 'update');
}
}

$: {
if (!nexusEnabled($page.data.systemInfo?.capabilities)) {
options = options.filter(({ value }) => value !== 'nexus');
if (!nexusEnabled(page.data.systemInfo?.capabilities)) {
list = list.filter(({ value }) => value !== 'nexus');
}
}
return list;
});

const onOptionClick = ({ value }) => {
const onOptionClick = ({ value }: (typeof options)[number]) => {
clearActiveGroups();
const newCategories = $eventTypeFilter.some((type) => type === value)
? $eventTypeFilter.filter((type) => type !== value)
: [...$eventTypeFilter, value];
$eventTypeFilter = newCategories;
updateEventFilterParams(
$page.url,
page.url,
{
categories:
newCategories.length === defaultOptions.length ? null : newCategories,
Expand All @@ -75,7 +78,7 @@
$eventTypeFilter = defaultOptions;
$eventStatusFilter = false;
updateEventFilterParams(
$page.url,
page.url,
{ categories: null, statusFilter: false },
goto,
);
Expand All @@ -85,7 +88,7 @@
$eventTypeFilter = defaultOptions;
$eventStatusFilter = !$eventStatusFilter;
updateEventFilterParams(
$page.url,
page.url,
{ categories: null, statusFilter: !$eventStatusFilter },
goto,
);
Expand All @@ -95,13 +98,15 @@
$eventTypeFilter = [];
$eventStatusFilter = false;
updateEventFilterParams(
$page.url,
page.url,
{ categories: [], statusFilter: false },
goto,
);
};

$: filterActive = $eventTypeFilter.length < defaultOptions.length;
const filterActive = $derived(
$eventTypeFilter.length < defaultOptions.length,
);
</script>

<MenuContainer {open}>
Expand All @@ -111,7 +116,10 @@
class="flex h-6 w-6 flex-col items-center justify-center rounded-full transition-colors duration-200"
class:bg-interactive={filterActive}
>
<Icon name="filter" class={filterActive && 'pt-0.5 text-white'} />
<Icon
name="filter"
class={filterActive ? 'pt-0.5 text-white' : undefined}
/>
</div>
{/snippet}
<span class="hidden text-sm md:block">{translate('common.filter')}</span>
Expand Down Expand Up @@ -167,7 +175,7 @@
{translate('common.none')}
</MenuItem>
<MenuDivider />
{#each options as option}
{#each options as option (option.value)}
<MenuItem
data-testid={option.label}
description={option.description}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<script lang="ts">
import { getContext } from 'svelte';
import { getContext, type Snippet } from 'svelte';

import {
Menu,
Expand All @@ -12,8 +12,6 @@

import { FILTER_CONTEXT, type FilterContext } from './index.svelte';

const { filter, focusedElementId, handleSubmit } =
getContext<FilterContext>(FILTER_CONTEXT);
const defaultConditionOptions = [
{ value: '>' },
{ value: '>=' },
Expand All @@ -23,40 +21,55 @@
{ value: '<' },
];

export let options: { value: string; label?: string }[] =
defaultConditionOptions;
export let disabled = false;
export let inputId: string;
export let noBorderLeft = false;
export let noBorderRight = false;
interface Props {
options?: { value: string; label?: string }[];
disabled?: boolean;
inputId: string;
noBorderLeft?: boolean;
noBorderRight?: boolean;
children?: Snippet;
}

let {
options = defaultConditionOptions,
disabled = false,
inputId,
noBorderLeft = false,
noBorderRight = false,
children,
}: Props = $props();

let conditionalOptions = [
const { filter, focusedElementId, handleSubmit } =
getContext<FilterContext>(FILTER_CONTEXT);

const conditionalOptions = $derived([
...options,
{ value: 'is', label: translate('common.is-null') },
{ value: 'is not', label: translate('common.is-not-null') },
];
]);

$: filterConditionalOption = conditionalOptions.find(
(o) => o.value === $filter.conditional,
const filterConditionalOption = $derived(
conditionalOptions.find((o) => o.value === $filter.conditional),
);
$: {
filterConditionalOption;
updateFilterConditional();
}
$: isNullFilter = isNullConditional($filter.conditional);
$: selectedOption = filterConditionalOption ?? conditionalOptions[0];
$: selectedLabel = selectedOption?.label ?? selectedOption?.value;
const isNullFilter = $derived(isNullConditional($filter.conditional));
const selectedOption = $derived(
filterConditionalOption ?? conditionalOptions[0],
);
const selectedLabel = $derived(
selectedOption?.label ?? selectedOption?.value,
);

$effect(() => {
if (!filterConditionalOption) {
$filter.conditional = conditionalOptions[0].value;
}
});

function handleNullFilter() {
$filter.value = null;
$filter.customDate = false;
handleSubmit();
}

function updateFilterConditional() {
if (!filterConditionalOption)
$filter.conditional = conditionalOptions[0].value;
}
</script>

<MenuContainer>
Expand Down Expand Up @@ -85,5 +98,5 @@
</Menu>
</MenuContainer>
{#if !isNullFilter}
<slot />
{@render children?.()}
{/if}
29 changes: 21 additions & 8 deletions src/lib/components/search-attribute-filter/list-filter.svelte
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<script lang="ts">
import { getContext } from 'svelte';
import { getContext, type Snippet } from 'svelte';

import Button from '$lib/holocene/button.svelte';
import ChipInput from '$lib/holocene/input/chip-input.svelte';
Expand All @@ -11,12 +11,19 @@
import ConditionalMenu from './conditional-menu.svelte';
import { FILTER_CONTEXT, type FilterContext } from './index.svelte';

interface Props {
children?: Snippet;
}

let { children }: Props = $props();

const { filter, handleSubmit } = getContext<FilterContext>(FILTER_CONTEXT);

$: ({ value, conditional } = $filter);
$: _value = value;
$: chips = formatListFilterValue(_value);
$: options = [
const value = $derived($filter.value);
const conditional = $derived($filter.conditional);
let _value = $derived(value);
let chips = $derived(formatListFilterValue(_value));
const options = [
{ value: 'in', label: 'In' },
{ value: '=', label: translate('common.equal-to') },
{ value: '!=', label: translate('common.not-equal-to') },
Expand All @@ -36,7 +43,13 @@
}
</script>

<form class="flex grow" on:submit|preventDefault={onSubmit}>
<form
class="flex grow"
onsubmit={(e) => {
e.preventDefault();
onSubmit();
}}
>
<ConditionalMenu inputId="list-filter" noBorderLeft {options}>
{#if isInConditional(conditional)}
<ChipInput
Expand All @@ -54,7 +67,7 @@
<Button disabled={!chips.length} type="submit">
{translate('common.search')}
</Button>
<slot />
{@render children?.()}
</div>
{:else}
<Input
Expand All @@ -68,7 +81,7 @@
bind:value={_value}
on:keydown={handleKeydown}
/>
<slot />
{@render children?.()}
{/if}
</ConditionalMenu>
</form>
Loading
Loading