@svadmin/ui 0.34.9 → 0.34.10
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.
- package/dist/component-registry.svelte.js +1 -0
- package/dist/components/AICommandBar.svelte +3 -3
- package/dist/components/AboutSettings.svelte +2 -2
- package/dist/components/AdminApp.svelte +2 -3
- package/dist/components/AnomalyBadge.svelte +1 -1
- package/dist/components/AppearanceSettings.svelte +5 -6
- package/dist/components/AuditLogDrawer.svelte +1 -1
- package/dist/components/AuditLogViewer.svelte +1 -1
- package/dist/components/AutoForm.svelte +5 -4
- package/dist/components/AutoTable.svelte +17 -17
- package/dist/components/Breadcrumbs.svelte +1 -0
- package/dist/components/ChatDialog.svelte +5 -4
- package/dist/components/ComboboxField.svelte +3 -3
- package/dist/components/CommandPalette.svelte +3 -3
- package/dist/components/CopilotPanel.svelte +2 -2
- package/dist/components/CreatePage.svelte +0 -1
- package/dist/components/DevTools.svelte +4 -3
- package/dist/components/DraggableHeader.svelte +2 -1
- package/dist/components/EditPage.svelte +1 -1
- package/dist/components/EmptyState.svelte +1 -1
- package/dist/components/FieldRenderer.svelte +7 -6
- package/dist/components/Header.svelte +1 -0
- package/dist/components/InferencerPanel.svelte +4 -3
- package/dist/components/InfiniteList.svelte +3 -4
- package/dist/components/KeyboardShortcuts.svelte +3 -3
- package/dist/components/Layout.svelte +5 -5
- package/dist/components/MarkdownRenderer.svelte +3 -5
- package/dist/components/ModalForm.svelte +1 -3
- package/dist/components/PageSkeleton.svelte +4 -4
- package/dist/components/PasswordInput.svelte +1 -2
- package/dist/components/PermissionMatrix.svelte +5 -5
- package/dist/components/ProfilePage.svelte +1 -1
- package/dist/components/RolesSettings.svelte +1 -2
- package/dist/components/SettingsPage.svelte +4 -5
- package/dist/components/ShowPage.svelte +4 -6
- package/dist/components/Sidebar.svelte +12 -11
- package/dist/components/SidebarItem.svelte +1 -2
- package/dist/components/StepsForm.svelte +1 -1
- package/dist/components/TaskList.svelte +1 -1
- package/dist/components/TaskQueueDrawer.svelte +2 -1
- package/dist/components/TenantSwitcher.svelte +1 -2
- package/dist/components/Toast.svelte +1 -0
- package/dist/components/TooltipButton.svelte +1 -0
- package/dist/components/VirtualTable.svelte +1 -1
- package/dist/components/VoiceInput.svelte +1 -0
- package/dist/components/buttons/ImportButton.svelte +1 -1
- package/dist/components/buttons/ListButton.svelte +1 -1
- package/dist/components/charts/BarChart.svelte +1 -1
- package/dist/components/charts/LineChart.svelte +3 -3
- package/dist/components/charts/PieChart.svelte +2 -2
- package/dist/components/fieldComponentMap.js +2 -1
- package/dist/components/fields/ArrayField.svelte +1 -1
- package/dist/components/fields/MarkdownField.svelte +1 -0
- package/dist/components/fields/MultiSelectField.svelte +1 -1
- package/dist/components/fields/TagField.svelte +1 -1
- package/dist/components/ui/alert/index.js +1 -0
- package/dist/components/ui/badge/index.js +1 -0
- package/dist/components/ui/button/button.svelte +1 -0
- package/dist/components/ui/button/index.js +1 -0
- package/dist/components/ui/dropdown-menu/dropdown-menu-trigger.svelte +1 -0
- package/dist/components/ui/dropdown-menu/dropdown-menu.svelte +1 -1
- package/dist/components/ui/sheet/sheet.svelte +1 -0
- package/dist/components/ui/tabs/tabs.svelte +1 -0
- package/package.json +13 -13
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
import { toggleTheme } from '@svadmin/core';
|
|
6
6
|
import { Command } from 'cmdk-sv';
|
|
7
7
|
import * as Dialog from './ui/dialog/index.js';
|
|
8
|
-
import { Search, LayoutDashboard, Plus, Sun, FileText, Sparkles, Loader2
|
|
8
|
+
import { Search, LayoutDashboard, Plus, Sun, FileText, Sparkles, Loader2 } from '@lucide/svelte';
|
|
9
9
|
import MarkdownRenderer from './MarkdownRenderer.svelte';
|
|
10
10
|
|
|
11
11
|
let { open = $bindable(false) } = $props<{ open?: boolean }>();
|
|
@@ -124,7 +124,7 @@
|
|
|
124
124
|
<LayoutDashboard class="h-4 w-4 text-muted-foreground" />
|
|
125
125
|
{t('common.home')}
|
|
126
126
|
</Command.Item>
|
|
127
|
-
{#each resources as r}
|
|
127
|
+
{#each resources as r, _i (_i)}
|
|
128
128
|
<Command.Item value={r.name} onSelect={() => act(() => navigate(`/${r.name}`))} class={itemClass}>
|
|
129
129
|
<FileText class="h-4 w-4 text-muted-foreground" />
|
|
130
130
|
{r.label}
|
|
@@ -136,7 +136,7 @@
|
|
|
136
136
|
|
|
137
137
|
<!-- Actions -->
|
|
138
138
|
<Command.Group heading={t('common.actions')}>
|
|
139
|
-
{#each resources as r}
|
|
139
|
+
{#each resources as r, _i (_i)}
|
|
140
140
|
<Command.Item value={`create-${r.name}`} onSelect={() => act(() => navigate(`/${r.name}/create`))} class={itemClass}>
|
|
141
141
|
<Plus class="h-4 w-4 text-muted-foreground" />
|
|
142
142
|
{t('common.create')} {r.label}
|
|
@@ -46,7 +46,7 @@
|
|
|
46
46
|
</Card.CardHeader>
|
|
47
47
|
<Card.CardContent>
|
|
48
48
|
<div class="flex flex-wrap gap-2">
|
|
49
|
-
{#each resources as resource}
|
|
49
|
+
{#each resources as resource, _i (_i)}
|
|
50
50
|
<Badge variant="outline" class="font-mono text-xs">{resource.name}</Badge>
|
|
51
51
|
{/each}
|
|
52
52
|
{#if resources.length === 0}
|
|
@@ -66,7 +66,7 @@
|
|
|
66
66
|
</Card.CardHeader>
|
|
67
67
|
<Card.CardContent>
|
|
68
68
|
<div class="flex flex-wrap gap-2">
|
|
69
|
-
{#each providerNames as name}
|
|
69
|
+
{#each providerNames as name, _i (_i)}
|
|
70
70
|
<Badge variant="outline" class="font-mono text-xs">{name}</Badge>
|
|
71
71
|
{/each}
|
|
72
72
|
</div>
|
|
@@ -3,12 +3,11 @@
|
|
|
3
3
|
import '../app.css';
|
|
4
4
|
import type { Snippet } from 'svelte';
|
|
5
5
|
import type { DataProvider, AuthProvider, ResourceDefinition, ThemeMode, RouterProvider, ThemeConfig, MenuItem, TaskProvider } from '@svadmin/core';
|
|
6
|
-
import { setDataProvider, setAuthProvider, setResources, setLocale, setTheme, setRouterProvider, setTaskProvider,
|
|
6
|
+
import { setDataProvider, setAuthProvider, setResources, setLocale, setTheme, setRouterProvider, setTaskProvider, createHashRouterProvider, configureTheme } from '@svadmin/core';
|
|
7
7
|
import { t } from '@svadmin/core/i18n';
|
|
8
8
|
import { navigate } from '@svadmin/core/router';
|
|
9
|
-
import { currentPath } from '@svadmin/core/router';
|
|
10
9
|
import { QueryClient, QueryClientProvider, type DefaultOptions } from '@tanstack/svelte-query';
|
|
11
|
-
import { setComponentRegistry,
|
|
10
|
+
import { setComponentRegistry, type ComponentRegistry } from '../component-registry.svelte.js';
|
|
12
11
|
import Layout from './Layout.svelte';
|
|
13
12
|
import AutoTable from './AutoTable.svelte';
|
|
14
13
|
import AutoForm from './AutoForm.svelte';
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import { Badge } from './ui/badge/index.js';
|
|
3
|
-
import { TrendingUp, TrendingDown
|
|
3
|
+
import { TrendingUp, TrendingDown } from '@lucide/svelte';
|
|
4
4
|
import TooltipButton from './TooltipButton.svelte';
|
|
5
5
|
|
|
6
6
|
interface Props {
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import { t } from '@svadmin/core/i18n';
|
|
3
|
-
import { getTheme, setTheme,
|
|
3
|
+
import { getTheme, setTheme, getColorTheme, setColorTheme, getColorPresets } from '@svadmin/core';
|
|
4
4
|
import { getLocale, setLocale, getAvailableLocales } from '@svadmin/core/i18n';
|
|
5
5
|
import * as Card from './ui/card/index.js';
|
|
6
|
-
import { Button } from './ui/button/index.js';
|
|
7
6
|
import { Sun, Moon, Monitor, Check } from '@lucide/svelte';
|
|
8
7
|
|
|
9
8
|
// Theme mode
|
|
@@ -67,7 +66,7 @@
|
|
|
67
66
|
</Card.CardHeader>
|
|
68
67
|
<Card.CardContent>
|
|
69
68
|
<div class="grid grid-cols-3 gap-3">
|
|
70
|
-
{#each themeOptions as opt}
|
|
69
|
+
{#each themeOptions as opt, _i (_i)}
|
|
71
70
|
{@const active = currentTheme === opt.value}
|
|
72
71
|
<button
|
|
73
72
|
class="relative flex flex-col items-center gap-2 rounded-xl border-2 p-4 transition-all duration-200
|
|
@@ -101,7 +100,7 @@
|
|
|
101
100
|
</Card.CardHeader>
|
|
102
101
|
<Card.CardContent>
|
|
103
102
|
<div class="flex flex-wrap gap-3">
|
|
104
|
-
{#each presets as preset}
|
|
103
|
+
{#each presets as preset, _i (_i)}
|
|
105
104
|
{@const active = currentColor === preset.name}
|
|
106
105
|
<button
|
|
107
106
|
class="group relative h-9 w-9 rounded-full transition-all duration-200 hover:scale-110
|
|
@@ -137,7 +136,7 @@
|
|
|
137
136
|
value={currentLocale}
|
|
138
137
|
onchange={(e) => setLocale((e.target as HTMLSelectElement).value)}
|
|
139
138
|
>
|
|
140
|
-
{#each availableLocales as loc}
|
|
139
|
+
{#each availableLocales as loc, _i (_i)}
|
|
141
140
|
<option value={loc}>{localeNames[loc] ?? loc}</option>
|
|
142
141
|
{/each}
|
|
143
142
|
</select>
|
|
@@ -172,7 +171,7 @@
|
|
|
172
171
|
<p class="text-sm font-medium text-foreground">{t('settings.defaultPageSize')}</p>
|
|
173
172
|
</div>
|
|
174
173
|
<div class="flex rounded-lg border border-input overflow-hidden">
|
|
175
|
-
{#each pageSizeOptions as size}
|
|
174
|
+
{#each pageSizeOptions as size, _i (_i)}
|
|
176
175
|
<button
|
|
177
176
|
class="px-3 py-1.5 text-xs font-mono font-medium transition-colors
|
|
178
177
|
{pageSize === size ? 'bg-primary text-primary-foreground' : 'bg-background text-muted-foreground hover:bg-accent'}"
|
|
@@ -68,7 +68,7 @@
|
|
|
68
68
|
</div>
|
|
69
69
|
{:else}
|
|
70
70
|
<div class="relative border-l border-border ml-3 pl-6 space-y-8">
|
|
71
|
-
{#each logs as log}
|
|
71
|
+
{#each logs as log, _i (_i)}
|
|
72
72
|
<div class="relative">
|
|
73
73
|
<span class="absolute -left-7 top-1 flex h-2 w-2 items-center justify-center rounded-full ring-4 ring-background {getActionColor(log.action)}"></span>
|
|
74
74
|
<div class="flex flex-col gap-1.5">
|
|
@@ -130,7 +130,7 @@
|
|
|
130
130
|
</Table.Row>
|
|
131
131
|
</Table.Header>
|
|
132
132
|
<Table.Body>
|
|
133
|
-
{#each filteredLogs as log}
|
|
133
|
+
{#each filteredLogs as log, _i (_i)}
|
|
134
134
|
<Table.Row class="border-0 even:bg-muted/20 hover:bg-muted/40 transition-colors">
|
|
135
135
|
<Table.Cell class="text-xs text-muted-foreground font-mono">
|
|
136
136
|
{formatDate(log.createdAt)}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
+
/* eslint-disable svelte/prefer-svelte-reactivity */
|
|
2
3
|
import { useForm, getResource, deriveValidator } from '@svadmin/core';
|
|
3
4
|
import { slide } from 'svelte/transition';
|
|
4
5
|
import type { FieldDefinition } from '@svadmin/core';
|
|
@@ -49,9 +50,9 @@
|
|
|
49
50
|
for (const f of formFields) {
|
|
50
51
|
const g = f.group ?? '';
|
|
51
52
|
if (!map.has(g)) { order.push(g); map.set(g, []); }
|
|
52
|
-
map.get(g)
|
|
53
|
+
(map.get(g) ?? []).push(f);
|
|
53
54
|
}
|
|
54
|
-
return order.map(g => ({ name: g, fields: map.get(g)
|
|
55
|
+
return order.map(g => ({ name: g, fields: map.get(g) ?? [] }));
|
|
55
56
|
})());
|
|
56
57
|
|
|
57
58
|
// ─── Default values from field metadata ───────────────────────────
|
|
@@ -161,7 +162,7 @@
|
|
|
161
162
|
{#if form.loading}
|
|
162
163
|
<div class="max-w-3xl space-y-6">
|
|
163
164
|
<div class="rounded-lg shadow-sm ring-1 ring-border/10 p-6 space-y-5">
|
|
164
|
-
{#each Array(4) as _}
|
|
165
|
+
{#each Array(4) as _, _i (_i)}
|
|
165
166
|
<div class="space-y-2">
|
|
166
167
|
<Skeleton class="h-4 w-24" />
|
|
167
168
|
<Skeleton class="h-10 w-full" />
|
|
@@ -181,7 +182,7 @@
|
|
|
181
182
|
{/if}
|
|
182
183
|
|
|
183
184
|
{#if hasGroups}
|
|
184
|
-
{#each groups as group}
|
|
185
|
+
{#each groups as group, _i (_i)}
|
|
185
186
|
<Card.Root class="border-border/40 shadow-sm">
|
|
186
187
|
{#if group.name}
|
|
187
188
|
<Card.Header>
|
|
@@ -25,7 +25,7 @@
|
|
|
25
25
|
table_toggleAllRowsSelected,
|
|
26
26
|
row_getIsSelected,
|
|
27
27
|
row_toggleSelected,
|
|
28
|
-
|
|
28
|
+
row_getVisibleCells,
|
|
29
29
|
row_getIsExpanded,
|
|
30
30
|
row_toggleExpanded,
|
|
31
31
|
cell_getValue,
|
|
@@ -519,7 +519,7 @@
|
|
|
519
519
|
{/snippet}
|
|
520
520
|
</DropdownMenu.Trigger>
|
|
521
521
|
<DropdownMenu.Content align="end" class="w-48">
|
|
522
|
-
{#each table_getAllLeafColumns(tbl).filter((c: any) => !c.id.startsWith('_')) as column}
|
|
522
|
+
{#each table_getAllLeafColumns(tbl).filter((c: any) => !c.id.startsWith('_')) as column, _i (_i)}
|
|
523
523
|
<DropdownMenu.CheckboxItem
|
|
524
524
|
checked={column_getIsVisible(column)}
|
|
525
525
|
onCheckedChange={(v) => column_toggleVisibility(column, !!v)}
|
|
@@ -571,7 +571,7 @@
|
|
|
571
571
|
<Popover.Content class="w-80">
|
|
572
572
|
<div class="space-y-3">
|
|
573
573
|
<h4 class="font-medium text-sm">{t('common.filter')}</h4>
|
|
574
|
-
{#each filterableFields as field}
|
|
574
|
+
{#each filterableFields as field, _i (_i)}
|
|
575
575
|
<div class="space-y-1">
|
|
576
576
|
<label class="text-xs text-muted-foreground" for="filter-{field.key}">{field.label}</label>
|
|
577
577
|
{#if field.type === 'select' && field.options}
|
|
@@ -582,7 +582,7 @@
|
|
|
582
582
|
onchange={(e) => filterValues[field.key] = (e.currentTarget as HTMLSelectElement).value}
|
|
583
583
|
>
|
|
584
584
|
<option value="">{t('common.all')}</option>
|
|
585
|
-
{#each field.options as opt}
|
|
585
|
+
{#each field.options as opt, _i (_i)}
|
|
586
586
|
<option value={opt.value}>{opt.label}</option>
|
|
587
587
|
{/each}
|
|
588
588
|
</select>
|
|
@@ -620,13 +620,13 @@
|
|
|
620
620
|
{#if query.isLoading}
|
|
621
621
|
<div class="p-4 space-y-3">
|
|
622
622
|
<div class="flex gap-4 mb-2">
|
|
623
|
-
{#each visibleFields.slice(0, 4) as _}
|
|
623
|
+
{#each visibleFields.slice(0, 4) as _, _i (_i)}
|
|
624
624
|
<Skeleton class="h-4 flex-1" />
|
|
625
625
|
{/each}
|
|
626
626
|
</div>
|
|
627
|
-
{#each Array(5) as _}
|
|
627
|
+
{#each Array(5) as _, _i (_i)}
|
|
628
628
|
<div class="flex gap-4">
|
|
629
|
-
{#each visibleFields.slice(0, 4) as __}
|
|
629
|
+
{#each visibleFields.slice(0, 4) as __, _i (_i)}
|
|
630
630
|
<Skeleton class="h-8 flex-1" />
|
|
631
631
|
{/each}
|
|
632
632
|
</div>
|
|
@@ -642,13 +642,13 @@
|
|
|
642
642
|
<div class="hidden md:block">
|
|
643
643
|
<Table.Root>
|
|
644
644
|
<Table.Header>
|
|
645
|
-
{#each table_getHeaderGroups(tbl) as headerGroup}
|
|
645
|
+
{#each table_getHeaderGroups(tbl) as headerGroup, _i (_i)}
|
|
646
646
|
<DraggableHeader
|
|
647
647
|
columns={headerGroup.headers.map((h: any) => ({ id: h.column.id, header: h }))}
|
|
648
648
|
resourceName={resourceName}
|
|
649
649
|
onReorder={(newOrder) => { columnOrder = newOrder.map((c: any) => c.id); }}
|
|
650
650
|
>
|
|
651
|
-
{#snippet header(col,
|
|
651
|
+
{#snippet header(col, _index, dragProps)}
|
|
652
652
|
{@const header = col.header as typeof headerGroup.headers[0]}
|
|
653
653
|
<Table.Head
|
|
654
654
|
{...dragProps}
|
|
@@ -688,14 +688,14 @@
|
|
|
688
688
|
{/each}
|
|
689
689
|
</Table.Header>
|
|
690
690
|
<Table.Body>
|
|
691
|
-
{#each table_getRowModel(tbl).rows as row}
|
|
691
|
+
{#each table_getRowModel(tbl).rows as row, _i (_i)}
|
|
692
692
|
{@const record = row.original}
|
|
693
693
|
{@const id = record[primaryKey] as string | number}
|
|
694
694
|
<ContextMenu.Root>
|
|
695
695
|
<ContextMenu.Trigger>
|
|
696
696
|
{#snippet child({ props })}
|
|
697
697
|
<Table.Row {...props} class="transition-all duration-300 border-b border-border/10 {row_getIsSelected(row) ? 'bg-primary/5' : 'hover:bg-muted/20'}">
|
|
698
|
-
{#each
|
|
698
|
+
{#each row_getVisibleCells(row) as cell, _i (_i)}
|
|
699
699
|
<Table.Cell>
|
|
700
700
|
{#if cell.column.id === '_select'}
|
|
701
701
|
<Checkbox
|
|
@@ -739,7 +739,7 @@
|
|
|
739
739
|
{new Date(cell_getValue(cell) as string).toLocaleDateString()}
|
|
740
740
|
{:else if field?.type === 'tags' && Array.isArray(cell_getValue(cell))}
|
|
741
741
|
<div class="flex flex-wrap gap-1">
|
|
742
|
-
{#each (cell_getValue(cell) as string[]).slice(0, 3) as tag}
|
|
742
|
+
{#each (cell_getValue(cell) as string[]).slice(0, 3) as tag, _i (_i)}
|
|
743
743
|
<Badge variant="secondary">{tag}</Badge>
|
|
744
744
|
{/each}
|
|
745
745
|
</div>
|
|
@@ -787,7 +787,7 @@
|
|
|
787
787
|
</ContextMenu.Root>
|
|
788
788
|
{#if expandedRowRender && row_getIsExpanded(row)}
|
|
789
789
|
<Table.Row class="bg-muted/10 border-b border-border/10 transition-all">
|
|
790
|
-
<Table.Cell colspan={
|
|
790
|
+
<Table.Cell colspan={row_getVisibleCells(row).length}>
|
|
791
791
|
{@render expandedRowRender({ record })}
|
|
792
792
|
</Table.Cell>
|
|
793
793
|
</Table.Row>
|
|
@@ -821,7 +821,7 @@
|
|
|
821
821
|
|
|
822
822
|
<!-- Mobile Card View (visible only on small screens) -->
|
|
823
823
|
<div class="md:hidden space-y-3 p-2">
|
|
824
|
-
{#each table_getRowModel(tbl).rows as row}
|
|
824
|
+
{#each table_getRowModel(tbl).rows as row, _i (_i)}
|
|
825
825
|
{@const record = row.original}
|
|
826
826
|
{@const id = record[primaryKey] as string | number}
|
|
827
827
|
<div
|
|
@@ -860,7 +860,7 @@
|
|
|
860
860
|
</div>
|
|
861
861
|
<!-- Card fields -->
|
|
862
862
|
<div class="space-y-2">
|
|
863
|
-
{#each visibleFields.slice(0, 6) as field}
|
|
863
|
+
{#each visibleFields.slice(0, 6) as field, _i (_i)}
|
|
864
864
|
{@const value = record[field.key]}
|
|
865
865
|
<div class="flex items-start justify-between gap-4">
|
|
866
866
|
<span class="text-xs font-medium text-muted-foreground shrink-0">{field.label}</span>
|
|
@@ -875,7 +875,7 @@
|
|
|
875
875
|
{new Date(value as string).toLocaleDateString()}
|
|
876
876
|
{:else if field.type === 'tags' && Array.isArray(value)}
|
|
877
877
|
<div class="flex flex-wrap gap-1 justify-end">
|
|
878
|
-
{#each (value as string[]).slice(0, 2) as tag}
|
|
878
|
+
{#each (value as string[]).slice(0, 2) as tag, _i (_i)}
|
|
879
879
|
<Badge variant="secondary" class="text-[10px]">{tag}</Badge>
|
|
880
880
|
{/each}
|
|
881
881
|
</div>
|
|
@@ -933,7 +933,7 @@
|
|
|
933
933
|
disabled={currentPage <= 1}
|
|
934
934
|
/>
|
|
935
935
|
</PaginationUI.Item>
|
|
936
|
-
{#each pages as page}
|
|
936
|
+
{#each pages as page, _i (_i)}
|
|
937
937
|
<PaginationUI.Item>
|
|
938
938
|
{#if page === '...'}
|
|
939
939
|
<PaginationUI.Ellipsis />
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
+
/* eslint-disable no-undef, svelte/no-at-html-tags */
|
|
2
3
|
import { getChatProvider, getChatContext, setChatContext, getAgentProvider, registerApproval, resolveApproval } from '@svadmin/core';
|
|
3
|
-
import type { ChatMessage, ChatAction
|
|
4
|
+
import type { ChatMessage, ChatAction } from '@svadmin/core';
|
|
4
5
|
import { t } from '@svadmin/core/i18n';
|
|
5
6
|
import { useParsed } from '@svadmin/core';
|
|
6
7
|
import { fly, fade, scale } from 'svelte/transition';
|
|
7
8
|
import { Button } from './ui/button/index.js';
|
|
8
9
|
import TooltipButton from './TooltipButton.svelte';
|
|
9
|
-
import { MessageCircle, X, Minus, Send, Loader2, Bot, Trash2
|
|
10
|
+
import { MessageCircle, X, Minus, Send, Loader2, Bot, Trash2 } from '@lucide/svelte';
|
|
10
11
|
|
|
11
12
|
interface Props {
|
|
12
13
|
/** localStorage key for chat history persistence. Set to '' to disable. */
|
|
@@ -508,7 +509,7 @@
|
|
|
508
509
|
{t('chat.welcomeDesc') || 'Ask me anything about your admin panel.'}
|
|
509
510
|
</p>
|
|
510
511
|
<div class="flex flex-col gap-2 w-full max-w-[240px]">
|
|
511
|
-
{#each suggestions as suggestion}
|
|
512
|
+
{#each suggestions as suggestion, _i (_i)}
|
|
512
513
|
<button
|
|
513
514
|
class="text-left text-xs px-3 py-2 rounded-lg border border-border hover:bg-accent hover:text-accent-foreground transition-colors cursor-pointer"
|
|
514
515
|
onclick={() => { inputValue = suggestion; }}
|
|
@@ -535,7 +536,7 @@
|
|
|
535
536
|
<!-- Action Buttons -->
|
|
536
537
|
{#if msg.actions && msg.actions.length > 0}
|
|
537
538
|
<div class="flex flex-wrap gap-1.5 mt-2 pt-2 border-t border-border/50">
|
|
538
|
-
{#each msg.actions as action}
|
|
539
|
+
{#each msg.actions as action, _i (_i)}
|
|
539
540
|
<Button
|
|
540
541
|
variant={action.variant ?? 'outline'}
|
|
541
542
|
size="sm"
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
+
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
2
3
|
import { t } from '@svadmin/core/i18n';
|
|
3
4
|
import { useSelect } from '@svadmin/core';
|
|
4
5
|
import type { Filter } from '@svadmin/core';
|
|
5
6
|
import { Button } from './ui/button/index.js';
|
|
6
7
|
import TooltipButton from './TooltipButton.svelte';
|
|
7
|
-
import { Badge } from './ui/badge/index.js';
|
|
8
8
|
import { Command } from 'cmdk-sv';
|
|
9
9
|
import { Skeleton } from './ui/skeleton/index.js';
|
|
10
10
|
import { ChevronsUpDown, Check, X, Search } from '@lucide/svelte';
|
|
@@ -117,11 +117,11 @@
|
|
|
117
117
|
No results.
|
|
118
118
|
</Command.Empty>
|
|
119
119
|
{#if query.isLoading}
|
|
120
|
-
{#each Array(3) as _}
|
|
120
|
+
{#each Array(3) as _, _i (_i)}
|
|
121
121
|
<div class="px-2 py-1.5"><Skeleton class="h-5 w-full" /></div>
|
|
122
122
|
{/each}
|
|
123
123
|
{:else}
|
|
124
|
-
{#each (options as { label: string; value: string | number }[]) ?? [] as opt}
|
|
124
|
+
{#each (options as { label: string; value: string | number }[]) ?? [] as opt, _i (_i)}
|
|
125
125
|
<Command.Item
|
|
126
126
|
value={opt.label}
|
|
127
127
|
onSelect={() => handleSelect(opt.value)}
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
import { toggleTheme } from '@svadmin/core';
|
|
6
6
|
import { Command } from 'cmdk-sv';
|
|
7
7
|
import * as Dialog from './ui/dialog/index.js';
|
|
8
|
-
import { Search, LayoutDashboard, Plus, Sun, FileText,
|
|
8
|
+
import { Search, LayoutDashboard, Plus, Sun, FileText, Sparkles } from '@lucide/svelte';
|
|
9
9
|
|
|
10
10
|
interface Props {
|
|
11
11
|
open?: boolean;
|
|
@@ -93,7 +93,7 @@
|
|
|
93
93
|
<LayoutDashboard class="h-4 w-4 text-muted-foreground" />
|
|
94
94
|
{t('common.home')}
|
|
95
95
|
</Command.Item>
|
|
96
|
-
{#each resources as r}
|
|
96
|
+
{#each resources as r, _i (_i)}
|
|
97
97
|
<Command.Item
|
|
98
98
|
value={r.name}
|
|
99
99
|
onSelect={() => act(() => navigate(`/${r.name}`))}
|
|
@@ -109,7 +109,7 @@
|
|
|
109
109
|
|
|
110
110
|
<!-- Actions -->
|
|
111
111
|
<Command.Group heading={t('common.actions')}>
|
|
112
|
-
{#each resources as r}
|
|
112
|
+
{#each resources as r, _i (_i)}
|
|
113
113
|
<Command.Item
|
|
114
114
|
value={"create-" + r.name}
|
|
115
115
|
onSelect={() => act(() => navigate(`/${r.name}/create`))}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import { getChatProvider, getChatContext } from '@svadmin/core';
|
|
3
|
-
import { Sparkles, X,
|
|
4
|
-
import {
|
|
3
|
+
import { Sparkles, X, Check, RefreshCcw } from '@lucide/svelte';
|
|
4
|
+
import { slide } from 'svelte/transition';
|
|
5
5
|
import { Button } from './ui/button/index.js';
|
|
6
6
|
import MarkdownRenderer from './MarkdownRenderer.svelte';
|
|
7
7
|
import TooltipButton from './TooltipButton.svelte';
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
-
|
|
2
|
+
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
3
|
+
import { fly } from 'svelte/transition';
|
|
3
4
|
import { getResources } from '@svadmin/core';
|
|
4
5
|
import { getTheme, getColorTheme } from '@svadmin/core';
|
|
5
6
|
import { getLocale, t } from '@svadmin/core/i18n';
|
|
6
7
|
import { currentPath } from '@svadmin/core/router';
|
|
7
|
-
import { Button } from './ui/button/index.js';
|
|
8
8
|
import TooltipButton from './TooltipButton.svelte';
|
|
9
9
|
import * as Tabs from './ui/tabs/index.js';
|
|
10
10
|
import { Badge } from './ui/badge/index.js';
|
|
@@ -35,6 +35,7 @@
|
|
|
35
35
|
|
|
36
36
|
// Auto-trace state changes in dev mode via Svelte 5 $inspect
|
|
37
37
|
if ((import.meta as any).env?.DEV) {
|
|
38
|
+
// eslint-disable-next-line svelte/no-inspect
|
|
38
39
|
$inspect({ path, theme, colorTheme, locale, resourceCount: resources.length });
|
|
39
40
|
}
|
|
40
41
|
</script>
|
|
@@ -119,7 +120,7 @@
|
|
|
119
120
|
<!-- Resources -->
|
|
120
121
|
<div class="py-1">
|
|
121
122
|
<h4 class="text-[0.6875rem] font-bold uppercase tracking-widest text-muted-foreground mb-1 px-1">Resources ({resources.length})</h4>
|
|
122
|
-
{#each resources as r}
|
|
123
|
+
{#each resources as r, _i (_i)}
|
|
123
124
|
<div class="flex items-center justify-between px-1 py-0.5 rounded hover:bg-muted/50">
|
|
124
125
|
<span class="text-xs text-foreground">{r.name}</span>
|
|
125
126
|
<Badge variant="outline" class="font-mono text-[0.6875rem]">{r.fields.length} fields</Badge>
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
+
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
2
3
|
/**
|
|
3
4
|
* DraggableHeader — Wraps table header cells with HTML5 Drag and Drop
|
|
4
5
|
* to enable column reorder. Persists order to localStorage.
|
|
@@ -99,7 +100,7 @@
|
|
|
99
100
|
</script>
|
|
100
101
|
|
|
101
102
|
<tr class="hover:bg-muted/50 data-[state=selected]:bg-muted transition-colors bg-muted/50">
|
|
102
|
-
{#each columns as column, index}
|
|
103
|
+
{#each columns as column, index (index)}
|
|
103
104
|
{@render header(column, index, {
|
|
104
105
|
draggable: true,
|
|
105
106
|
ondragstart: (e: DragEvent) => handleDragStart(e, index),
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
<script lang="ts" module>
|
|
2
|
+
/* eslint-disable no-import-assign */
|
|
2
3
|
export type { FieldDefinition } from '@svadmin/core';
|
|
3
4
|
</script>
|
|
4
5
|
|
|
@@ -240,7 +241,7 @@
|
|
|
240
241
|
disabled={disabled}
|
|
241
242
|
>
|
|
242
243
|
<option value="">{t('field.selectPlaceholder')}</option>
|
|
243
|
-
{#each field.options ?? [] as opt}
|
|
244
|
+
{#each field.options ?? [] as opt, _i (_i)}
|
|
244
245
|
<option value={opt.value}>{opt.label}</option>
|
|
245
246
|
{/each}
|
|
246
247
|
</select>
|
|
@@ -253,7 +254,7 @@
|
|
|
253
254
|
{disabled}
|
|
254
255
|
placeholder={t('field.selectPlaceholder')}
|
|
255
256
|
>
|
|
256
|
-
{#each field.options ?? [] as opt}
|
|
257
|
+
{#each field.options ?? [] as opt, _i (_i)}
|
|
257
258
|
<option value={opt.value}>{opt.label}</option>
|
|
258
259
|
{/each}
|
|
259
260
|
</Select>
|
|
@@ -265,7 +266,7 @@
|
|
|
265
266
|
role="group"
|
|
266
267
|
aria-labelledby="label-{field.key}"
|
|
267
268
|
>
|
|
268
|
-
{#each field.options ?? [] as opt}
|
|
269
|
+
{#each field.options ?? [] as opt, _i (_i)}
|
|
269
270
|
<label class="flex items-center gap-2 text-sm cursor-pointer hover:bg-muted/50 rounded px-1 py-0.5 transition-colors">
|
|
270
271
|
<Checkbox
|
|
271
272
|
id={`${field.key}-${opt.value}`}
|
|
@@ -282,7 +283,7 @@
|
|
|
282
283
|
</div>
|
|
283
284
|
{#if multiVal.length > 0}
|
|
284
285
|
<div class="flex flex-wrap gap-1 mt-1">
|
|
285
|
-
{#each multiVal as v}
|
|
286
|
+
{#each multiVal as v, _i (_i)}
|
|
286
287
|
{@const label = field.options?.find((o: { label: string; value: string | number }) => o.value === v)?.label ?? String(v)}
|
|
287
288
|
<Badge variant="secondary" class="gap-1">
|
|
288
289
|
{label}
|
|
@@ -306,7 +307,7 @@
|
|
|
306
307
|
{:else if field.type === 'tags'}
|
|
307
308
|
<div class="space-y-2">
|
|
308
309
|
<div class="flex flex-wrap gap-1.5">
|
|
309
|
-
{#each tagsVal as tag, i}
|
|
310
|
+
{#each tagsVal as tag, i (i)}
|
|
310
311
|
<Badge variant="secondary" class="gap-1">
|
|
311
312
|
{tag}
|
|
312
313
|
<button
|
|
@@ -339,7 +340,7 @@
|
|
|
339
340
|
|
|
340
341
|
{:else if field.type === 'images'}
|
|
341
342
|
<div class="space-y-2">
|
|
342
|
-
{#each imagesVal as url, i}
|
|
343
|
+
{#each imagesVal as url, i (i)}
|
|
343
344
|
<div class="flex items-center gap-2">
|
|
344
345
|
<Input
|
|
345
346
|
id={i === 0 ? field.key : undefined}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
+
|
|
2
3
|
import { getDataProvider, getResources, inferResource } from '@svadmin/core';
|
|
3
4
|
import type { InferResult } from '@svadmin/core';
|
|
4
5
|
import { Button } from './ui/button/index.js';
|
|
@@ -99,7 +100,7 @@
|
|
|
99
100
|
bind:value={selectedResource}
|
|
100
101
|
placeholder="— Select a resource —"
|
|
101
102
|
>
|
|
102
|
-
{#each resources as res}
|
|
103
|
+
{#each resources as res, _i (_i)}
|
|
103
104
|
<option value={res.name}>{res.label} ({res.name})</option>
|
|
104
105
|
{/each}
|
|
105
106
|
</Select>
|
|
@@ -131,7 +132,7 @@
|
|
|
131
132
|
|
|
132
133
|
{#if loading}
|
|
133
134
|
<div class="space-y-2">
|
|
134
|
-
{#each Array(4) as _}
|
|
135
|
+
{#each Array(4) as _, _i (_i)}
|
|
135
136
|
<Skeleton class="h-8 w-full" />
|
|
136
137
|
{/each}
|
|
137
138
|
</div>
|
|
@@ -150,7 +151,7 @@
|
|
|
150
151
|
</Table.Row>
|
|
151
152
|
</Table.Header>
|
|
152
153
|
<Table.Body>
|
|
153
|
-
{#each inferResult.fields as field}
|
|
154
|
+
{#each inferResult.fields as field, _i (_i)}
|
|
154
155
|
<Table.Row>
|
|
155
156
|
<Table.Cell class="font-mono text-xs">{field.key}</Table.Cell>
|
|
156
157
|
<Table.Cell>
|
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
-
import { fade
|
|
2
|
+
import { fade } from 'svelte/transition';
|
|
3
3
|
import { useInfiniteList } from '@svadmin/core';
|
|
4
4
|
import type { BaseRecord, Sort, Filter } from '@svadmin/core';
|
|
5
5
|
import type { Snippet } from 'svelte';
|
|
6
6
|
import { t } from '@svadmin/core/i18n';
|
|
7
7
|
import { Skeleton } from './ui/skeleton/index.js';
|
|
8
|
-
import { Button } from './ui/button/index.js';
|
|
9
8
|
import { Loader2 } from '@lucide/svelte';
|
|
10
9
|
import { intersect } from '../actions.js';
|
|
11
10
|
|
|
@@ -59,7 +58,7 @@
|
|
|
59
58
|
{@render loadingSkeleton()}
|
|
60
59
|
{:else}
|
|
61
60
|
<div class="space-y-3">
|
|
62
|
-
{#each Array(5) as _}
|
|
61
|
+
{#each Array(5) as _, _i (_i)}
|
|
63
62
|
<Skeleton class="h-16 w-full rounded-lg" />
|
|
64
63
|
{/each}
|
|
65
64
|
</div>
|
|
@@ -71,7 +70,7 @@
|
|
|
71
70
|
<p class="text-center text-sm text-muted-foreground py-8">{t('empty.title')}</p>
|
|
72
71
|
{/if}
|
|
73
72
|
{:else}
|
|
74
|
-
{#each allItems as item, index}
|
|
73
|
+
{#each allItems as item, index (index)}
|
|
75
74
|
<div in:fade={{ duration: 200, delay: index < 20 ? index * 30 : 0 }}>
|
|
76
75
|
{@render children({ item, index })}
|
|
77
76
|
</div>
|
|
@@ -39,15 +39,15 @@
|
|
|
39
39
|
<Dialog.Title>{t('common.keyboardShortcuts') || 'Keyboard Shortcuts'}</Dialog.Title>
|
|
40
40
|
</Dialog.Header>
|
|
41
41
|
<div class="space-y-4 py-2">
|
|
42
|
-
{#each shortcuts as group}
|
|
42
|
+
{#each shortcuts as group, _i (_i)}
|
|
43
43
|
<div>
|
|
44
44
|
<h4 class="text-xs font-semibold uppercase tracking-wider text-muted-foreground mb-2">{group.group}</h4>
|
|
45
45
|
<div class="space-y-1.5">
|
|
46
|
-
{#each group.items as shortcut}
|
|
46
|
+
{#each group.items as shortcut, _i (_i)}
|
|
47
47
|
<div class="flex items-center justify-between py-1">
|
|
48
48
|
<span class="text-sm text-foreground">{shortcut.label}</span>
|
|
49
49
|
<div class="flex items-center gap-1">
|
|
50
|
-
{#each shortcut.keys as key}
|
|
50
|
+
{#each shortcut.keys as key, _i (_i)}
|
|
51
51
|
<kbd class="inline-flex h-5 min-w-5 items-center justify-center rounded border bg-muted px-1.5 text-[10px] font-medium font-mono text-muted-foreground">{key}</kbd>
|
|
52
52
|
{/each}
|
|
53
53
|
</div>
|