runeforge 0.0.10 → 0.0.11
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 +3 -1
- package/dist/components/crud/views/List.svelte +34 -3
- package/dist/i18n/en.js +2 -0
- package/dist/i18n/es.js +2 -0
- package/dist/i18n/types.d.ts +2 -0
- package/dist/types/crud.d.ts +1 -0
- package/package.json +80 -78
package/README.md
CHANGED
|
@@ -326,7 +326,7 @@ Key props:
|
|
|
326
326
|
- `labelOne` / `labelMany` — singular and plural names for the entity
|
|
327
327
|
- `columns` — `ColumnDefinition[]` for the table view
|
|
328
328
|
- `fields` — `FieldDefinition[]` for form views
|
|
329
|
-
- `creation`, `update`, `read`, `deletion` — `ActionConfiguration` objects that define handlers and permissions for each operation
|
|
329
|
+
- `creation`, `update`, `read`, `deletion` — `ActionConfiguration` objects that define handlers and permissions for each operation. Set `confirm: true` on `deletion` to show a confirmation dialog before any delete (single row or batch)
|
|
330
330
|
|
|
331
331
|
### PaginatedTable
|
|
332
332
|
|
|
@@ -584,6 +584,8 @@ All UI strings default to **Spanish** (Argentina). To switch to another language
|
|
|
584
584
|
| `saveAndContinue` | `string` | `Guardar y continuar` |
|
|
585
585
|
| `cancel` | `string` | `Cancelar` |
|
|
586
586
|
| `back` | `string` | `Volver` |
|
|
587
|
+
| `confirm` | `string` | `Confirmar` |
|
|
588
|
+
| `deleteConfirm` | `(count) => string` | `¿Seguro que querés eliminar 3 elementos?` |
|
|
587
589
|
| `required` | `(field) => string` | `Título es requerido` |
|
|
588
590
|
| `serverError` | `string` | `Error inesperado del servidor.` |
|
|
589
591
|
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
import { invalidateAll } from '$app/navigation';
|
|
4
4
|
import Button from '../../form/Button.svelte';
|
|
5
5
|
import Header from '../../common/Header.svelte';
|
|
6
|
+
import Modal from '../../Modal.svelte';
|
|
6
7
|
import PaginatedTable from '../../table/PaginatedTable.svelte';
|
|
7
8
|
import { getIconSet } from '../../../icons/context.js';
|
|
8
9
|
import { defaultIconSet } from '../../../icons/sets/default.js';
|
|
@@ -65,6 +66,7 @@
|
|
|
65
66
|
const showRowActions = $derived(allowRead || allowUpdate || allowDelete || actions.length > 0);
|
|
66
67
|
|
|
67
68
|
let selected = new SvelteSet<number>();
|
|
69
|
+
let pendingDeletion = $state<T[] | null>(null);
|
|
68
70
|
|
|
69
71
|
async function runEndpointAction(endpoint: string, items: T[]) {
|
|
70
72
|
await Promise.all(items.map((item) => {
|
|
@@ -83,12 +85,27 @@
|
|
|
83
85
|
}
|
|
84
86
|
}
|
|
85
87
|
|
|
88
|
+
function requestDeletion(items: T[]) {
|
|
89
|
+
if (deletion.confirm) {
|
|
90
|
+
pendingDeletion = items;
|
|
91
|
+
} else {
|
|
92
|
+
runDeletion(items);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
86
96
|
function handleCreate() { onCreate?.(); }
|
|
87
97
|
|
|
88
|
-
|
|
98
|
+
function handleDelete() {
|
|
89
99
|
const items = [...selected].map(i => data[i]);
|
|
90
100
|
selected.clear();
|
|
91
|
-
|
|
101
|
+
requestDeletion(items);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
async function confirmDeletion() {
|
|
105
|
+
if (pendingDeletion) {
|
|
106
|
+
await runDeletion(pendingDeletion);
|
|
107
|
+
pendingDeletion = null;
|
|
108
|
+
}
|
|
92
109
|
}
|
|
93
110
|
|
|
94
111
|
const rowActions = $derived<RowAction<T>[]>([
|
|
@@ -100,7 +117,7 @@
|
|
|
100
117
|
})),
|
|
101
118
|
...(allowRead ? [{ label: readLabel, icon: icons.view, run: (item: T) => onView?.(item) }] : []),
|
|
102
119
|
...(allowUpdate ? [{ label: updateLabel, icon: icons.edit, run: (item: T) => onEdit?.(item) }] : []),
|
|
103
|
-
...(allowDelete ? [{ label: deleteLabel, icon: icons.delete, class: 'text-error', run: (item: T) =>
|
|
120
|
+
...(allowDelete ? [{ label: deleteLabel, icon: icons.delete, class: 'text-error', run: (item: T) => requestDeletion([item]) }] : []),
|
|
104
121
|
]);
|
|
105
122
|
</script>
|
|
106
123
|
|
|
@@ -172,6 +189,20 @@
|
|
|
172
189
|
</div>
|
|
173
190
|
</div>
|
|
174
191
|
|
|
192
|
+
{#if pendingDeletion !== null}
|
|
193
|
+
<Modal title={deleteLabel} onClose={() => (pendingDeletion = null)}>
|
|
194
|
+
<p>{strings.deleteConfirm(pendingDeletion.length)}</p>
|
|
195
|
+
<div class="flex justify-end gap-2 mt-4">
|
|
196
|
+
<Button variant="ghost" onclick={() => (pendingDeletion = null)}>
|
|
197
|
+
{strings.cancel}
|
|
198
|
+
</Button>
|
|
199
|
+
<Button variant="error" onclick={confirmDeletion}>
|
|
200
|
+
{strings.confirm}
|
|
201
|
+
</Button>
|
|
202
|
+
</div>
|
|
203
|
+
</Modal>
|
|
204
|
+
{/if}
|
|
205
|
+
|
|
175
206
|
<style>
|
|
176
207
|
.table-wrapper {
|
|
177
208
|
width: 100%;
|
package/dist/i18n/en.js
CHANGED
|
@@ -19,6 +19,8 @@ export const en = {
|
|
|
19
19
|
saveAndContinue: 'Save and continue',
|
|
20
20
|
cancel: 'Cancel',
|
|
21
21
|
back: 'Back',
|
|
22
|
+
confirm: 'Confirm',
|
|
23
|
+
deleteConfirm: (count) => `Are you sure you want to delete ${count} item${count === 1 ? '' : 's'}?`,
|
|
22
24
|
required: (field) => `${field} is required`,
|
|
23
25
|
serverError: 'Unexpected server error.',
|
|
24
26
|
};
|
package/dist/i18n/es.js
CHANGED
|
@@ -19,6 +19,8 @@ export const es = {
|
|
|
19
19
|
saveAndContinue: 'Guardar y continuar',
|
|
20
20
|
cancel: 'Cancelar',
|
|
21
21
|
back: 'Volver',
|
|
22
|
+
confirm: 'Confirmar',
|
|
23
|
+
deleteConfirm: (count) => `¿Seguro que querés eliminar ${count} elemento${count === 1 ? '' : 's'}?`,
|
|
22
24
|
required: (field) => `${field} es requerido`,
|
|
23
25
|
serverError: 'Error inesperado del servidor.',
|
|
24
26
|
};
|
package/dist/i18n/types.d.ts
CHANGED
package/dist/types/crud.d.ts
CHANGED
|
@@ -30,6 +30,7 @@ export interface ActionConfiguration<T extends object = Record<string, unknown>>
|
|
|
30
30
|
enabled?: boolean;
|
|
31
31
|
label?: string;
|
|
32
32
|
endpoint?: string;
|
|
33
|
+
confirm?: boolean;
|
|
33
34
|
callback?: (items: T[]) => void | Promise<void>;
|
|
34
35
|
}
|
|
35
36
|
export interface CustomAction<T extends object = Record<string, unknown>> {
|
package/package.json
CHANGED
|
@@ -1,79 +1,81 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
2
|
+
"name": "runeforge",
|
|
3
|
+
"version": "0.0.11",
|
|
4
|
+
"description": "SvelteKit toolkit for building metadata-driven CRUD interfaces with tables, forms, and actions",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"author": "Ezequiel Puerta",
|
|
7
|
+
"keywords": [
|
|
8
|
+
"svelte",
|
|
9
|
+
"sveltekit",
|
|
10
|
+
"crud",
|
|
11
|
+
"table",
|
|
12
|
+
"form",
|
|
13
|
+
"daisyui",
|
|
14
|
+
"tailwindcss",
|
|
15
|
+
"ui"
|
|
16
|
+
],
|
|
17
|
+
"scripts": {
|
|
18
|
+
"dev": "vite dev",
|
|
19
|
+
"build": "vite build && npm run prepack",
|
|
20
|
+
"preview": "vite preview",
|
|
21
|
+
"prepare": "svelte-kit sync || echo ''",
|
|
22
|
+
"prepack": "svelte-kit sync && svelte-package && publint",
|
|
23
|
+
"check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
|
|
24
|
+
"check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch",
|
|
25
|
+
"test": "pnpm run test:unit && pnpm run test:e2e",
|
|
26
|
+
"test:unit": "vitest run",
|
|
27
|
+
"test:unit:watch": "vitest",
|
|
28
|
+
"test:e2e": "playwright test",
|
|
29
|
+
"lint": "prettier --check . && eslint .",
|
|
30
|
+
"format": "prettier --write ."
|
|
31
|
+
},
|
|
32
|
+
"files": [
|
|
33
|
+
"dist",
|
|
34
|
+
"!dist/**/*.test.*",
|
|
35
|
+
"!dist/**/*.spec.*"
|
|
36
|
+
],
|
|
37
|
+
"sideEffects": [
|
|
38
|
+
"**/*.css"
|
|
39
|
+
],
|
|
40
|
+
"svelte": "./dist/index.js",
|
|
41
|
+
"types": "./dist/index.d.ts",
|
|
42
|
+
"type": "module",
|
|
43
|
+
"exports": {
|
|
44
|
+
".": {
|
|
45
|
+
"types": "./dist/index.d.ts",
|
|
46
|
+
"svelte": "./dist/index.js"
|
|
47
|
+
}
|
|
48
|
+
},
|
|
49
|
+
"peerDependencies": {
|
|
50
|
+
"@sveltejs/kit": "^2.0.0",
|
|
51
|
+
"daisyui": "^5.0.0",
|
|
52
|
+
"svelte": "^5.0.0",
|
|
53
|
+
"tailwindcss": "^4.0.0"
|
|
54
|
+
},
|
|
55
|
+
"devDependencies": {
|
|
56
|
+
"@eslint/js": "^10.0.1",
|
|
57
|
+
"@playwright/test": "^1.60.0",
|
|
58
|
+
"@sveltejs/adapter-auto": "^7.0.1",
|
|
59
|
+
"@sveltejs/kit": "^2.63.0",
|
|
60
|
+
"@sveltejs/package": "^2.5.8",
|
|
61
|
+
"@sveltejs/vite-plugin-svelte": "^7.1.2",
|
|
62
|
+
"@tailwindcss/vite": "^4.3.1",
|
|
63
|
+
"@types/node": "^22",
|
|
64
|
+
"daisyui": "^5.5.23",
|
|
65
|
+
"eslint": "^10.4.1",
|
|
66
|
+
"eslint-config-prettier": "^10.1.8",
|
|
67
|
+
"eslint-plugin-svelte": "^3.19.0",
|
|
68
|
+
"globals": "^17.6.0",
|
|
69
|
+
"prettier": "^3.8.3",
|
|
70
|
+
"prettier-plugin-svelte": "^4.1.0",
|
|
71
|
+
"publint": "^0.3.21",
|
|
72
|
+
"svelte": "^5.56.1",
|
|
73
|
+
"svelte-bootstrap-icons": "^3.3.0",
|
|
74
|
+
"svelte-check": "^4.6.0",
|
|
75
|
+
"tailwindcss": "^4.3.1",
|
|
76
|
+
"typescript": "^6.0.3",
|
|
77
|
+
"typescript-eslint": "^8.60.1",
|
|
78
|
+
"vite": "^8.0.16",
|
|
79
|
+
"vitest": "^4.1.8"
|
|
80
|
+
}
|
|
81
|
+
}
|