windmill-components 1.501.23 → 1.502.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (30) hide show
  1. package/package/components/Dev.svelte +4 -5
  2. package/package/components/apps/components/display/AppCarouselList.svelte +39 -4
  3. package/package/components/apps/editor/appUtils.js +4 -0
  4. package/package/components/apps/editor/componentsPanel/componentControlUtils.js +3 -1
  5. package/package/components/apps/editor/settingsPanel/ComponentPanelDataSource.svelte +0 -1
  6. package/package/components/auditLogs/AuditLogsFilters.svelte +12 -2
  7. package/package/components/auditLogs/AuditLogsTable.svelte +209 -122
  8. package/package/components/auditLogs/AuditLogsTable.svelte.d.ts +5 -20
  9. package/package/components/auditLogs/AuditLogsTimeline.svelte +449 -0
  10. package/package/components/auditLogs/AuditLogsTimeline.svelte.d.ts +16 -0
  11. package/package/components/copilot/chat/AIChatDisplay.svelte +23 -165
  12. package/package/components/copilot/chat/AIChatInput.svelte +128 -0
  13. package/package/components/copilot/chat/AIChatInput.svelte.d.ts +16 -0
  14. package/package/components/copilot/chat/AIChatManager.svelte.d.ts +4 -1
  15. package/package/components/copilot/chat/AIChatManager.svelte.js +33 -13
  16. package/package/components/copilot/chat/AIChatMessage.svelte +93 -0
  17. package/package/components/copilot/chat/AIChatMessage.svelte.d.ts +12 -0
  18. package/package/components/copilot/chat/ContextTextarea.svelte +13 -15
  19. package/package/components/copilot/chat/ContextTextarea.svelte.d.ts +4 -2
  20. package/package/components/copilot/chat/flow/FlowAIChat.svelte +11 -0
  21. package/package/components/copilot/chat/shared.d.ts +13 -3
  22. package/package/components/flow_builder.d.ts +10 -1
  23. package/package/components/graph/FlowGraphV2.svelte +1 -0
  24. package/package/components/schema/EditableSchemaWrapper.svelte +3 -3
  25. package/package/components/search/GlobalSearchModal.svelte +28 -18
  26. package/package/gen/core/OpenAPI.js +1 -1
  27. package/package/gen/schemas.gen.d.ts +11 -2
  28. package/package/gen/schemas.gen.js +11 -2
  29. package/package/gen/types.gen.d.ts +5 -2
  30. package/package.json +2 -1
@@ -441,22 +441,21 @@ let token = $derived($page.url.searchParams.get('wm_token') ?? undefined);
441
441
  let workspace = $derived($page.url.searchParams.get('workspace') ?? undefined);
442
442
  let themeDarkRaw = $derived($page.url.searchParams.get('activeColorTheme'));
443
443
  let themeDark = $derived(themeDarkRaw == '2' || themeDarkRaw == '4');
