Skip to content

Commit

Permalink
Merge branch 'main' into user-metadata
Browse files Browse the repository at this point in the history
  • Loading branch information
Alex-Tideman committed Nov 20, 2024
2 parents 057d477 + bbaa395 commit 77f4828
Show file tree
Hide file tree
Showing 8 changed files with 223 additions and 62 deletions.
41 changes: 41 additions & 0 deletions src/lib/components/namespace-picker.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
<script lang="ts">
import { page } from '$app/stores';
import Combobox from '$lib/holocene/combobox/combobox.svelte';
import { translate } from '$lib/i18n/translate';
import { lastUsedNamespace } from '$lib/stores/namespaces';
import type { NamespaceListItem } from '$lib/types/global';
import { routeForNamespace } from '$lib/utilities/route-for';
export let namespaceList: NamespaceListItem[] = [];
$: namespace = $page.params.namespace || $lastUsedNamespace;
$: namespaceExists = namespaceList.some(
(namespaceListItem) => namespaceListItem.namespace === namespace,
);
$: href = routeForNamespace({ namespace });
const handleNamespaceSelect = (
event: CustomEvent<{ value: NamespaceListItem }>,
) => {
const namespaceListItem = event.detail.value;
$lastUsedNamespace = namespaceListItem.namespace;
namespaceListItem?.onClick(namespaceListItem.namespace);
};
</script>

<Combobox
label={translate('namespaces.namespace-label', { namespace })}
noResultsText={translate('common.no-results')}
labelHidden
value={namespace}
id="namespace-switcher"
leadingIcon="namespace-switcher"
options={namespaceList}
optionValueKey="namespace"
on:change={handleNamespaceSelect}
minSize={32}
actionTooltip={translate('namespaces.go-to-namespace')}
{href}
hrefDisabled={!namespaceExists}
/>
38 changes: 1 addition & 37 deletions src/lib/components/top-nav.svelte
Original file line number Diff line number Diff line change
@@ -1,31 +1,9 @@
<script lang="ts">
import { page } from '$app/stores';
import DataEncoderStatus from '$lib/components/data-encoder-status.svelte';
import TimezoneSelect from '$lib/components/timezone-select.svelte';
import Combobox from '$lib/holocene/combobox/combobox.svelte';
import { translate } from '$lib/i18n/translate';
import { lastUsedNamespace } from '$lib/stores/namespaces';
import type { NamespaceListItem } from '$lib/types/global';
import { routeForNamespace } from '$lib/utilities/route-for';
export let namespaceList: NamespaceListItem[] = [];
let screenWidth: number;
$: namespace = $page.params.namespace || $lastUsedNamespace;
$: namespaceExists = namespaceList.some(
(namespaceListItem) => namespaceListItem.namespace === namespace,
);
$: href = routeForNamespace({ namespace });
const handleNamespaceSelect = (
event: CustomEvent<{ value: NamespaceListItem }>,
) => {
const namespaceListItem = event.detail.value;
$lastUsedNamespace = namespaceListItem.namespace;
namespaceListItem?.onClick(namespaceListItem.namespace);
};
</script>

