@svadmin/lite 0.3.7 → 0.3.12
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/README.md +19 -13
- package/dist/components/LiteAlert.svelte +19 -0
- package/dist/components/LiteAlert.svelte.d.ts +11 -0
- package/dist/components/LiteArrayField.svelte +60 -0
- package/dist/components/LiteArrayField.svelte.d.ts +17 -0
- package/dist/components/LiteArrayItem.svelte +146 -0
- package/dist/components/LiteArrayItem.svelte.d.ts +13 -0
- package/dist/components/LiteAuditLog.svelte +104 -0
- package/dist/components/LiteAuditLog.svelte.d.ts +23 -0
- package/dist/components/LiteBreadcrumbs.svelte +39 -0
- package/dist/components/LiteBreadcrumbs.svelte.d.ts +16 -0
- package/dist/components/LiteChatDialog.svelte +101 -0
- package/dist/components/LiteChatDialog.svelte.d.ts +20 -0
- package/dist/components/LiteConfirmDialog.svelte +60 -0
- package/dist/components/LiteConfirmDialog.svelte.d.ts +22 -0
- package/dist/components/LiteEmptyState.svelte +39 -0
- package/dist/components/LiteEmptyState.svelte.d.ts +16 -0
- package/dist/components/LiteForm.svelte +165 -0
- package/dist/components/LiteForm.svelte.d.ts +26 -0
- package/dist/components/LiteLayout.svelte +147 -0
- package/dist/components/LiteLayout.svelte.d.ts +19 -0
- package/dist/components/LiteLogin.svelte +41 -0
- package/dist/components/LiteLogin.svelte.d.ts +8 -0
- package/dist/components/LitePagination.svelte +73 -0
- package/dist/components/LitePagination.svelte.d.ts +11 -0
- package/dist/components/LitePermissionMatrix.svelte +147 -0
- package/dist/components/LitePermissionMatrix.svelte.d.ts +32 -0
- package/dist/components/LiteSearch.svelte +41 -0
- package/dist/components/LiteSearch.svelte.d.ts +9 -0
- package/dist/components/LiteShow.svelte +61 -0
- package/dist/components/LiteShow.svelte.d.ts +14 -0
- package/dist/components/LiteShowField.svelte +62 -0
- package/dist/components/LiteShowField.svelte.d.ts +12 -0
- package/dist/components/LiteStatsCard.svelte +70 -0
- package/dist/components/LiteStatsCard.svelte.d.ts +24 -0
- package/dist/components/LiteTable.svelte +132 -0
- package/dist/components/LiteTable.svelte.d.ts +19 -0
- package/dist/components/LiteTabs.svelte +57 -0
- package/dist/components/LiteTabs.svelte.d.ts +16 -0
- package/dist/components/advanced/LiteAutoSaveIndicator.svelte +26 -0
- package/dist/components/advanced/LiteAutoSaveIndicator.svelte.d.ts +12 -0
- package/dist/components/advanced/LiteDraggableHeader.svelte +33 -0
- package/dist/components/advanced/LiteDraggableHeader.svelte.d.ts +15 -0
- package/dist/components/advanced/LiteDrawerForm.svelte +42 -0
- package/dist/components/advanced/LiteDrawerForm.svelte.d.ts +16 -0
- package/dist/components/advanced/LiteInlineEdit.svelte +32 -0
- package/dist/components/advanced/LiteInlineEdit.svelte.d.ts +15 -0
- package/dist/components/advanced/LiteModalForm.svelte +44 -0
- package/dist/components/advanced/LiteModalForm.svelte.d.ts +17 -0
- package/dist/components/advanced/LiteToast.svelte +34 -0
- package/dist/components/advanced/LiteToast.svelte.d.ts +14 -0
- package/dist/components/advanced/LiteUndoableNotification.svelte +25 -0
- package/dist/components/advanced/LiteUndoableNotification.svelte.d.ts +13 -0
- package/dist/components/advanced/LiteVirtualTable.svelte +44 -0
- package/dist/components/advanced/LiteVirtualTable.svelte.d.ts +20 -0
- package/dist/components/advanced/index.js +8 -0
- package/dist/components/buttons/LiteCloneButton.svelte +33 -0
- package/dist/components/buttons/LiteCloneButton.svelte.d.ts +11 -0
- package/dist/components/buttons/LiteCreateButton.svelte +31 -0
- package/dist/components/buttons/LiteCreateButton.svelte.d.ts +10 -0
- package/dist/components/buttons/LiteDeleteButton.svelte +57 -0
- package/dist/components/buttons/LiteDeleteButton.svelte.d.ts +12 -0
- package/dist/components/buttons/LiteEditButton.svelte +33 -0
- package/dist/components/buttons/LiteEditButton.svelte.d.ts +11 -0
- package/dist/components/buttons/LiteExportButton.svelte +31 -0
- package/dist/components/buttons/LiteExportButton.svelte.d.ts +10 -0
- package/dist/components/buttons/LiteImportButton.svelte +50 -0
- package/dist/components/buttons/LiteImportButton.svelte.d.ts +10 -0
- package/dist/components/buttons/LiteListButton.svelte +31 -0
- package/dist/components/buttons/LiteListButton.svelte.d.ts +10 -0
- package/dist/components/buttons/LiteRefreshButton.svelte +34 -0
- package/dist/components/buttons/LiteRefreshButton.svelte.d.ts +8 -0
- package/dist/components/buttons/LiteSaveButton.svelte +27 -0
- package/dist/components/buttons/LiteSaveButton.svelte.d.ts +8 -0
- package/dist/components/buttons/LiteShowButton.svelte +33 -0
- package/dist/components/buttons/LiteShowButton.svelte.d.ts +11 -0
- package/dist/components/buttons/index.js +10 -0
- package/dist/components/fields/LiteBooleanField.svelte +42 -0
- package/dist/components/fields/LiteBooleanField.svelte.d.ts +10 -0
- package/dist/components/fields/LiteDateField.svelte +51 -0
- package/dist/components/fields/LiteDateField.svelte.d.ts +10 -0
- package/dist/components/fields/LiteEmailField.svelte +41 -0
- package/dist/components/fields/LiteEmailField.svelte.d.ts +10 -0
- package/dist/components/fields/LiteFileField.svelte +59 -0
- package/dist/components/fields/LiteFileField.svelte.d.ts +10 -0
- package/dist/components/fields/LiteImageField.svelte +57 -0
- package/dist/components/fields/LiteImageField.svelte.d.ts +10 -0
- package/dist/components/fields/LiteJsonField.svelte +43 -0
- package/dist/components/fields/LiteJsonField.svelte.d.ts +10 -0
- package/dist/components/fields/LiteMarkdownField.svelte +33 -0
- package/dist/components/fields/LiteMarkdownField.svelte.d.ts +10 -0
- package/dist/components/fields/LiteMultiSelectField.svelte +57 -0
- package/dist/components/fields/LiteMultiSelectField.svelte.d.ts +10 -0
- package/dist/components/fields/LiteNumberField.svelte +35 -0
- package/dist/components/fields/LiteNumberField.svelte.d.ts +10 -0
- package/dist/components/fields/LiteRelationField.svelte +67 -0
- package/dist/components/fields/LiteRelationField.svelte.d.ts +10 -0
- package/dist/components/fields/LiteRichTextField.svelte +44 -0
- package/dist/components/fields/LiteRichTextField.svelte.d.ts +10 -0
- package/dist/components/fields/LiteSelectField.svelte +47 -0
- package/dist/components/fields/LiteSelectField.svelte.d.ts +10 -0
- package/dist/components/fields/LiteTagField.svelte +44 -0
- package/dist/components/fields/LiteTagField.svelte.d.ts +10 -0
- package/dist/components/fields/LiteTextField.svelte +35 -0
- package/dist/components/fields/LiteTextField.svelte.d.ts +10 -0
- package/dist/components/fields/LiteUrlField.svelte +52 -0
- package/dist/components/fields/LiteUrlField.svelte.d.ts +10 -0
- package/dist/components/fields/index.js +15 -0
- package/dist/components/layout/LiteAuthenticated.svelte +23 -0
- package/dist/components/layout/LiteAuthenticated.svelte.d.ts +10 -0
- package/dist/components/layout/LiteCanAccess.svelte +27 -0
- package/dist/components/layout/LiteCanAccess.svelte.d.ts +10 -0
- package/dist/components/layout/LiteCatchAllNavigate.svelte +20 -0
- package/dist/components/layout/LiteCatchAllNavigate.svelte.d.ts +7 -0
- package/dist/components/layout/LiteErrorBoundary.svelte +20 -0
- package/dist/components/layout/LiteErrorBoundary.svelte.d.ts +13 -0
- package/dist/components/layout/LiteErrorComponent.svelte +37 -0
- package/dist/components/layout/LiteErrorComponent.svelte.d.ts +9 -0
- package/dist/components/layout/LiteHeader.svelte +19 -0
- package/dist/components/layout/LiteHeader.svelte.d.ts +8 -0
- package/dist/components/layout/LiteNavigateToResource.svelte +25 -0
- package/dist/components/layout/LiteNavigateToResource.svelte.d.ts +7 -0
- package/dist/components/layout/LiteSidebar.svelte +93 -0
- package/dist/components/layout/LiteSidebar.svelte.d.ts +12 -0
- package/dist/components/layout/index.js +8 -0
- package/dist/components/pages/LiteCreatePage.svelte +39 -0
- package/dist/components/pages/LiteCreatePage.svelte.d.ts +10 -0
- package/dist/components/pages/LiteEditPage.svelte +54 -0
- package/dist/components/pages/LiteEditPage.svelte.d.ts +12 -0
- package/dist/components/pages/LiteForgotPasswordPage.svelte +60 -0
- package/dist/components/pages/LiteForgotPasswordPage.svelte.d.ts +11 -0
- package/dist/components/pages/LiteListPage.svelte +81 -0
- package/dist/components/pages/LiteListPage.svelte.d.ts +20 -0
- package/dist/components/pages/LiteProfilePage.svelte +61 -0
- package/dist/components/pages/LiteProfilePage.svelte.d.ts +14 -0
- package/dist/components/pages/LiteRegisterPage.svelte +63 -0
- package/dist/components/pages/LiteRegisterPage.svelte.d.ts +10 -0
- package/dist/components/pages/LiteShowPage.svelte +61 -0
- package/dist/components/pages/LiteShowPage.svelte.d.ts +11 -0
- package/dist/components/pages/LiteUpdatePasswordPage.svelte +51 -0
- package/dist/components/pages/LiteUpdatePasswordPage.svelte.d.ts +9 -0
- package/dist/components/pages/index.js +8 -0
- package/dist/components/widgets/LiteAnomalyBadge.svelte +40 -0
- package/dist/components/widgets/LiteAnomalyBadge.svelte.d.ts +15 -0
- package/dist/components/widgets/LiteBarChart.svelte +45 -0
- package/dist/components/widgets/LiteBarChart.svelte.d.ts +17 -0
- package/dist/components/widgets/LiteInsightCard.svelte +31 -0
- package/dist/components/widgets/LiteInsightCard.svelte.d.ts +13 -0
- package/dist/components/widgets/LiteLineChart.svelte +48 -0
- package/dist/components/widgets/LiteLineChart.svelte.d.ts +17 -0
- package/dist/components/widgets/LitePieChart.svelte +44 -0
- package/dist/components/widgets/LitePieChart.svelte.d.ts +17 -0
- package/dist/components/widgets/index.js +5 -0
- package/dist/enhance.js +112 -0
- package/dist/index.d.ts +27 -0
- package/{src/index.ts → dist/index.js} +3 -26
- package/dist/lite.css +817 -0
- package/dist/schema-generator.d.ts +29 -0
- package/dist/schema-generator.js +226 -0
- package/dist/security.d.ts +14 -0
- package/dist/security.js +59 -0
- package/dist/server-adapter.d.ts +111 -0
- package/dist/server-adapter.js +422 -0
- package/package.json +57 -20
- package/src/schema-generator.ts +0 -147
- package/src/server-adapter.ts +0 -307
- /package/{src/components/advanced/index.ts → dist/components/advanced/index.d.ts} +0 -0
- /package/{src/components/buttons/index.ts → dist/components/buttons/index.d.ts} +0 -0
- /package/{src/components/fields/index.ts → dist/components/fields/index.d.ts} +0 -0
- /package/{src/components/layout/index.ts → dist/components/layout/index.d.ts} +0 -0
- /package/{src/components/pages/index.ts → dist/components/pages/index.d.ts} +0 -0
- /package/{src/components/widgets/index.ts → dist/components/widgets/index.d.ts} +0 -0
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* LiteTabs — SSR-compatible tab navigation.
|
|
3
|
+
* Uses simple <a> tags and flexbox. No JS required.
|
|
4
|
+
*/
|
|
5
|
+
interface TabItem {
|
|
6
|
+
label: string;
|
|
7
|
+
value: string;
|
|
8
|
+
href: string;
|
|
9
|
+
}
|
|
10
|
+
interface Props {
|
|
11
|
+
items: TabItem[];
|
|
12
|
+
activeValue: string;
|
|
13
|
+
}
|
|
14
|
+
declare const LiteTabs: import("svelte").Component<Props, {}, "">;
|
|
15
|
+
type LiteTabs = ReturnType<typeof LiteTabs>;
|
|
16
|
+
export default LiteTabs;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
/**
|
|
3
|
+
* SSR AutoSaveIndicator — Degraded to a static status label.
|
|
4
|
+
* Without JS, there is no auto-save. This component simply renders
|
|
5
|
+
* the last known save status passed from the server.
|
|
6
|
+
*/
|
|
7
|
+
interface Props {
|
|
8
|
+
status?: 'idle' | 'saved' | 'error';
|
|
9
|
+
message?: string;
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
let { status = 'idle', message }: Props = $props();
|
|
13
|
+
|
|
14
|
+
const statusConfig: Record<string, { icon: string; color: string; text: string }> = {
|
|
15
|
+
idle: { icon: '☁', color: '#64748b', text: 'All changes saved' },
|
|
16
|
+
saved: { icon: '✓', color: '#10b981', text: 'Saved' },
|
|
17
|
+
error: { icon: '✕', color: '#ef4444', text: 'Save failed' },
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
const cfg = $derived(statusConfig[status] ?? statusConfig.idle);
|
|
21
|
+
</script>
|
|
22
|
+
|
|
23
|
+
<span style="display: inline-flex; align-items: center; gap: 6px; font-size: 13px; color: {cfg.color};">
|
|
24
|
+
<span>{cfg.icon}</span>
|
|
25
|
+
<span>{message ?? cfg.text}</span>
|
|
26
|
+
</span>
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SSR AutoSaveIndicator — Degraded to a static status label.
|
|
3
|
+
* Without JS, there is no auto-save. This component simply renders
|
|
4
|
+
* the last known save status passed from the server.
|
|
5
|
+
*/
|
|
6
|
+
interface Props {
|
|
7
|
+
status?: 'idle' | 'saved' | 'error';
|
|
8
|
+
message?: string;
|
|
9
|
+
}
|
|
10
|
+
declare const LiteAutoSaveIndicator: import("svelte").Component<Props, {}, "">;
|
|
11
|
+
type LiteAutoSaveIndicator = ReturnType<typeof LiteAutoSaveIndicator>;
|
|
12
|
+
export default LiteAutoSaveIndicator;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
/**
|
|
3
|
+
* SSR DraggableHeader — Degraded to a static table header.
|
|
4
|
+
* Column dragging/resizing requires JS mouse/touch events.
|
|
5
|
+
* In lite mode, columns are rendered at natural widths.
|
|
6
|
+
* Sort is achieved via URL query parameters as in LiteTable.
|
|
7
|
+
*/
|
|
8
|
+
import type { FieldDefinition } from '@svadmin/core';
|
|
9
|
+
|
|
10
|
+
interface Props {
|
|
11
|
+
fields: FieldDefinition[];
|
|
12
|
+
currentSort?: string;
|
|
13
|
+
currentOrder?: 'asc' | 'desc';
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
let { fields, currentSort, currentOrder = 'asc' }: Props = $props();
|
|
17
|
+
</script>
|
|
18
|
+
|
|
19
|
+
<tr>
|
|
20
|
+
{#each fields as field, _i (_i)}
|
|
21
|
+
<th style="padding: 10px 12px; text-align: left; font-weight: 600; font-size: 13px; color: #475569; white-space: nowrap;">
|
|
22
|
+
{#if currentSort === field.key}
|
|
23
|
+
<a href="?sort={field.key}&order={currentOrder === 'asc' ? 'desc' : 'asc'}" style="color: #0f172a; text-decoration: none;">
|
|
24
|
+
{field.label} {currentOrder === 'asc' ? '↑' : '↓'}
|
|
25
|
+
</a>
|
|
26
|
+
{:else}
|
|
27
|
+
<a href="?sort={field.key}&order=asc" style="color: inherit; text-decoration: none;">
|
|
28
|
+
{field.label}
|
|
29
|
+
</a>
|
|
30
|
+
{/if}
|
|
31
|
+
</th>
|
|
32
|
+
{/each}
|
|
33
|
+
</tr>
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SSR DraggableHeader — Degraded to a static table header.
|
|
3
|
+
* Column dragging/resizing requires JS mouse/touch events.
|
|
4
|
+
* In lite mode, columns are rendered at natural widths.
|
|
5
|
+
* Sort is achieved via URL query parameters as in LiteTable.
|
|
6
|
+
*/
|
|
7
|
+
import type { FieldDefinition } from '@svadmin/core';
|
|
8
|
+
interface Props {
|
|
9
|
+
fields: FieldDefinition[];
|
|
10
|
+
currentSort?: string;
|
|
11
|
+
currentOrder?: 'asc' | 'desc';
|
|
12
|
+
}
|
|
13
|
+
declare const LiteDraggableHeader: import("svelte").Component<Props, {}, "">;
|
|
14
|
+
type LiteDraggableHeader = ReturnType<typeof LiteDraggableHeader>;
|
|
15
|
+
export default LiteDraggableHeader;
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
/**
|
|
3
|
+
* SSR DrawerForm — Degraded to a dedicated page redirect.
|
|
4
|
+
* Side drawers require JS for sliding panel rendering. In lite mode,
|
|
5
|
+
* this component works identically to LiteModalForm: a plain link.
|
|
6
|
+
*/
|
|
7
|
+
import type { ResourceDefinition } from '@svadmin/core';
|
|
8
|
+
import { t } from '@svadmin/core/i18n';
|
|
9
|
+
|
|
10
|
+
interface Props {
|
|
11
|
+
resource: ResourceDefinition;
|
|
12
|
+
mode?: 'create' | 'edit';
|
|
13
|
+
recordId?: string | number;
|
|
14
|
+
basePath?: string;
|
|
15
|
+
label?: string;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
let {
|
|
19
|
+
resource,
|
|
20
|
+
mode = 'create',
|
|
21
|
+
recordId,
|
|
22
|
+
basePath = '/lite',
|
|
23
|
+
label,
|
|
24
|
+
}: Props = $props();
|
|
25
|
+
|
|
26
|
+
const href = $derived(
|
|
27
|
+
mode === 'create'
|
|
28
|
+
? `${basePath}/${resource.name}/create`
|
|
29
|
+
: `${basePath}/${resource.name}/edit/${recordId}`
|
|
30
|
+
);
|
|
31
|
+
|
|
32
|
+
const buttonLabel = $derived(
|
|
33
|
+
label ??
|
|
34
|
+
(mode === 'create'
|
|
35
|
+
? `${t('common.create') || 'Create'} ${resource.label || resource.name}`
|
|
36
|
+
: `${t('common.edit') || 'Edit'} ${resource.label || resource.name}`)
|
|
37
|
+
);
|
|
38
|
+
</script>
|
|
39
|
+
|
|
40
|
+
<a href={href} class="lite-btn lite-btn-outline">
|
|
41
|
+
{buttonLabel}
|
|
42
|
+
</a>
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SSR DrawerForm — Degraded to a dedicated page redirect.
|
|
3
|
+
* Side drawers require JS for sliding panel rendering. In lite mode,
|
|
4
|
+
* this component works identically to LiteModalForm: a plain link.
|
|
5
|
+
*/
|
|
6
|
+
import type { ResourceDefinition } from '@svadmin/core';
|
|
7
|
+
interface Props {
|
|
8
|
+
resource: ResourceDefinition;
|
|
9
|
+
mode?: 'create' | 'edit';
|
|
10
|
+
recordId?: string | number;
|
|
11
|
+
basePath?: string;
|
|
12
|
+
label?: string;
|
|
13
|
+
}
|
|
14
|
+
declare const LiteDrawerForm: import("svelte").Component<Props, {}, "">;
|
|
15
|
+
type LiteDrawerForm = ReturnType<typeof LiteDrawerForm>;
|
|
16
|
+
export default LiteDrawerForm;
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
/**
|
|
3
|
+
* SSR InlineEdit — Degraded to a show-value + edit-link pattern.
|
|
4
|
+
* True inline editing requires JS for focus management, key events,
|
|
5
|
+
* and async save. In lite mode, we display the value as static text
|
|
6
|
+
* and provide a small "edit" link that navigates to the edit page.
|
|
7
|
+
*/
|
|
8
|
+
import type { FieldDefinition } from '@svadmin/core';
|
|
9
|
+
|
|
10
|
+
interface Props {
|
|
11
|
+
field: FieldDefinition;
|
|
12
|
+
value: unknown;
|
|
13
|
+
editUrl?: string;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
let { field, value, editUrl }: Props = $props();
|
|
17
|
+
|
|
18
|
+
const displayValue = $derived(
|
|
19
|
+
value == null ? '—' : String(value)
|
|
20
|
+
);
|
|
21
|
+
</script>
|
|
22
|
+
|
|
23
|
+
<span style="display: inline-flex; align-items: center; gap: 6px;">
|
|
24
|
+
<span>{displayValue}</span>
|
|
25
|
+
{#if editUrl}
|
|
26
|
+
<a
|
|
27
|
+
href={editUrl}
|
|
28
|
+
style="font-size: 11px; color: #6366f1; text-decoration: none;"
|
|
29
|
+
title="Edit {field.label}"
|
|
30
|
+
>✎</a>
|
|
31
|
+
{/if}
|
|
32
|
+
</span>
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SSR InlineEdit — Degraded to a show-value + edit-link pattern.
|
|
3
|
+
* True inline editing requires JS for focus management, key events,
|
|
4
|
+
* and async save. In lite mode, we display the value as static text
|
|
5
|
+
* and provide a small "edit" link that navigates to the edit page.
|
|
6
|
+
*/
|
|
7
|
+
import type { FieldDefinition } from '@svadmin/core';
|
|
8
|
+
interface Props {
|
|
9
|
+
field: FieldDefinition;
|
|
10
|
+
value: unknown;
|
|
11
|
+
editUrl?: string;
|
|
12
|
+
}
|
|
13
|
+
declare const LiteInlineEdit: import("svelte").Component<Props, {}, "">;
|
|
14
|
+
type LiteInlineEdit = ReturnType<typeof LiteInlineEdit>;
|
|
15
|
+
export default LiteInlineEdit;
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
/**
|
|
3
|
+
* SSR ModalForm — Degraded to a dedicated page redirect.
|
|
4
|
+
* True modals require JS for overlay rendering. In lite mode,
|
|
5
|
+
* this component simply renders a link that navigates to the
|
|
6
|
+
* create/edit page for the resource (a full page load).
|
|
7
|
+
*/
|
|
8
|
+
import type { ResourceDefinition } from '@svadmin/core';
|
|
9
|
+
import { t } from '@svadmin/core/i18n';
|
|
10
|
+
|
|
11
|
+
interface Props {
|
|
12
|
+
resource: ResourceDefinition;
|
|
13
|
+
mode?: 'create' | 'edit';
|
|
14
|
+
recordId?: string | number;
|
|
15
|
+
basePath?: string;
|
|
16
|
+
label?: string;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
let {
|
|
20
|
+
resource,
|
|
21
|
+
mode = 'create',
|
|
22
|
+
recordId,
|
|
23
|
+
basePath = '/lite',
|
|
24
|
+
label,
|
|
25
|
+
}: Props = $props();
|
|
26
|
+
|
|
27
|
+
const href = $derived(
|
|
28
|
+
mode === 'create'
|
|
29
|
+
? `${basePath}/${resource.name}/create`
|
|
30
|
+
: `${basePath}/${resource.name}/edit/${recordId}`
|
|
31
|
+
);
|
|
32
|
+
|
|
33
|
+
const buttonLabel = $derived(
|
|
34
|
+
label ??
|
|
35
|
+
(mode === 'create'
|
|
36
|
+
? `${t('common.create') || 'Create'} ${resource.label || resource.name}`
|
|
37
|
+
: `${t('common.edit') || 'Edit'} ${resource.label || resource.name}`)
|
|
38
|
+
);
|
|
39
|
+
</script>
|
|
40
|
+
|
|
41
|
+
<!-- In lite mode, modals degrade to a full-page navigation -->
|
|
42
|
+
<a href={href} class="lite-btn lite-btn-primary">
|
|
43
|
+
{buttonLabel}
|
|
44
|
+
</a>
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SSR ModalForm — Degraded to a dedicated page redirect.
|
|
3
|
+
* True modals require JS for overlay rendering. In lite mode,
|
|
4
|
+
* this component simply renders a link that navigates to the
|
|
5
|
+
* create/edit page for the resource (a full page load).
|
|
6
|
+
*/
|
|
7
|
+
import type { ResourceDefinition } from '@svadmin/core';
|
|
8
|
+
interface Props {
|
|
9
|
+
resource: ResourceDefinition;
|
|
10
|
+
mode?: 'create' | 'edit';
|
|
11
|
+
recordId?: string | number;
|
|
12
|
+
basePath?: string;
|
|
13
|
+
label?: string;
|
|
14
|
+
}
|
|
15
|
+
declare const LiteModalForm: import("svelte").Component<Props, {}, "">;
|
|
16
|
+
type LiteModalForm = ReturnType<typeof LiteModalForm>;
|
|
17
|
+
export default LiteModalForm;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
/**
|
|
3
|
+
* SSR Toast — Degraded to a static alert banner.
|
|
4
|
+
* In SSR-only mode, toast notifications are rendered as inline banners
|
|
5
|
+
* by the server and included in the page HTML. They persist until the
|
|
6
|
+
* next full-page navigation (no auto-dismiss without JS).
|
|
7
|
+
*/
|
|
8
|
+
interface Props {
|
|
9
|
+
message: string;
|
|
10
|
+
type?: 'success' | 'error' | 'warning' | 'info';
|
|
11
|
+
dismissUrl?: string;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
let { message, type = 'info', dismissUrl }: Props = $props();
|
|
15
|
+
|
|
16
|
+
const colors: Record<string, { bg: string; border: string; text: string }> = {
|
|
17
|
+
success: { bg: '#ecfdf5', border: '#a7f3d0', text: '#065f46' },
|
|
18
|
+
error: { bg: '#fef2f2', border: '#fecaca', text: '#991b1b' },
|
|
19
|
+
warning: { bg: '#fffbeb', border: '#fed7aa', text: '#92400e' },
|
|
20
|
+
info: { bg: '#eff6ff', border: '#bfdbfe', text: '#1e40af' },
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
const style = $derived(colors[type] ?? colors.info);
|
|
24
|
+
</script>
|
|
25
|
+
|
|
26
|
+
<div
|
|
27
|
+
role="alert"
|
|
28
|
+
style="padding: 12px 16px; background: {style.bg}; border: 1px solid {style.border}; color: {style.text}; border-radius: 6px; margin-bottom: 16px; display: flex; justify-content: space-between; align-items: center; font-size: 14px;"
|
|
29
|
+
>
|
|
30
|
+
<span>{message}</span>
|
|
31
|
+
{#if dismissUrl}
|
|
32
|
+
<a href={dismissUrl} style="color: {style.text}; text-decoration: none; font-weight: 600; margin-left: 12px;">✕</a>
|
|
33
|
+
{/if}
|
|
34
|
+
</div>
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SSR Toast — Degraded to a static alert banner.
|
|
3
|
+
* In SSR-only mode, toast notifications are rendered as inline banners
|
|
4
|
+
* by the server and included in the page HTML. They persist until the
|
|
5
|
+
* next full-page navigation (no auto-dismiss without JS).
|
|
6
|
+
*/
|
|
7
|
+
interface Props {
|
|
8
|
+
message: string;
|
|
9
|
+
type?: 'success' | 'error' | 'warning' | 'info';
|
|
10
|
+
dismissUrl?: string;
|
|
11
|
+
}
|
|
12
|
+
declare const LiteToast: import("svelte").Component<Props, {}, "">;
|
|
13
|
+
type LiteToast = ReturnType<typeof LiteToast>;
|
|
14
|
+
export default LiteToast;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
/**
|
|
3
|
+
* SSR UndoableNotification — Degraded to a static banner with an undo link.
|
|
4
|
+
* Without JS there's no countdown timer. Instead, the server provides an
|
|
5
|
+
* undo URL that performs the reversal action. If the user navigates away,
|
|
6
|
+
* the action is considered confirmed.
|
|
7
|
+
*/
|
|
8
|
+
interface Props {
|
|
9
|
+
message: string;
|
|
10
|
+
undoUrl: string;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
let { message, undoUrl }: Props = $props();
|
|
14
|
+
</script>
|
|
15
|
+
|
|
16
|
+
<div
|
|
17
|
+
role="alert"
|
|
18
|
+
style="padding: 12px 16px; background: #fefce8; border: 1px solid #fde68a; color: #713f12; border-radius: 6px; margin-bottom: 16px; display: flex; justify-content: space-between; align-items: center; font-size: 14px;"
|
|
19
|
+
>
|
|
20
|
+
<span>{message}</span>
|
|
21
|
+
<a
|
|
22
|
+
href={undoUrl}
|
|
23
|
+
style="color: #b45309; font-weight: 600; text-decoration: underline; margin-left: 16px; white-space: nowrap;"
|
|
24
|
+
>Undo</a>
|
|
25
|
+
</div>
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SSR UndoableNotification — Degraded to a static banner with an undo link.
|
|
3
|
+
* Without JS there's no countdown timer. Instead, the server provides an
|
|
4
|
+
* undo URL that performs the reversal action. If the user navigates away,
|
|
5
|
+
* the action is considered confirmed.
|
|
6
|
+
*/
|
|
7
|
+
interface Props {
|
|
8
|
+
message: string;
|
|
9
|
+
undoUrl: string;
|
|
10
|
+
}
|
|
11
|
+
declare const LiteUndoableNotification: import("svelte").Component<Props, {}, "">;
|
|
12
|
+
type LiteUndoableNotification = ReturnType<typeof LiteUndoableNotification>;
|
|
13
|
+
export default LiteUndoableNotification;
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
/**
|
|
3
|
+
* SSR VirtualTable — Identical to LiteTable.
|
|
4
|
+
* Virtual scrolling (rendering only visible rows) requires JS.
|
|
5
|
+
* In lite mode, all rows are rendered server-side. For large datasets,
|
|
6
|
+
* rely on server-side pagination instead.
|
|
7
|
+
*/
|
|
8
|
+
import type { ResourceDefinition } from '@svadmin/core';
|
|
9
|
+
import LiteTable from '../LiteTable.svelte';
|
|
10
|
+
|
|
11
|
+
interface Props {
|
|
12
|
+
records: Record<string, unknown>[];
|
|
13
|
+
resource: ResourceDefinition;
|
|
14
|
+
currentSort?: string;
|
|
15
|
+
currentOrder?: 'asc' | 'desc';
|
|
16
|
+
currentSearch?: string;
|
|
17
|
+
basePath?: string;
|
|
18
|
+
canEdit?: boolean;
|
|
19
|
+
canDelete?: boolean;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
let {
|
|
23
|
+
records,
|
|
24
|
+
resource,
|
|
25
|
+
currentSort,
|
|
26
|
+
currentOrder = 'asc',
|
|
27
|
+
currentSearch,
|
|
28
|
+
basePath = '/lite',
|
|
29
|
+
canEdit = true,
|
|
30
|
+
canDelete = true,
|
|
31
|
+
}: Props = $props();
|
|
32
|
+
</script>
|
|
33
|
+
|
|
34
|
+
<!-- Virtual scrolling is not available without JS. All rows are rendered. -->
|
|
35
|
+
<LiteTable
|
|
36
|
+
{records}
|
|
37
|
+
{resource}
|
|
38
|
+
{currentSort}
|
|
39
|
+
{currentOrder}
|
|
40
|
+
{currentSearch}
|
|
41
|
+
{basePath}
|
|
42
|
+
{canEdit}
|
|
43
|
+
{canDelete}
|
|
44
|
+
/>
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* SSR VirtualTable — Identical to LiteTable.
|
|
3
|
+
* Virtual scrolling (rendering only visible rows) requires JS.
|
|
4
|
+
* In lite mode, all rows are rendered server-side. For large datasets,
|
|
5
|
+
* rely on server-side pagination instead.
|
|
6
|
+
*/
|
|
7
|
+
import type { ResourceDefinition } from '@svadmin/core';
|
|
8
|
+
interface Props {
|
|
9
|
+
records: Record<string, unknown>[];
|
|
10
|
+
resource: ResourceDefinition;
|
|
11
|
+
currentSort?: string;
|
|
12
|
+
currentOrder?: 'asc' | 'desc';
|
|
13
|
+
currentSearch?: string;
|
|
14
|
+
basePath?: string;
|
|
15
|
+
canEdit?: boolean;
|
|
16
|
+
canDelete?: boolean;
|
|
17
|
+
}
|
|
18
|
+
declare const LiteVirtualTable: import("svelte").Component<Props, {}, "">;
|
|
19
|
+
type LiteVirtualTable = ReturnType<typeof LiteVirtualTable>;
|
|
20
|
+
export default LiteVirtualTable;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export { default as LiteToast } from './LiteToast.svelte';
|
|
2
|
+
export { default as LiteUndoableNotification } from './LiteUndoableNotification.svelte';
|
|
3
|
+
export { default as LiteModalForm } from './LiteModalForm.svelte';
|
|
4
|
+
export { default as LiteDrawerForm } from './LiteDrawerForm.svelte';
|
|
5
|
+
export { default as LiteInlineEdit } from './LiteInlineEdit.svelte';
|
|
6
|
+
export { default as LiteAutoSaveIndicator } from './LiteAutoSaveIndicator.svelte';
|
|
7
|
+
export { default as LiteVirtualTable } from './LiteVirtualTable.svelte';
|
|
8
|
+
export { default as LiteDraggableHeader } from './LiteDraggableHeader.svelte';
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { t } from '@svadmin/core/i18n';
|
|
3
|
+
import { Copy } from '@lucide/svelte';
|
|
4
|
+
|
|
5
|
+
interface Props {
|
|
6
|
+
resource: string;
|
|
7
|
+
recordItemId: string | number;
|
|
8
|
+
basePath?: string;
|
|
9
|
+
hideText?: boolean;
|
|
10
|
+
class?: string;
|
|
11
|
+
size?: 'sm' | 'default' | 'icon';
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
let {
|
|
15
|
+
resource,
|
|
16
|
+
recordItemId,
|
|
17
|
+
basePath = '/lite',
|
|
18
|
+
hideText = false,
|
|
19
|
+
class: className = '',
|
|
20
|
+
size = 'default'
|
|
21
|
+
}: Props = $props();
|
|
22
|
+
</script>
|
|
23
|
+
|
|
24
|
+
<a
|
|
25
|
+
href={`${basePath}/${resource}/clone/${recordItemId}`}
|
|
26
|
+
class="lite-btn {size === 'sm' ? 'lite-btn-sm' : ''} {className}"
|
|
27
|
+
title={t('common.clone') || 'Clone'}
|
|
28
|
+
>
|
|
29
|
+
<Copy class="h-4 w-4" />
|
|
30
|
+
{#if !hideText}
|
|
31
|
+
<span style="marginLeft: 4px">{t('common.clone') || 'Clone'}</span>
|
|
32
|
+
{/if}
|
|
33
|
+
</a>
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
interface Props {
|
|
2
|
+
resource: string;
|
|
3
|
+
recordItemId: string | number;
|
|
4
|
+
basePath?: string;
|
|
5
|
+
hideText?: boolean;
|
|
6
|
+
class?: string;
|
|
7
|
+
size?: 'sm' | 'default' | 'icon';
|
|
8
|
+
}
|
|
9
|
+
declare const LiteCloneButton: import("svelte").Component<Props, {}, "">;
|
|
10
|
+
type LiteCloneButton = ReturnType<typeof LiteCloneButton>;
|
|
11
|
+
export default LiteCloneButton;
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { t } from '@svadmin/core/i18n';
|
|
3
|
+
import { Plus } from '@lucide/svelte';
|
|
4
|
+
|
|
5
|
+
interface Props {
|
|
6
|
+
resource: string;
|
|
7
|
+
basePath?: string;
|
|
8
|
+
hideText?: boolean;
|
|
9
|
+
class?: string;
|
|
10
|
+
size?: 'sm' | 'default' | 'icon';
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
let {
|
|
14
|
+
resource,
|
|
15
|
+
basePath = '/lite',
|
|
16
|
+
hideText = false,
|
|
17
|
+
class: className = '',
|
|
18
|
+
size = 'default'
|
|
19
|
+
}: Props = $props();
|
|
20
|
+
</script>
|
|
21
|
+
|
|
22
|
+
<a
|
|
23
|
+
href={`${basePath}/${resource}/create`}
|
|
24
|
+
class="lite-btn lite-btn-primary {size === 'sm' ? 'lite-btn-sm' : ''} {className}"
|
|
25
|
+
title={t('common.create') || 'Create'}
|
|
26
|
+
>
|
|
27
|
+
<Plus class="h-4 w-4" />
|
|
28
|
+
{#if !hideText}
|
|
29
|
+
<span style="marginLeft: 4px">{t('common.create') || 'Create'}</span>
|
|
30
|
+
{/if}
|
|
31
|
+
</a>
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
interface Props {
|
|
2
|
+
resource: string;
|
|
3
|
+
basePath?: string;
|
|
4
|
+
hideText?: boolean;
|
|
5
|
+
class?: string;
|
|
6
|
+
size?: 'sm' | 'default' | 'icon';
|
|
7
|
+
}
|
|
8
|
+
declare const LiteCreateButton: import("svelte").Component<Props, {}, "">;
|
|
9
|
+
type LiteCreateButton = ReturnType<typeof LiteCreateButton>;
|
|
10
|
+
export default LiteCreateButton;
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { t } from '@svadmin/core/i18n';
|
|
3
|
+
import { Trash2 } from '@lucide/svelte';
|
|
4
|
+
|
|
5
|
+
interface Props {
|
|
6
|
+
resource: string;
|
|
7
|
+
recordItemId: string | number;
|
|
8
|
+
basePath?: string;
|
|
9
|
+
hideText?: boolean;
|
|
10
|
+
class?: string;
|
|
11
|
+
size?: 'sm' | 'default' | 'icon';
|
|
12
|
+
redirectUrl?: string;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
let {
|
|
16
|
+
resource,
|
|
17
|
+
recordItemId,
|
|
18
|
+
basePath = '/lite',
|
|
19
|
+
hideText = false,
|
|
20
|
+
class: className = '',
|
|
21
|
+
size = 'default',
|
|
22
|
+
redirectUrl = ''
|
|
23
|
+
}: Props = $props();
|
|
24
|
+
</script>
|
|
25
|
+
|
|
26
|
+
<details class="lite-confirm-details {className}">
|
|
27
|
+
<summary
|
|
28
|
+
class="lite-btn lite-btn-danger {size === 'sm' ? 'lite-btn-sm' : ''}"
|
|
29
|
+
title={t('common.delete') || 'Delete'}
|
|
30
|
+
>
|
|
31
|
+
<Trash2 class="h-4 w-4" />
|
|
32
|
+
{#if !hideText}
|
|
33
|
+
<span style="marginLeft: 4px">{t('common.delete') || 'Delete'}</span>
|
|
34
|
+
{/if}
|
|
35
|
+
</summary>
|
|
36
|
+
<div class="lite-confirm-panel" style="right: 0; left: auto;">
|
|
37
|
+
<p style="margin: 0 0 8px; font-size: 13px; color: #111827;">
|
|
38
|
+
{t('common.areYouSure') || 'Are you sure?'}
|
|
39
|
+
</p>
|
|
40
|
+
<form method="POST" action={`${basePath}/${resource}?/delete`} style="display:inline-flex; gap: 8px;">
|
|
41
|
+
<input type="hidden" name="id" value={String(recordItemId)} />
|
|
42
|
+
{#if redirectUrl}
|
|
43
|
+
<input type="hidden" name="redirect" value={redirectUrl} />
|
|
44
|
+
{/if}
|
|
45
|
+
<button
|
|
46
|
+
type="button"
|
|
47
|
+
class="lite-btn lite-btn-sm"
|
|
48
|
+
onclick={(e) => (e.currentTarget as HTMLElement).closest('details')?.removeAttribute('open')}
|
|
49
|
+
>
|
|
50
|
+
{t('common.cancel') || 'Cancel'}
|
|
51
|
+
</button>
|
|
52
|
+
<button type="submit" class="lite-btn lite-btn-sm lite-btn-danger">
|
|
53
|
+
{t('common.confirm') || 'Confirm'}
|
|
54
|
+
</button>
|
|
55
|
+
</form>
|
|
56
|
+
</div>
|
|
57
|
+
</details>
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
interface Props {
|
|
2
|
+
resource: string;
|
|
3
|
+
recordItemId: string | number;
|
|
4
|
+
basePath?: string;
|
|
5
|
+
hideText?: boolean;
|
|
6
|
+
class?: string;
|
|
7
|
+
size?: 'sm' | 'default' | 'icon';
|
|
8
|
+
redirectUrl?: string;
|
|
9
|
+
}
|
|
10
|
+
declare const LiteDeleteButton: import("svelte").Component<Props, {}, "">;
|
|
11
|
+
type LiteDeleteButton = ReturnType<typeof LiteDeleteButton>;
|
|
12
|
+
export default LiteDeleteButton;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { t } from '@svadmin/core/i18n';
|
|
3
|
+
import { Pencil } from '@lucide/svelte';
|
|
4
|
+
|
|
5
|
+
interface Props {
|
|
6
|
+
resource: string;
|
|
7
|
+
recordItemId: string | number;
|
|
8
|
+
basePath?: string;
|
|
9
|
+
hideText?: boolean;
|
|
10
|
+
class?: string;
|
|
11
|
+
size?: 'sm' | 'default' | 'icon';
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
let {
|
|
15
|
+
resource,
|
|
16
|
+
recordItemId,
|
|
17
|
+
basePath = '/lite',
|
|
18
|
+
hideText = false,
|
|
19
|
+
class: className = '',
|
|
20
|
+
size = 'default'
|
|
21
|
+
}: Props = $props();
|
|
22
|
+
</script>
|
|
23
|
+
|
|
24
|
+
<a
|
|
25
|
+
href={`${basePath}/${resource}/edit/${recordItemId}`}
|
|
26
|
+
class="lite-btn {size === 'sm' ? 'lite-btn-sm' : ''} {className}"
|
|
27
|
+
title={t('common.edit') || 'Edit'}
|
|
28
|
+
>
|
|
29
|
+
<Pencil class="h-4 w-4" />
|
|
30
|
+
{#if !hideText}
|
|
31
|
+
<span style="marginLeft: 4px">{t('common.edit') || 'Edit'}</span>
|
|
32
|
+
{/if}
|
|
33
|
+
</a>
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
interface Props {
|
|
2
|
+
resource: string;
|
|
3
|
+
recordItemId: string | number;
|
|
4
|
+
basePath?: string;
|
|
5
|
+
hideText?: boolean;
|
|
6
|
+
class?: string;
|
|
7
|
+
size?: 'sm' | 'default' | 'icon';
|
|
8
|
+
}
|
|
9
|
+
declare const LiteEditButton: import("svelte").Component<Props, {}, "">;
|
|
10
|
+
type LiteEditButton = ReturnType<typeof LiteEditButton>;
|
|
11
|
+
export default LiteEditButton;
|