444
- $effect(() => {
444
+ $effect.pre(() => {
445
445
  if (token) {
446
446
  OpenAPI.WITH_CREDENTIALS = true;
447
447
  OpenAPI.TOKEN = token;
448
- untrack(() => loadUser());
449
448
  }
450
449
  });
451
- $effect(() => {
450
+ $effect.pre(() => {
452
451
  if (workspace) {
453
452
  $workspaceStore = workspace;
454
- untrack(() => setupCopilotInfo());
455
453
  }
456
454
  });
457
- $effect(() => {
455
+ $effect.pre(() => {
458
456
  if (workspace && token) {
459
457
  untrack(() => loadUser());
458
+ untrack(() => setupCopilotInfo());
460
459
  }
461
460
  });
462
461
  $effect(() => {
@@ -1,4 +1,4 @@
1
- <script lang="ts">import { getContext } from 'svelte';
1
+ <script lang="ts">import { getContext, untrack } from 'svelte';
2
2
  import { initConfig, initOutput } from '../../editor/appUtils';
3
3
  import SubGridEditor from '../../editor/SubGridEditor.svelte';
4
4
  import { initCss } from '../../utils';
@@ -13,15 +13,16 @@ import { Button } from '../../../common';
13
13
  import { twMerge } from 'tailwind-merge';
14
14
  import ResolveStyle from '../helpers/ResolveStyle.svelte';
15
15
  let { id, componentInput, configuration, customCss = undefined, render, initializing = $bindable(), componentContainerHeight } = $props();
16
- const { app, focusedGrid, selectedComponent, worldStore, connectingInput } = getContext('AppViewerContext');
16
+ const { app, focusedGrid, selectedComponent, worldStore, connectingInput, componentControl } = getContext('AppViewerContext');
17
17
  let everRender = $state(render);
18
18
  $effect.pre(() => {
19
19
  render && !everRender && (everRender = true);
20
20
  });
21
- const outputs = initOutput($worldStore, id, {
21
+ let outputs = initOutput($worldStore, id, {
22
22
  result: undefined,
23
23
  loading: false,
24
- inputs: {}
24
+ inputs: {},
25
+ currentIndex: 0
25
26
  });
26
27
  const resolvedConfig = $state(initConfig(components['carousellistcomponent'].initialData.configuration, configuration));
27
28
  function onFocus() {
@@ -43,6 +44,40 @@ $effect.pre(() => {
43
44
  });
44
45
  });
45
46
  let currentPageIndex = $state(0);
47
+ // Single update function - ONLY place that calls .set()
48
+ function handleIndexChange() {
49
+ if (outputs?.currentIndex) {
50
+ if (!Array.isArray(result) || result.length === 0) {
51
+ // No data or empty data - reset to 0
52
+ currentPageIndex = 0;
53
+ outputs.currentIndex.set(0);
54
+ }
55
+ else if (currentPageIndex >= result.length) {
56
+ // Current index is out of bounds - reset to 0
57
+ currentPageIndex = 0;
58
+ outputs.currentIndex.set(0);
59
+ }
60
+ else {
61
+ // Valid data and valid current index
62
+ outputs.currentIndex.set(currentPageIndex);
63
+ // Navigate carousel to match the current index
64
+ if (carousel) {
65
+ carousel.goTo(currentPageIndex);
66
+ }
67
+ }
68
+ }
69
+ }
70
+ // Watch for changes and call update function (like working components)
71
+ $effect.pre(() => {
72
+ currentPageIndex != undefined && untrack(() => handleIndexChange());
73
+ });
74
+ $componentControl[id] = {
75
+ setSelectedIndex: (index) => {
76
+ if (Array.isArray(result) && index >= 0 && index < result.length) {
77
+ currentPageIndex = index;
78
+ }
79
+ }
80
+ };
46
81
  </script>
47
82
 
48
83
  {#each Object.keys(components['carousellistcomponent'].initialData.configuration) as key (key)}
@@ -923,6 +923,7 @@ export function isContainer(type) {
923
923
  type === 'horizontalsplitpanescomponent' ||
924
924
  type === 'steppercomponent' ||
925
925
  type === 'listcomponent' ||
926
+ type === 'carousellistcomponent' ||
926
927
  type === 'decisiontreecomponent');
927
928
  }
928
929
  export function subGridIndexKey(type, id, world) {
@@ -938,6 +939,9 @@ export function subGridIndexKey(type, id, world) {
938
939
  case 'steppercomponent': {
939
940
  return world?.outputsById?.[id]?.currentStepIndex?.peak() ?? 0;
940
941
  }
942
+ case 'carousellistcomponent': {
943
+ return world?.outputsById?.[id]?.currentIndex?.peak() ?? 0;
944
+ }
941
945
  case 'decisiontreecomponent': {
942
946
  return world?.outputsById?.[id]?.currentNodeIndex?.peak() ?? 0;
943
947
  }
@@ -25,7 +25,7 @@ const setValue = {
25
25
  };
26
26
  const setSelectedIndex = {
27
27
  title: 'setSelectedIndex',
28
- description: 'Use the setSelectedIndex function to select a row in a table or an AG Grid table.',
28
+ description: 'Use the setSelectedIndex function to select a row in a table, an AG Grid table, or navigate to a slide in a Carousel component.',
29
29
  example: 'setSelectedIndex(id: string, index: number)',
30
30
  documentation: 'https://www.windmill.dev/docs/apps/app-runnable-panel#setselectedindex'
31
31
  };
@@ -70,6 +70,8 @@ export function getComponentControl(type) {
70
70
  return [setTab, setValue, setSelectedIndex];
71
71
  case 'selecttabcomponent':
72
72
  return [setTab, setValue, setSelectedIndex];
73
+ case 'carousellistcomponent':
74
+ return [setSelectedIndex];
73
75
  case 'conditionalwrapper':
74
76
  case 'steppercomponent':
75
77
  return [setTab];
@@ -8,7 +8,6 @@ import ConfirmationModal from '../../../common/confirmationModal/ConfirmationMod
8
8
  import { createChartjsComponentDataset, createPlotlyComponentDataset } from '../appUtils';
9
9
  let { component = $bindable(), children } = $props();
10
10
  let convertToUIEditorCallback = $state(undefined);
11
- console.log('FOOBAR', component.type);
12
11
  let selected = $state((component.type === 'plotlycomponentv2' || component.type === 'chartjscomponentv2') &&
13
12
  component.datasets !== undefined
14
13
  ? 'ui-editor'
@@ -45,6 +45,7 @@ $effect.pre(() => {
45
45
  }
46
46
  });
47
47
  async function loadLogs(username, page, perPage, before, after, operation, resource, actionKind, scope) {
48
+ console.log("loading logs");
48
49
  loading = true;
49
50
  if (username == 'all') {
50
51
  username = undefined;
@@ -73,6 +74,7 @@ async function loadLogs(username, page, perPage, before, after, operation, resou
73
74
  });
74
75
  hasMore = logs.length > 0 && logs.length === perPage;
75
76
  loading = false;
77
+ console.log("loadede logs");
76
78
  }
77
79
  async function loadUsers() {
78
80
  usernames =
@@ -283,24 +285,32 @@ $effect(() => {
283
285
  <span class="text-xs absolute -top-4">After</span>
284
286
  <input type="text" value={after ?? 'After'} disabled />
285
287
  <CalendarPicker
288
+ clearable
286
289
  date={after}
287
290
  placement="bottom-end"
288
291
  label="After"
289
- on:change={async ({ detail }) => {
292
+ on:change={({ detail }) => {
290
293
  after = new Date(detail).toISOString()
291
294
  }}
295
+ on:clear={() => {
296
+ after = undefined
297
+ }}
292
298
  />
293
299
  </div>
294
300
  <div class="flex gap-1 relative w-full">
295
301
  <span class="text-xs absolute -top-4">Before</span>
296
302
  <input type="text" value={before ?? 'Before'} disabled />
297
303
  <CalendarPicker
304
+ clearable
298
305
  bind:date={before}
299
306
  label="Before"
300
307
  placement="bottom-end"
301
- on:change={async ({ detail }) => {
308
+ on:change={({ detail }) => {
302
309
  before = new Date(detail).toISOString()
303
310
  }}
311
+ on:clear={() => {
312
+ before = undefined
313
+ }}
304
314
  />
305
315
  </div>
306
316
 
@@ -1,21 +1,11 @@
1
1
  <script lang="ts">import Badge from '../common/badge/Badge.svelte';
2
- import Cell from '../table/Cell.svelte';
3
- import DataTable from '../table/DataTable.svelte';
4
- import Head from '../table/Head.svelte';
5
- import Row from '../table/Row.svelte';
6
2
  import { displayDate } from '../../utils';
7
- import { createEventDispatcher } from 'svelte';
3
+ import { onMount, tick } from 'svelte';
8
4
  import Button from '../common/button/Button.svelte';
9
- import { ListFilter } from 'lucide-svelte';
10
- export let logs = [];
11
- export let pageIndex = 1;
12
- export let perPage = 100;
13
- export let hasMore = true;
14
- export let actionKind = undefined;
15
- export let operation = undefined;
16
- export let selectedId = undefined;
17
- export let usernameFilter = undefined;
18
- export let resourceFilter = undefined;
5
+ import { ListFilter, ChevronLeft, ChevronRight } from 'lucide-svelte';
6
+ import VirtualList from '@tutorlatin/svelte-tiny-virtual-list';
7
+ import { twMerge } from 'tailwind-merge';
8
+ let { logs = [], pageIndex = $bindable(1), perPage = $bindable(100), hasMore = $bindable(true), actionKind = $bindable(), operation = $bindable(), selectedId = undefined, usernameFilter = $bindable(), resourceFilter = $bindable(), onselect } = $props();
19
9
  function groupLogsByDay(logs) {
20
10
  const groupedLogs = {};
21
11
  if (!logs)
@@ -34,8 +24,39 @@ function groupLogsByDay(logs) {
34
24
  }
35
25
  return groupedLogs;
36
26
  }
37
- const dispatch = createEventDispatcher();
38
- $: groupedLogs = groupLogsByDay(logs);
27
+ function flattenLogs(groupedLogs) {
28
+ const flatLogs = [];
29
+ for (const [date, logsByDay] of Object.entries(groupedLogs)) {
30
+ flatLogs.push({ type: 'date', date });
31
+ for (const log of logsByDay) {
32
+ flatLogs.push({ type: 'log', log });
33
+ }
34
+ }
35
+ return flatLogs;
36
+ }
37
+ let tableHeight = $state(0);
38
+ let headerHeight = $state(0);
39
+ let footerHeight = $state(48);
40
+ function computeHeight() {
41
+ tableHeight =
42
+ document.querySelector('#audit-logs-table-wrapper').parentElement?.clientHeight ?? 0;
43
+ }
44
+ onMount(() => {
45
+ tick().then(computeHeight);
46
+ });
47
+ let groupedLogs = $derived(groupLogsByDay(logs));
48
+ let flatLogs = $derived(groupedLogs ? flattenLogs(groupedLogs) : undefined);
49
+ let stickyIndices = $derived.by(() => {
50
+ const nstickyIndices = [];
51
+ let index = 0;
52
+ for (const entry of flatLogs ?? []) {
53
+ if (entry.type === 'date') {
54
+ nstickyIndices.push(index);
55
+ }
56
+ index++;
57
+ }
58
+ return nstickyIndices;
59
+ });
39
60
  function kindToBadgeColor(kind) {
40
61
  if (kind == 'Execute') {
41
62
  return 'blue';
@@ -53,118 +74,178 @@ function kindToBadgeColor(kind) {
53
74
  }
54
75
  </script>
55
76
 
56
- <DataTable
57
- on:next={() => {
58
- pageIndex = (pageIndex ?? 1) + 1
59
- }}
60
- on:previous={() => {
61
- pageIndex = (pageIndex ?? 1) - 1
62
- }}
63
- currentPage={pageIndex}
64
- paginated
65
- rounded={false}
66
- size="sm"
67
- {hasMore}
68
- bind:perPage
77
+ <svelte:window onresize={() => computeHeight()} />
78
+
79
+ <div
80
+ class="divide-y min-w-[640px] h-full"
81
+ id="audit-logs-table-wrapper"
69
82
  >
70
- <Head>
71
- <Cell first head>ID</Cell>
72
- <Cell head>Timestamp</Cell>
73
- <Cell head>Username</Cell>
74
- <Cell head>Operation</Cell>
75
- <Cell head last>Resource</Cell>
76
- </Head>
77
- {#if logs?.length > 0}
78
- <tbody class="divide-y">
79
- {#each Object.entries(groupedLogs) as [date, logsByDay]}
80
- <tr class="border-t">
81
- <Cell
82
- first
83
- colspan="6"
84
- scope="colgroup"
85
- class="bg-surface-secondary/30 py-2 border-b font-semibold"
86
- >
87
- {date}
88
- </Cell>
89
- </tr>
90
- {#each logsByDay as { id, timestamp, username, operation: op, action_kind, resource, parameters }}
91
- <Row
92
- hoverable
93
- selected={id === selectedId}
94
- on:click={() => {
95
- dispatch('select', id)
96
- }}
97
- >
98
- <Cell first>
99
- {id}
100
- </Cell>
101
- <Cell>
102
- {displayDate(timestamp)}
103
- </Cell>
104
- <Cell>
105
- <div class="flex flex-row gap-2 items-center">
106
- <div class="whitespace-nowrap overflow-x-auto no-scrollbar max-w-52">
107
- {username}
108
- {#if parameters && 'end_user' in parameters}
109
- <span> ({parameters.end_user})</span>
110
- {/if}
83
+
84
+ <div bind:clientHeight={headerHeight}>
85
+ <div
86
+ class="flex flex-row bg-surface-secondary sticky top-0 w-full p-2 pr-4 text-xs font-semibold"
87
+ >
88
+ <div class="w-1/12">ID</div>
89
+ <div class="w-3/12">Timestamp</div>
90
+ <div class="w-3/12">Username</div>
91
+ <div class="w-3/12">Operation</div>
92
+ <div class="w-2/12">Resource</div>
93
+ </div>
94
+ </div>
95
+ {#if logs?.length == 0}
96
+ <div class="text-xs text-secondary p-8"> No logs found for the selected filters. </div>
97
+ {:else}
98
+ <VirtualList
99
+ width="100%"
100
+ height={tableHeight - headerHeight - footerHeight}
101
+ itemCount={flatLogs?.length ?? 0}
102
+ itemSize={42}
103
+ overscanCount={20}
104
+ {stickyIndices}
105
+ scrollToAlignment="center"
106
+ >
107
+ {#snippet header()}{/snippet}
108
+ {#snippet children({ index, style })}
109
+ <div {style} class="w-full">
110
+ {#if flatLogs}
111
+ {@const logOrDate = flatLogs[index]}
112
+
113
+ {#if logOrDate}
114
+ {#if logOrDate?.type === 'date'}
115
+ <div class="bg-surface-secondary py-2 border-b font-semibold text-xs pl-5">
116
+ {logOrDate.date}
111
117
  </div>
112
- <Button
113
- color="light"
114
- size="xs2"
115
- iconOnly
116
- startIcon={{ icon: ListFilter }}
117
- on:click={() => {
118
- usernameFilter = username
118
+ {:else}
119
+ <!-- svelte-ignore a11y_click_events_have_key_events -->
120
+ <!-- svelte-ignore a11y_no_static_element_interactions -->
121
+ <div
122
+ class={twMerge(
123
+ 'flex flex-row items-center h-full w-full px-2 py-1 hover:bg-surface-hover cursor-pointer',
124
+ logOrDate.log.id === selectedId ? 'bg-blue-50 dark:bg-blue-900/50' : ''
125
+ )}
126
+ role="button"
127
+ tabindex="0"
128
+ onclick={() => {
129
+ onselect?.(logOrDate.log.id)
119
130
  }}
120
- />
121
- </div>
122
- </Cell>
123
- <Cell>
124
- <div class="flex flex-row gap-1">
125
- <Badge
126
- on:click={() => {
127
- actionKind = action_kind.toLocaleLowerCase()
128
- }}
129
- color={kindToBadgeColor(action_kind)}>{action_kind}</Badge
130
131
  >
131
- <Badge
132
- on:click={() => {
133
- operation = op
134
- }}
135
- >
136
- {op}
137
- </Badge>
138
- </div>
139
- </Cell>
140
- <Cell last>
141
- <div class="flex flex-row gap-2 items-center">
142
- <div class="whitespace-nowrap overflow-x-auto no-scrollbar w-48">
143
- {resource}
132
+ <div class="w-1/12 text-xs truncate">
133
+ {logOrDate.log.id}
134
+ </div>
135
+ <div class="w-3/12 text-xs">
136
+ {displayDate(logOrDate.log.timestamp)}
137
+ </div>
138
+ <div class="w-3/12 text-xs">
139
+ <div class="flex flex-row gap-2 items-center">
140
+ <div class="whitespace-nowrap overflow-x-auto no-scrollbar max-w-60">
141
+ {logOrDate.log.username}
142
+ {#if logOrDate.log.parameters && 'end_user' in logOrDate.log.parameters}
143
+ <span> ({logOrDate.log.parameters.end_user})</span>
144
+ {/if}
145
+ </div>
146
+ <Button
147
+ color="light"
148
+ size="xs2"
149
+ iconOnly
150
+ startIcon={{ icon: ListFilter }}
151
+ on:click={() => {
152
+ usernameFilter = logOrDate.log.username
153
+ }}
154
+ />
155
+ </div>
156
+ </div>
157
+ <div class="w-3/12 text-xs">
158
+ <div class="flex flex-row gap-1">
159
+ <Badge
160
+ on:click={() => {
161
+ actionKind = logOrDate.log.action_kind.toLocaleLowerCase()
162
+ }}
163
+ color={kindToBadgeColor(logOrDate.log.action_kind)}
164
+ >
165
+ {logOrDate.log.action_kind}
166
+ </Badge>
167
+ <Badge
168
+ on:click={() => {
169
+ operation = logOrDate.log.operation
170
+ }}
171
+ >
172
+ {logOrDate.log.operation}
173
+ </Badge>
174
+ </div>
175
+ </div>
176
+ <div class="w-2/12 text-xs">
177
+ <div class="flex flex-row gap-2 items-center">
178
+ <div class="whitespace-nowrap overflow-x-auto no-scrollbar max-w-60">
179
+ {logOrDate.log.resource}
180
+ </div>
181
+ <Button
182
+ color="light"
183
+ size="xs2"
184
+ iconOnly
185
+ startIcon={{ icon: ListFilter }}
186
+ on:click={() => {
187
+ resourceFilter = logOrDate.log.resource
188
+ }}
189
+ />
190
+ </div>
191
+ </div>
144
192
  </div>
145
- <Button
146
- color="light"
147
- size="xs2"
148
- iconOnly
149
- startIcon={{ icon: ListFilter }}
150
- on:click={() => {
151
- resourceFilter = resource
152
- }}
153
- />
193
+ {/if}
194
+ {:else}
195
+ <div class="flex flex-row items-center h-full w-full px-2">
196
+ <div class="text-xs text-secondary">Loading...</div>
154
197
  </div>
155
- </Cell>
156
- </Row>
157
- {/each}
158
- {/each}
159
- </tbody>
160
- {:else}
161
- <tr>
162
- <td colspan="4" class="text-center py-8">
163
- <div class="text-xs text-secondary"> No logs found for the selected filters. </div>
164
- </td>
165
- </tr>
198
+ {/if}
199
+ {:else}
200
+ <div class="flex flex-row items-center h-full w-full px-2">
201
+ <div class="text-xs text-secondary">Loading...</div>
202
+ </div>
203
+ {/if}
204
+ </div>
205
+ {/snippet}
206
+ {#snippet footer()}{/snippet}
207
+ </VirtualList>
166
208
  {/if}
167
- </DataTable>
209
+ <!-- Pagination footer - always visible -->
210
+ <div class="flex flex-row justify-between items-center p-2 bg-surface-primary border-t">
211
+ <div class="flex flex-row gap-2 items-center">
212
+ <Button
213
+ color="light"
214
+ size="xs2"
215
+ startIcon={{ icon: ChevronLeft }}
216
+ on:click={() => {
217
+ pageIndex = (pageIndex ?? 1) - 1
218
+ }}
219
+ disabled={pageIndex <= 1}
220
+ >
221
+ Previous
222
+ </Button>
223
+ <span class="text-xs text-secondary px-2">Page {pageIndex}</span>
224
+ <Button
225
+ color="light"
226
+ size="xs2"
227
+ endIcon={{ icon: ChevronRight }}
228
+ on:click={() => {
229
+ pageIndex = (pageIndex ?? 1) + 1
230
+ }}
231
+ disabled={!hasMore}
232
+ >
233
+ Next
234
+ </Button>
235
+ </div>
236
+ <div class="flex flex-row gap-2 items-center">
237
+ <span class="text-xs text-secondary">Per page:</span>
238
+ <select
239
+ bind:value={perPage}
240
+ class="text-xs bg-transparent border border-gray-300 dark:border-gray-600 rounded px-2 py-1"
241
+ >
242
+ <option value={25}>25</option>
243
+ <option value={100}>100</option>
244
+ <option value={1000}>1000</option>
245
+ </select>
246
+ </div>
247
+ </div>
248
+ </div>
168
249
 
169
250
  <style>
170
251
  /* Hide scrollbar for Chrome, Safari and Opera */
@@ -176,4 +257,10 @@ function kindToBadgeColor(kind) {
176
257
  .no-scrollbar {
177
258
  -ms-overflow-style: none; /* IE and Edge */
178
259
  scrollbar-width: none; /* Firefox */
260
+ }
261
+
262
+ /* VirtualList scrollbar styling */
263
+ :global(.virtual-list-wrapper:hover::-webkit-scrollbar) {
264
+ width: 8px !important;
265
+ height: 8px !important;
179
266
  }</style>
@@ -1,18 +1,5 @@
1
1
  import type { AuditLog } from '../../gen';
2
- interface $$__sveltets_2_IsomorphicComponent<Props extends Record<string, any> = any, Events extends Record<string, any> = any, Slots extends Record<string, any> = any, Exports = {}, Bindings = string> {
3
- new (options: import('svelte').ComponentConstructorOptions<Props>): import('svelte').SvelteComponent<Props, Events, Slots> & {
4
- $$bindings?: Bindings;
5
- } & Exports;
6
- (internal: unknown, props: Props & {
7
- $$events?: Events;
8
- $$slots?: Slots;
9
- }): Exports & {
10
- $set?: any;
11
- $on?: any;
12
- };
13
- z_$$bindings?: Bindings;
14
- }
15
- declare const AuditLogsTable: $$__sveltets_2_IsomorphicComponent<{
2
+ interface Props {
16
3
  logs?: AuditLog[];
17
4
  pageIndex?: number | undefined;
18
5
  perPage?: number | undefined;
@@ -22,10 +9,8 @@ declare const AuditLogsTable: $$__sveltets_2_IsomorphicComponent<{
22
9
  selectedId?: number | undefined;
23
10
  usernameFilter?: string | undefined;
24
11
  resourceFilter?: string | undefined;
25
- }, {
26
- select: CustomEvent<any>;
27
- } & {
28
- [evt: string]: CustomEvent<any>;
29
- }, {}, {}, string>;
30
- type AuditLogsTable = InstanceType<typeof AuditLogsTable>;
12
+ onselect?: (id: number) => void;
13
+ }
14
+ declare const AuditLogsTable: import("svelte").Component<Props, {}, "operation" | "perPage" | "hasMore" | "pageIndex" | "actionKind" | "usernameFilter" | "resourceFilter">;
15
+ type AuditLogsTable = ReturnType<typeof AuditLogsTable>;
31
16
  export default AuditLogsTable;