<svelte:window bind:innerWidth={screenWidth} />
Expand All @@ -35,21 +13,7 @@
aria-label={translate('common.main')}
>
<div class="flex grow items-center">
<Combobox
label={translate('namespaces.namespace-label', { namespace })}
noResultsText={translate('common.no-results')}
labelHidden
value={namespace}
id="namespace-switcher"
leadingIcon="namespace-switcher"
options={namespaceList}
optionValueKey="namespace"
on:change={handleNamespaceSelect}
minSize={32}
actionTooltip={translate('namespaces.go-to-namespace')}
{href}
hrefDisabled={!namespaceExists}
/>
<slot name="left" />
</div>
<div class="flex items-center gap-2">
<TimezoneSelect position={screenWidth < 768 ? 'left' : 'right'} />
Expand Down
62 changes: 62 additions & 0 deletions src/lib/holocene/combobox/async-test.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
<script lang="ts">
// The worst case smallest repro for interacting with combobox async
import Combobox from './combobox.svelte';
let syncOptions = ['one', 'two', 'three'];
let asyncOptions = ['asyncone', 'asynctwo', 'asyncthree'];
let value = '';
let options = syncOptions;
let loading = false;
let abortController: AbortController | null = null;
$: i = 0;
export let id = '';
function keypress(stuff) {
loading = true;
value = stuff.target.value;
options = syncOptions;
// This makes sure the worst case always happens the newest value comes first
// with old values coming after, so we know to discard old values.
i -= 1;
if (abortController) {
abortController.abort();
}
abortController = new AbortController();
const { signal } = abortController;
setTimeout(
(value) => {
if (!signal.aborted) {
console.log('newest options', { value });
options = asyncOptions;
loading = false;
} else {
// console.log("it's old!", { value });
}
},
2000 + i * 100,
value,
);
}
</script>

<Combobox
bind:value
{options}
{keypress}
on:change={(newVal) => {
console.log('change', newVal);
}}
{loading}
{id}
noResultsText="No Results"
label="Async Test"
placeholder="Type away!"
></Combobox>
8 changes: 7 additions & 1 deletion src/lib/holocene/combobox/combobox-option.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,13 @@
>
<slot slot="leading" name="leading">
{#if multiselect}
<Checkbox on:change={() => dispatch('click')} checked={selected} />
<Checkbox
on:change={() => dispatch('click')}
checked={selected}
tabindex={-1}
{label}
labelHidden
/>
{/if}
</slot>
{label}
Expand Down
53 changes: 52 additions & 1 deletion src/lib/holocene/combobox/combobox.stories.svelte
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<script lang="ts" context="module">
import type { Meta } from '@storybook/svelte';
import { expect, userEvent, within } from '@storybook/test';
import { expect, userEvent, waitFor, within } from '@storybook/test';
import Combobox from '$lib/holocene/combobox/combobox.svelte';
import { iconNames } from '$lib/holocene/icon';
Expand Down Expand Up @@ -49,6 +49,8 @@
<script lang="ts">
import { action } from '@storybook/addon-actions';
import { Story, Template } from '@storybook/addon-svelte-csf';
import AsyncTest from './async-test.svelte';
</script>

<Template let:args let:context>
Expand Down Expand Up @@ -132,4 +134,53 @@
multiselect: true,
value: [],
}}
play={async () => {
// re-enable this to get ally errors. Need to come back and resolve this
// DT-2629
// const canvas = within(canvasElement);
// const combobox = canvas.getByTestId(id);
// await userEvent.type(combobox, 'E');
// const menu = canvas.getByRole('listbox');
// expect(menu).toBeInTheDocument();
}}
/>

<Story
name="Async Select"
play={async ({ canvasElement, id, step }) => {
const canvas = within(canvasElement);
const combobox = canvas.getByTestId(id);

await userEvent.type(combobox, 'one');

const menu = canvas.getByRole('listbox');

expect(menu).toBeInTheDocument();

await step('Check async results', async () => {
expect(canvas.getByText('one')).toBeInTheDocument();
expect(canvas.getByText('Loading more results')).toBeInTheDocument();

await waitFor(
() => {
expect(canvas.getByText('asyncone')).toBeInTheDocument();
},
{ timeout: 2001 },
);
});

await step('Get no results', async () => {
await userEvent.type(combobox, 'omgnoresults');
expect(canvas.getByText('Loading more results')).toBeInTheDocument();
waitFor(
() => {
expect(canvas.getByText('No Results')).toBeInTheDocument();
},
{ timeout: 2001 },
);
});
}}
let:context
>
<AsyncTest id={context.id}></AsyncTest>
</Story>
Loading

0 comments on commit 77f4828

Please sign in to comment.