-
updateEntry(entry, ev.detail)}>
- {#if entry.value.t === 'Address'}
- {
- addSortKeys(String(entry.value.c), event.detail, true);
- }}
- />
- {:else}
-
-
-
- {/if}
-
+
+ updateEntry(entry, ev.detail)}
+ on:resolved={(event) => {
+ addSortKeys(String(entry.value.c), event.detail, true);
+ }}
+ />
{:else}
?
diff --git a/webui/src/lib/components/widgets/Table.svelte b/webui/src/lib/components/widgets/Table.svelte
new file mode 100644
index 0000000..4946950
--- /dev/null
+++ b/webui/src/lib/components/widgets/Table.svelte
@@ -0,0 +1,224 @@
+
+
+
+ {#if !sortedEntities.length}
+
+ {$i18n.t('No entries.')}
+
+ {/if}
+
+ {#each sortedEntities as entity (entity)}
+
+ {#if visible.has(entity)}
+
+ {
+ addSortKeys(entity, event.detail, true);
+ }}
+ />
+
+ {#each currentColumns as attribute}
+ {@const value = values?.getObject(entity)?.get(attribute)}
+ {#if value}
+
+ {:else}
+
X
+ {/if}
+ {/each}
+ {:else}
+
...
+ {/if}
+
+ {/each}
+
+
+
diff --git a/webui/src/lib/util/labels.ts b/webui/src/lib/util/labels.ts
index 6c4376a..9bc7203 100644
--- a/webui/src/lib/util/labels.ts
+++ b/webui/src/lib/util/labels.ts
@@ -2,10 +2,15 @@ import api from '$lib/api';
import { i18n } from '$lib/i18n';
import { derived, readable, type Readable } from 'svelte/store';
import type { AttributeListingResult } from '@upnd/upend/types';
+import debug from 'debug';
+
+const dbg = debug('kestrel:labels');
const databaseAttributeLabels: Readable<{ [key: string]: string }> = readable({}, (set) => {
const result: Record
= {};
+ dbg('Fetching all attributes');
api.fetchAllAttributes().then((attributes: AttributeListingResult) => {
+ dbg('Fetched all attributes: %o', attributes);
attributes.forEach((attribute) => {
if (attribute.labels.length) {
result[attribute.name] = attribute.labels.sort()[0];
diff --git a/webui/src/stories/Table.stories.ts b/webui/src/stories/Table.stories.ts
new file mode 100644
index 0000000..122395c
--- /dev/null
+++ b/webui/src/stories/Table.stories.ts
@@ -0,0 +1,23 @@
+import type { Meta, StoryObj } from '@storybook/svelte';
+import Table from '../lib/components/widgets/Table.svelte';
+import { imageAddress, imageVerticalAddress, videoAddress, videoVerticalAddress } from './common';
+
+const meta: Meta = {
+ title: 'Widgets/Table',
+ component: Table,
+ tags: ['autodocs'],
+ args: {
+ entities: [imageAddress, imageVerticalAddress, videoAddress, videoVerticalAddress]
+ }
+};
+
+export default meta;
+type Story = StoryObj;
+
+export const Default: Story = {};
+
+export const Mixed: Story = {
+ args: {
+ columns: ['MEDIA_DURATION', 'FILE_SIZE']
+ }
+};