@svadmin/lite 0.3.2 → 0.3.3
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/package.json +2 -2
- package/src/components/LiteAuditLog.svelte +2 -2
- package/src/components/LiteLayout.svelte +2 -2
- package/src/components/LiteShow.svelte +2 -2
- package/src/components/LiteTable.svelte +1 -1
- package/src/components/advanced/LiteDrawerForm.svelte +1 -1
- package/src/components/advanced/LiteModalForm.svelte +1 -1
- package/src/components/buttons/LiteCloneButton.svelte +1 -1
- package/src/components/buttons/LiteCreateButton.svelte +1 -1
- package/src/components/buttons/LiteDeleteButton.svelte +1 -1
- package/src/components/buttons/LiteEditButton.svelte +1 -1
- package/src/components/buttons/LiteImportButton.svelte +1 -1
- package/src/components/buttons/LiteListButton.svelte +1 -1
- package/src/components/buttons/LiteShowButton.svelte +1 -1
- package/src/components/layout/LiteSidebar.svelte +2 -2
- package/src/components/pages/LiteCreatePage.svelte +2 -2
- package/src/components/pages/LiteEditPage.svelte +3 -3
- package/src/components/pages/LiteShowPage.svelte +1 -1
- package/src/server-adapter.ts +16 -2
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@svadmin/lite",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.3",
|
|
4
4
|
"description": "SSR-compatible lightweight admin UI for @svadmin — zero client-side JS, works in IE11",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"files": [
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
},
|
|
22
22
|
"peerDependencies": {
|
|
23
23
|
"svelte": "^5.0.0",
|
|
24
|
-
"@svadmin/core": "^0.
|
|
24
|
+
"@svadmin/core": "^0.22.1",
|
|
25
25
|
"@sveltejs/kit": "^2.0.0"
|
|
26
26
|
},
|
|
27
27
|
"dependencies": {
|
|
@@ -79,11 +79,11 @@
|
|
|
79
79
|
{#if totalPages > 1}
|
|
80
80
|
<div class="lite-pagination" style="margin-top:12px;">
|
|
81
81
|
{#if page > 1}
|
|
82
|
-
<a href=
|
|
82
|
+
<a href={`${basePath}page={page - 1}`} class="lite-btn lite-btn-sm">« Prev</a>
|
|
83
83
|
{/if}
|
|
84
84
|
<span style="padding:0 12px;font-size:14px;color:#64748b;">Page {page} / {totalPages} ({total} total)</span>
|
|
85
85
|
{#if page < totalPages}
|
|
86
|
-
<a href=
|
|
86
|
+
<a href={`${basePath}page={page + 1}`} class="lite-btn lite-btn-sm">Next »</a>
|
|
87
87
|
{/if}
|
|
88
88
|
</div>
|
|
89
89
|
{/if}
|
|
@@ -81,7 +81,7 @@
|
|
|
81
81
|
{:else}
|
|
82
82
|
{#each menuResources as res}
|
|
83
83
|
<a
|
|
84
|
-
href=
|
|
84
|
+
href={`${basePath}/${res.name}`}
|
|
85
85
|
class={res.name === currentResource ? 'active' : ''}
|
|
86
86
|
>
|
|
87
87
|
{res.label}
|
|
@@ -91,7 +91,7 @@
|
|
|
91
91
|
{#if userName}
|
|
92
92
|
<div style="position:absolute;bottom:0;left:0;right:0;padding:12px 16px;border-top:1px solid #334155;font-size:12px;color:#94a3b8;">
|
|
93
93
|
{userName}
|
|
94
|
-
<form method="POST" action=
|
|
94
|
+
<form method="POST" action={`${basePath}/login?/logout`} style="display:inline;margin-left:8px;">
|
|
95
95
|
<button type="submit" class="lite-btn lite-btn-sm" style="color:#94a3b8;border-color:#475569;background:transparent;">Logout</button>
|
|
96
96
|
</form>
|
|
97
97
|
</div>
|
|
@@ -33,11 +33,11 @@
|
|
|
33
33
|
<h1>{resource.label} #{id}</h1>
|
|
34
34
|
<div>
|
|
35
35
|
{#if canEdit}
|
|
36
|
-
<a href=
|
|
36
|
+
<a href={`${basePath}/${resource.name}/edit/${id}`} class="lite-btn lite-btn-primary">
|
|
37
37
|
{t('common.edit') || 'Edit'}
|
|
38
38
|
</a>
|
|
39
39
|
{/if}
|
|
40
|
-
<a href=
|
|
40
|
+
<a href={`${basePath}/${resource.name}`} class="lite-btn" style="margin-left:8px;">
|
|
41
41
|
{t('common.backToList') || 'Back to List'}
|
|
42
42
|
</a>
|
|
43
43
|
</div>
|
|
@@ -103,7 +103,7 @@
|
|
|
103
103
|
{#if canEdit || canDelete}
|
|
104
104
|
<td class="actions">
|
|
105
105
|
{#if canEdit}
|
|
106
|
-
<a href=
|
|
106
|
+
<a href={`${basePath}/${resource.name}/edit/${id}`} class="lite-btn lite-btn-sm">{t('common.edit') || 'Edit'}</a>
|
|
107
107
|
{/if}
|
|
108
108
|
{#if canDelete}
|
|
109
109
|
<!-- Delete uses <details> for no-JS confirmation -->
|
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
<p style="margin: 0 0 8px; font-size: 13px; color: #111827;">
|
|
38
38
|
{t('common.areYouSure') || 'Are you sure?'}
|
|
39
39
|
</p>
|
|
40
|
-
<form method="POST" action="?/
|
|
40
|
+
<form method="POST" action="?/delete" style="display:inline-flex; gap: 8px;">
|
|
41
41
|
<input type="hidden" name="id" value={String(recordItemId)} />
|
|
42
42
|
{#if redirectUrl}
|
|
43
43
|
<input type="hidden" name="redirect" value={redirectUrl} />
|
|
@@ -31,7 +31,7 @@
|
|
|
31
31
|
</summary>
|
|
32
32
|
<div class="lite-confirm-panel">
|
|
33
33
|
<p style="margin: 0 0 8px; font-size: 13px;">{t('common.importData') || 'Import data (CSV/JSON)'}</p>
|
|
34
|
-
<form method="POST" action="
|
|
34
|
+
<form method="POST" action="?/${resource}_import" enctype="multipart/form-data" style="display:flex; flex-direction: column; gap: 8px;">
|
|
35
35
|
<input type="file" name="file" accept=".csv,.json" required style="font-size: 13px;" />
|
|
36
36
|
<div style="display:flex; gap: 8px; justify-content: flex-end;">
|
|
37
37
|
<button
|
|
@@ -75,7 +75,7 @@
|
|
|
75
75
|
{:else}
|
|
76
76
|
{#each menuResources as res}
|
|
77
77
|
<a
|
|
78
|
-
href=
|
|
78
|
+
href={`${basePath}/${res.name}`}
|
|
79
79
|
class={res.name === currentResource ? 'active' : ''}
|
|
80
80
|
>
|
|
81
81
|
{res.label ?? res.name}
|
|
@@ -85,7 +85,7 @@
|
|
|
85
85
|
{#if userName}
|
|
86
86
|
<div style="position:absolute;bottom:0;left:0;right:0;padding:12px 16px;border-top:1px solid #334155;font-size:12px;color:#94a3b8;">
|
|
87
87
|
{userName}
|
|
88
|
-
<form method="POST" action=
|
|
88
|
+
<form method="POST" action={`${basePath}/login?/logout`} style="display:inline;margin-left:8px;">
|
|
89
89
|
<button type="submit" class="lite-btn lite-btn-sm" style="color:#94a3b8;border-color:#475569;background:transparent;padding:2px 8px;">Logout</button>
|
|
90
90
|
</form>
|
|
91
91
|
</div>
|
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
{/if}
|
|
38
38
|
<LiteListButton resource={resource.name} {basePath} />
|
|
39
39
|
{#if canDelete}
|
|
40
|
-
<LiteDeleteButton resource={resource.name} recordItemId={idStr} redirectUrl=
|
|
40
|
+
<LiteDeleteButton resource={resource.name} recordItemId={idStr} redirectUrl={`${basePath}/${resource.name}`} {basePath} />
|
|
41
41
|
{/if}
|
|
42
42
|
</div>
|
|
43
43
|
</div>
|
|
@@ -48,7 +48,7 @@
|
|
|
48
48
|
{resource}
|
|
49
49
|
{errors}
|
|
50
50
|
values={record}
|
|
51
|
-
action="?/
|
|
52
|
-
cancelUrl=
|
|
51
|
+
action="?/update"
|
|
52
|
+
cancelUrl={`${basePath}/${resource.name}`}
|
|
53
53
|
/>
|
|
54
54
|
</div>
|
|
@@ -39,7 +39,7 @@
|
|
|
39
39
|
{/if}
|
|
40
40
|
<LiteListButton resource={resource.name} {basePath} />
|
|
41
41
|
{#if canDelete}
|
|
42
|
-
<LiteDeleteButton resource={resource.name} recordItemId={idStr} redirectUrl=
|
|
42
|
+
<LiteDeleteButton resource={resource.name} recordItemId={idStr} redirectUrl={`${basePath}/${resource.name}`} {basePath} />
|
|
43
43
|
{/if}
|
|
44
44
|
</div>
|
|
45
45
|
</div>
|
package/src/server-adapter.ts
CHANGED
|
@@ -9,7 +9,7 @@ import type {
|
|
|
9
9
|
ResourceDefinition, FieldDefinition,
|
|
10
10
|
Sort, Filter,
|
|
11
11
|
} from '@svadmin/core';
|
|
12
|
-
import { fail, redirect, type RequestEvent } from '@sveltejs/kit';
|
|
12
|
+
import { fail, redirect, isRedirect, type RequestEvent } from '@sveltejs/kit';
|
|
13
13
|
|
|
14
14
|
// ─── List Loader ──────────────────────────────────────────────
|
|
15
15
|
|
|
@@ -107,6 +107,7 @@ export function createCrudActions(
|
|
|
107
107
|
const result = await dp.create({ resource: resource.name, variables });
|
|
108
108
|
return { success: true, id: (result.data as Record<string, unknown>)[pk] };
|
|
109
109
|
} catch (e) {
|
|
110
|
+
if (isRedirect(e)) throw e;
|
|
110
111
|
return { success: false, error: (e as Error).message, values: variables };
|
|
111
112
|
}
|
|
112
113
|
},
|
|
@@ -120,6 +121,7 @@ export function createCrudActions(
|
|
|
120
121
|
await dp.update({ resource: resource.name, id, variables });
|
|
121
122
|
return { success: true };
|
|
122
123
|
} catch (e) {
|
|
124
|
+
if (isRedirect(e)) throw e;
|
|
123
125
|
return { success: false, error: (e as Error).message, values: variables };
|
|
124
126
|
}
|
|
125
127
|
},
|
|
@@ -133,6 +135,7 @@ export function createCrudActions(
|
|
|
133
135
|
if (redirectTo) throw redirect(303, redirectTo);
|
|
134
136
|
return { success: true };
|
|
135
137
|
} catch (e) {
|
|
138
|
+
if (isRedirect(e)) throw e;
|
|
136
139
|
return { success: false, error: (e as Error).message };
|
|
137
140
|
}
|
|
138
141
|
},
|
|
@@ -155,21 +158,31 @@ export function createAuthGuard(
|
|
|
155
158
|
return resolve(event);
|
|
156
159
|
}
|
|
157
160
|
|
|
161
|
+
// Local Lite Session Verify
|
|
162
|
+
const session = event.cookies.get('svadmin-session');
|
|
163
|
+
if (!session) {
|
|
164
|
+
return new Response(null, {
|
|
165
|
+
status: 302,
|
|
166
|
+
headers: { Location: loginPath },
|
|
167
|
+
});
|
|
168
|
+
}
|
|
169
|
+
|
|
158
170
|
try {
|
|
159
171
|
const check = await authProvider.check();
|
|
160
172
|
if (!check.authenticated) {
|
|
173
|
+
event.cookies.delete('svadmin-session', { path: '/' });
|
|
161
174
|
return new Response(null, {
|
|
162
175
|
status: 302,
|
|
163
176
|
headers: { Location: loginPath },
|
|
164
177
|
});
|
|
165
178
|
}
|
|
166
179
|
} catch {
|
|
180
|
+
event.cookies.delete('svadmin-session', { path: '/' });
|
|
167
181
|
return new Response(null, {
|
|
168
182
|
status: 302,
|
|
169
183
|
headers: { Location: loginPath },
|
|
170
184
|
});
|
|
171
185
|
}
|
|
172
|
-
|
|
173
186
|
return resolve(event);
|
|
174
187
|
};
|
|
175
188
|
}
|
|
@@ -196,6 +209,7 @@ export function createAuthActions(authProvider: AuthProvider) {
|
|
|
196
209
|
}
|
|
197
210
|
return { success: false, error: result.error?.message ?? 'Login failed' };
|
|
198
211
|
} catch (e) {
|
|
212
|
+
if (isRedirect(e)) throw e;
|
|
199
213
|
return { success: false, error: (e as Error).message };
|
|
200
214
|
}
|
|
201
215
|
},
|