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

MultiSelect component used in Event Type filter #1806

Merged
merged 4 commits into from
Jan 19, 2024
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
75 changes: 0 additions & 75 deletions src/lib/components/event/event-category-filter.svelte

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
<script lang="ts">
import { page } from '$app/stores';

import MultiSelect from '$lib/holocene/select/multi-select.svelte';
import { translate } from '$lib/i18n/translate';
import {
allEventTypeOptions,
compactEventTypeOptions,
} from '$lib/models/event-history/get-event-categorization';
import { eventCategoryFilter } from '$lib/stores/filters';
import { temporalVersion } from '$lib/stores/versions';
import { updateQueryParameters } from '$lib/utilities/update-query-parameters';
import { isVersionNewer } from '$lib/utilities/version-check';

export let compact = false;

$: label = compact
? translate('events.event-type')
: translate('events.workflow-events');

let parameter = 'category';
let options = compact ? compactEventTypeOptions : allEventTypeOptions;

$: {
if (isVersionNewer('1.21', $temporalVersion)) {
options = options.filter(({ value }) => value !== 'update');
}
}
$: initialSelected = $eventCategoryFilter
? options.filter((o) => $eventCategoryFilter.includes(o.value))
: [];

const onOptionClick = (_options) => {
const value = _options.map((o) => o.value).join(',');
updateQueryParameters({
parameter: parameter,
value,
url: $page.url,
});
};
</script>

<MultiSelect
id="event-category-filter-menu"
{options}
{initialSelected}
{label}
active={!!$eventCategoryFilter}
selectAllLabel={translate('common.select-all')}
clearAllLabel={translate('common.clear-all-capitalized')}
onChange={onOptionClick}
variant="table-header"
icon="filter"
/>
26 changes: 17 additions & 9 deletions src/lib/components/event/event-history-timeline.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,6 @@
let visualizationRef;
let timeline;

$: category = $eventCategoryFilter as EventTypeCategory;

function renderComponentToHTML(Component, props) {
const container = document.createElement('div');
new Component({ target: container, props });
Expand Down Expand Up @@ -74,7 +72,7 @@
const firstEvent = sortedHistory[0];
const finalEvent = sortedHistory[sortedHistory.length - 1];

if (!category) {
if (!$eventCategoryFilter) {
groups.add({
id: 'workflow',
content: renderExecutionName(),
Expand Down Expand Up @@ -163,24 +161,28 @@

const filterHistory = (
history: CommonHistoryEvent[],
category: EventTypeCategory,
category: EventTypeCategory[],
): CommonHistoryEvent[] => {
if (!category) return history;
return history.filter((i) => {
if (category === CATEGORIES.LOCAL_ACTIVITY) {
return isLocalActivityMarkerEvent(i);
if (category.includes(CATEGORIES.LOCAL_ACTIVITY)) {
return category.includes(i.category) || isLocalActivityMarkerEvent(i);
}
return i.category === category;
return category.includes(i.category);
});
};

const buildTimeline = (category: EventTypeCategory): void => {
const buildTimeline = (): void => {
timeline = new Timeline(
visualizationRef,
new DataSet([]),
new DataSet([]),
getTimelineOptions($workflowRun.workflow),
);
filterAndSetItems($eventCategoryFilter);
};

const filterAndSetItems = (category: EventTypeCategory[]) => {
const reverseHistory =
$eventFilterSort === 'descending' && $eventViewType === 'feed';
const sortedHistory = reverseHistory
Expand Down Expand Up @@ -210,14 +212,20 @@
if (timeline) {
timeline.destroy();
}
buildTimeline(category);
buildTimeline();
};

$: {
if (readyToDraw) {
drawTimeline();
}
}

$: {
if (timeline) {
filterAndSetItems($eventCategoryFilter);
}
}
</script>

<Accordion
Expand Down
5 changes: 3 additions & 2 deletions src/lib/components/event/event-summary-table.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,15 @@

import { page } from '$app/stores';

import EventCategoryFilter from '$lib/components/event/event-category-filter.svelte';
import EventDateFilter from '$lib/components/event/event-date-filter.svelte';
import Button from '$lib/holocene/button.svelte';
import TableHeaderRow from '$lib/holocene/table/table-header-row.svelte';
import Table from '$lib/holocene/table/table.svelte';
import { translate } from '$lib/i18n/translate';
import { expandAllEvents } from '$lib/stores/event-view';

import EventCategoryMultiselectFilter from './event-category-multiselect-filter.svelte';

export let compact = false;
export let updating = false;

Expand Down Expand Up @@ -41,7 +42,7 @@
<th class="w-16 md:w-32">
<EventDateFilter {compact} />
</th>
<th class="w-44"><EventCategoryFilter {compact} /></th>
<th class="w-44"><EventCategoryMultiselectFilter {compact} /></th>
<th class="w-auto xl:w-80">
<div class="flex w-full justify-end">
<Button
Expand Down
18 changes: 12 additions & 6 deletions src/lib/components/event/event-summary.svelte
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
<script lang="ts">
import { page } from '$app/stores';

import EventSummaryRow from '$lib/components/event/event-summary-row.svelte';
import EventSummaryTable from '$lib/components/event/event-summary-table.svelte';
import Pagination from '$lib/holocene/pagination.svelte';
Expand All @@ -25,14 +27,14 @@

const getEventsOrGroups = (
items: CommonHistoryEvent[],
category: string,
category?: string[],
): IterableEvent[] => {
if (category) {
const filteredItems = items.filter((i) => {
if (category === CATEGORIES.LOCAL_ACTIVITY) {
return isLocalActivityMarkerEvent(i);
if (category.includes(CATEGORIES.LOCAL_ACTIVITY)) {
return category.includes(i.category) || isLocalActivityMarkerEvent(i);
}
return i.category === category;
return category.includes(i.category);
});
return compact
? groupEvents(filteredItems, $eventFilterSort)
Expand All @@ -41,7 +43,11 @@
return compact ? groupEvents(items, $eventFilterSort) : items;
};

$: category = $eventCategoryFilter as EventTypeCategory;
$: $eventCategoryFilter = $page.url?.searchParams?.get('category')
? ($page.url?.searchParams
?.get('category')
.split(',') as EventTypeCategory[])
: undefined;
$: intialEvents =
$eventFilterSort === 'descending' && !compact
? $eventHistory?.end
Expand All @@ -50,7 +56,7 @@
? $fullEventHistory
: intialEvents;
$: initialItem = currentEvents?.[0];
$: items = getEventsOrGroups(currentEvents, category);
$: items = getEventsOrGroups(currentEvents, $eventCategoryFilter);
$: updating = currentEvents.length && !$fullEventHistory.length;
</script>

Expand Down
95 changes: 95 additions & 0 deletions src/lib/holocene/select/multi-select.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
<script lang="ts">
import { writable } from 'svelte/store';

import Checkbox from '$lib/holocene/checkbox.svelte';
import {
Menu,
MenuButton,
MenuContainer,
MenuDivider,
MenuItem,
} from '$lib/holocene/menu';

import Icon from '../icon/icon.svelte';
import type { IconName } from '../icon/paths';
import type { MenuButtonVariant } from '../menu/menu-button.svelte';

type Option = { label: string; value: string };
type MultiSelectOptions = Option[];

export let options: MultiSelectOptions = [];
export let initialSelected: MultiSelectOptions = [];
export let onChange: (options: MultiSelectOptions) => void;
export let label: string;
export let id: string;
export let variant: MenuButtonVariant = 'secondary';
export let icon: IconName | undefined = undefined;
export let selectAllLabel: string;
export let clearAllLabel: string;
export let active = false;

let selectedOptions = initialSelected.length ? initialSelected : options;

const open = writable(false);

const onOptionClick = (option: Option) => {
if (selectedOptions.some((s) => s.value === option.value)) {
selectedOptions = selectedOptions.filter((s) => s.value !== option.value);
} else {
selectedOptions = [...selectedOptions, option];
}
onChange(selectedOptions);
};

const onSelectAllOptionClick = () => {
selectedOptions = options;
onChange([]);
rossedfort marked this conversation as resolved.
Show resolved Hide resolved
};

const onRemoveAllOptionClick = () => {
selectedOptions = [];
onChange([]);
};
</script>

<MenuContainer {open}>
<MenuButton hasIndicator controls={id} {variant} {active}>
{#if icon}<Icon class="md:hidden" name={icon} />{/if}
<span class="max-md:hidden">{label}</span>
</MenuButton>
<Menu {id} keepOpen>
{#each options as option (option)}
{@const checked = Boolean(
selectedOptions.find((s) => s.value === option.value),
)}
<MenuItem
data-testid={option.label}
on:click={() => {
onOptionClick(option);
}}
>
<Checkbox
on:click={() => onOptionClick(option)}
slot="leading"
{checked}
label={option.label}
labelHidden
/>
Comment on lines +71 to +77
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

check out bind:group 👀

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Normally would agree, but we need to call onChange as well

{option.label}
</MenuItem>
{/each}
<MenuDivider />
<MenuItem
data-testid="multiselect-select-all"
on:click={onSelectAllOptionClick}
>
{selectAllLabel}
</MenuItem>
<MenuItem
data-testid="multiselect-remove-all"
on:click={onRemoveAllOptionClick}
>
{clearAllLabel}
</MenuItem>
</Menu>
</MenuContainer>
1 change: 1 addition & 0 deletions src/lib/i18n/locales/en/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ export const Strings = {
local: 'Local',
cancel: 'Cancel',
'clear-all': 'Clear all',
'clear-all-capitalized': 'Clear All',
'ante-meridiem': 'AM',
'post-meridiem': 'PM',
ascending: 'Ascending',
Expand Down
Loading
Loading