runeforge 0.0.57 → 0.0.59
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 +51 -0
- package/dist/components/crud/EmbeddedField.svelte +33 -5
- package/dist/components/crud/EmbeddedField.svelte.d.ts +6 -1
- package/dist/components/crud/Field.svelte +76 -423
- package/dist/components/crud/Field.svelte.d.ts +5 -1
- package/dist/components/crud/GenericCRUD.svelte +4 -4
- package/dist/components/crud/GenericCRUD.svelte.d.ts +4 -1
- package/dist/components/crud/SearchInput.svelte +1 -1
- package/dist/components/crud/SearchInput.svelte.d.ts +1 -1
- package/dist/components/crud/fields/BooleanField.svelte +38 -0
- package/dist/components/crud/fields/BooleanField.svelte.d.ts +33 -0
- package/dist/components/crud/fields/DatetimeField.svelte +250 -0
- package/dist/components/crud/fields/DatetimeField.svelte.d.ts +34 -0
- package/dist/components/crud/fields/DefaultField.svelte +67 -0
- package/dist/components/crud/fields/DefaultField.svelte.d.ts +34 -0
- package/dist/components/crud/fields/FileField.svelte +70 -0
- package/dist/components/crud/fields/FileField.svelte.d.ts +34 -0
- package/dist/components/crud/fields/MultiSelectField.svelte +70 -0
- package/dist/components/crud/fields/MultiSelectField.svelte.d.ts +34 -0
- package/dist/components/crud/fields/SelectField.svelte +67 -0
- package/dist/components/crud/fields/SelectField.svelte.d.ts +34 -0
- package/dist/components/crud/fields/TextareaField.svelte +55 -0
- package/dist/components/crud/fields/TextareaField.svelte.d.ts +34 -0
- package/dist/components/crud/fields/TreeField.svelte +63 -0
- package/dist/components/crud/fields/TreeField.svelte.d.ts +33 -0
- package/dist/components/crud/utils/embedded.d.ts +1 -1
- package/dist/components/crud/utils/grouping.d.ts +1 -1
- package/dist/components/crud/utils/resolution.d.ts +1 -1
- package/dist/components/crud/utils/resolution.js +6 -2
- package/dist/components/crud/utils/validation.d.ts +1 -1
- package/dist/components/crud/utils/validation.js +10 -0
- package/dist/components/crud/views/Create.svelte +37 -30
- package/dist/components/crud/views/Create.svelte.d.ts +2 -1
- package/dist/components/crud/views/Read.svelte +19 -12
- package/dist/components/crud/views/Read.svelte.d.ts +2 -1
- package/dist/components/crud/views/Update.svelte +28 -21
- package/dist/components/crud/views/Update.svelte.d.ts +2 -1
- package/dist/components/crud/views/list/List.svelte +3 -3
- package/dist/components/crud/views/list/List.svelte.d.ts +3 -1
- package/dist/components/crud/views/list/Modals.svelte +1 -1
- package/dist/components/crud/views/list/Modals.svelte.d.ts +1 -1
- package/dist/components/crud/views/list/Table.svelte +3 -6
- package/dist/components/crud/views/list/Table.svelte.d.ts +3 -1
- package/dist/components/crud/views/list/Toolbar.svelte +3 -4
- package/dist/components/crud/views/list/Toolbar.svelte.d.ts +3 -1
- package/dist/components/table/ColumnFilter.svelte +1 -1
- package/dist/components/table/ColumnFilter.svelte.d.ts +1 -1
- package/dist/components/table/PaginatedTable.svelte +1 -1
- package/dist/components/table/PaginatedTable.svelte.d.ts +1 -1
- package/dist/components/table/TableBody.svelte +1 -1
- package/dist/components/table/TableBody.svelte.d.ts +1 -1
- package/dist/components/table/TableHeader.svelte +1 -1
- package/dist/components/table/TableHeader.svelte.d.ts +1 -1
- package/dist/components/table/export.d.ts +1 -1
- package/dist/components/table/state.svelte.d.ts +1 -1
- package/dist/components/table/utils.d.ts +1 -1
- package/dist/index.d.ts +5 -1
- package/dist/types/attribute.d.ts +56 -4
- package/dist/types/{crud.d.ts → crud/actions.d.ts} +0 -123
- package/dist/types/crud/columns.d.ts +23 -0
- package/dist/types/crud/columns.js +1 -0
- package/dist/types/crud/fields.d.ts +48 -0
- package/dist/types/crud/fields.js +1 -0
- package/dist/types/crud/list-config.d.ts +23 -0
- package/dist/types/crud/list-config.js +1 -0
- package/dist/types/crud/reorder.d.ts +45 -0
- package/dist/types/crud/reorder.js +1 -0
- package/package.json +1 -1
- /package/dist/types/{crud.js → crud/actions.js} +0 -0
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import type { Snippet } from 'svelte';
|
|
2
|
+
import type { FieldDefinition } from '../../../types/crud/fields.js';
|
|
3
|
+
declare function $$render<T extends object = Record<string, unknown>>(): {
|
|
4
|
+
props: {
|
|
5
|
+
field: FieldDefinition<T>;
|
|
6
|
+
record?: Record<string, unknown>;
|
|
7
|
+
parentRecord?: Record<string, unknown>;
|
|
8
|
+
error?: string;
|
|
9
|
+
readonly?: boolean;
|
|
10
|
+
labelRow: Snippet;
|
|
11
|
+
errorRow: Snippet;
|
|
12
|
+
};
|
|
13
|
+
exports: {};
|
|
14
|
+
bindings: "record";
|
|
15
|
+
slots: {};
|
|
16
|
+
events: {};
|
|
17
|
+
};
|
|
18
|
+
declare class __sveltets_Render<T extends object = Record<string, unknown>> {
|
|
19
|
+
props(): ReturnType<typeof $$render<T>>['props'];
|
|
20
|
+
events(): ReturnType<typeof $$render<T>>['events'];
|
|
21
|
+
slots(): ReturnType<typeof $$render<T>>['slots'];
|
|
22
|
+
bindings(): "record";
|
|
23
|
+
exports(): {};
|
|
24
|
+
}
|
|
25
|
+
interface $$IsomorphicComponent {
|
|
26
|
+
new <T extends object = Record<string, unknown>>(options: import('svelte').ComponentConstructorOptions<ReturnType<__sveltets_Render<T>['props']>>): import('svelte').SvelteComponent<ReturnType<__sveltets_Render<T>['props']>, ReturnType<__sveltets_Render<T>['events']>, ReturnType<__sveltets_Render<T>['slots']>> & {
|
|
27
|
+
$$bindings?: ReturnType<__sveltets_Render<T>['bindings']>;
|
|
28
|
+
} & ReturnType<__sveltets_Render<T>['exports']>;
|
|
29
|
+
<T extends object = Record<string, unknown>>(internal: unknown, props: ReturnType<__sveltets_Render<T>['props']> & {}): ReturnType<__sveltets_Render<T>['exports']>;
|
|
30
|
+
z_$$bindings?: ReturnType<__sveltets_Render<any>['bindings']>;
|
|
31
|
+
}
|
|
32
|
+
declare const SelectField: $$IsomorphicComponent;
|
|
33
|
+
type SelectField<T extends object = Record<string, unknown>> = InstanceType<typeof SelectField<T>>;
|
|
34
|
+
export default SelectField;
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
<script lang="ts" generics="T extends object = Record<string, unknown>">
|
|
2
|
+
import type { Snippet } from 'svelte';
|
|
3
|
+
import type { FieldDefinition } from '../../../types/crud/fields.js';
|
|
4
|
+
|
|
5
|
+
let {
|
|
6
|
+
field,
|
|
7
|
+
record = $bindable({} as Record<string, unknown>),
|
|
8
|
+
parentRecord = undefined,
|
|
9
|
+
error = '',
|
|
10
|
+
readonly = false,
|
|
11
|
+
labelRow,
|
|
12
|
+
errorRow
|
|
13
|
+
}: {
|
|
14
|
+
field: FieldDefinition<T>;
|
|
15
|
+
record?: Record<string, unknown>;
|
|
16
|
+
parentRecord?: Record<string, unknown>;
|
|
17
|
+
error?: string;
|
|
18
|
+
readonly?: boolean;
|
|
19
|
+
labelRow: Snippet;
|
|
20
|
+
errorRow: Snippet;
|
|
21
|
+
} = $props();
|
|
22
|
+
|
|
23
|
+
const name = $derived(readonly ? undefined : field.attribute);
|
|
24
|
+
const saved = $derived(record[field.attribute]);
|
|
25
|
+
const displayValue = $derived(saved == null ? '' : String(saved));
|
|
26
|
+
const formattedValue = $derived(
|
|
27
|
+
readonly && field.formatter ? field.formatter(saved, record) : displayValue
|
|
28
|
+
);
|
|
29
|
+
const fieldDisabled = $derived(field.disabled ? field.disabled(record, parentRecord) : false);
|
|
30
|
+
</script>
|
|
31
|
+
|
|
32
|
+
{@render labelRow()}
|
|
33
|
+
|
|
34
|
+
{#if readonly}
|
|
35
|
+
<textarea
|
|
36
|
+
id={field.attribute}
|
|
37
|
+
rows={field.rows}
|
|
38
|
+
class="textarea textarea-bordered bg-base-100 w-full"
|
|
39
|
+
value={formattedValue}
|
|
40
|
+
disabled
|
|
41
|
+
></textarea>
|
|
42
|
+
{:else}
|
|
43
|
+
<textarea
|
|
44
|
+
id={field.attribute}
|
|
45
|
+
{name}
|
|
46
|
+
rows={field.rows}
|
|
47
|
+
placeholder={field.placeholder ?? ''}
|
|
48
|
+
bind:value={record[field.attribute]}
|
|
49
|
+
class="textarea textarea-bordered bg-base-100 w-full"
|
|
50
|
+
class:textarea-error={!!error}
|
|
51
|
+
disabled={fieldDisabled}
|
|
52
|
+
></textarea>
|
|
53
|
+
{/if}
|
|
54
|
+
|
|
55
|
+
{@render errorRow()}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import type { Snippet } from 'svelte';
|
|
2
|
+
import type { FieldDefinition } from '../../../types/crud/fields.js';
|
|
3
|
+
declare function $$render<T extends object = Record<string, unknown>>(): {
|
|
4
|
+
props: {
|
|
5
|
+
field: FieldDefinition<T>;
|
|
6
|
+
record?: Record<string, unknown>;
|
|
7
|
+
parentRecord?: Record<string, unknown>;
|
|
8
|
+
error?: string;
|
|
9
|
+
readonly?: boolean;
|
|
10
|
+
labelRow: Snippet;
|
|
11
|
+
errorRow: Snippet;
|
|
12
|
+
};
|
|
13
|
+
exports: {};
|
|
14
|
+
bindings: "record";
|
|
15
|
+
slots: {};
|
|
16
|
+
events: {};
|
|
17
|
+
};
|
|
18
|
+
declare class __sveltets_Render<T extends object = Record<string, unknown>> {
|
|
19
|
+
props(): ReturnType<typeof $$render<T>>['props'];
|
|
20
|
+
events(): ReturnType<typeof $$render<T>>['events'];
|
|
21
|
+
slots(): ReturnType<typeof $$render<T>>['slots'];
|
|
22
|
+
bindings(): "record";
|
|
23
|
+
exports(): {};
|
|
24
|
+
}
|
|
25
|
+
interface $$IsomorphicComponent {
|
|
26
|
+
new <T extends object = Record<string, unknown>>(options: import('svelte').ComponentConstructorOptions<ReturnType<__sveltets_Render<T>['props']>>): import('svelte').SvelteComponent<ReturnType<__sveltets_Render<T>['props']>, ReturnType<__sveltets_Render<T>['events']>, ReturnType<__sveltets_Render<T>['slots']>> & {
|
|
27
|
+
$$bindings?: ReturnType<__sveltets_Render<T>['bindings']>;
|
|
28
|
+
} & ReturnType<__sveltets_Render<T>['exports']>;
|
|
29
|
+
<T extends object = Record<string, unknown>>(internal: unknown, props: ReturnType<__sveltets_Render<T>['props']> & {}): ReturnType<__sveltets_Render<T>['exports']>;
|
|
30
|
+
z_$$bindings?: ReturnType<__sveltets_Render<any>['bindings']>;
|
|
31
|
+
}
|
|
32
|
+
declare const TextareaField: $$IsomorphicComponent;
|
|
33
|
+
type TextareaField<T extends object = Record<string, unknown>> = InstanceType<typeof TextareaField<T>>;
|
|
34
|
+
export default TextareaField;
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
<script lang="ts" generics="T extends object = Record<string, unknown>">
|
|
2
|
+
import type { Snippet } from 'svelte';
|
|
3
|
+
import Tree from '../../form/Tree.svelte';
|
|
4
|
+
import type { FieldDefinition } from '../../../types/crud/fields.js';
|
|
5
|
+
|
|
6
|
+
let {
|
|
7
|
+
field,
|
|
8
|
+
record = $bindable({} as Record<string, unknown>),
|
|
9
|
+
parentRecord = undefined,
|
|
10
|
+
readonly = false,
|
|
11
|
+
labelRow,
|
|
12
|
+
errorRow
|
|
13
|
+
}: {
|
|
14
|
+
field: FieldDefinition<T>;
|
|
15
|
+
record?: Record<string, unknown>;
|
|
16
|
+
parentRecord?: Record<string, unknown>;
|
|
17
|
+
readonly?: boolean;
|
|
18
|
+
labelRow: Snippet;
|
|
19
|
+
errorRow: Snippet;
|
|
20
|
+
} = $props();
|
|
21
|
+
|
|
22
|
+
const saved = $derived(record[field.attribute]);
|
|
23
|
+
const selectOptions = $derived(
|
|
24
|
+
field.dependentOptions ? field.dependentOptions(record, parentRecord) : (field.options ?? [])
|
|
25
|
+
);
|
|
26
|
+
const fieldDisabled = $derived(field.disabled ? field.disabled(record, parentRecord) : false);
|
|
27
|
+
|
|
28
|
+
// See SelectField's equivalent effect.
|
|
29
|
+
$effect(() => {
|
|
30
|
+
if (!field.dependentOptions) return;
|
|
31
|
+
const current = record[field.attribute];
|
|
32
|
+
if (!Array.isArray(current)) return;
|
|
33
|
+
const validValues = new Set(selectOptions.map((o) => o.value));
|
|
34
|
+
const pruned = current.filter((v) => validValues.has(String(v)));
|
|
35
|
+
if (pruned.length !== current.length) {
|
|
36
|
+
record[field.attribute] = pruned;
|
|
37
|
+
}
|
|
38
|
+
});
|
|
39
|
+
</script>
|
|
40
|
+
|
|
41
|
+
{@render labelRow()}
|
|
42
|
+
|
|
43
|
+
{#if readonly}
|
|
44
|
+
<input
|
|
45
|
+
type="text"
|
|
46
|
+
id={field.attribute}
|
|
47
|
+
class="input input-bordered w-full"
|
|
48
|
+
value={(Array.isArray(saved) ? saved : [])
|
|
49
|
+
.map((v) => selectOptions.find((o) => o.value === String(v))?.label ?? String(v))
|
|
50
|
+
.join(', ')}
|
|
51
|
+
disabled
|
|
52
|
+
/>
|
|
53
|
+
{:else}
|
|
54
|
+
<Tree
|
|
55
|
+
name={field.attribute}
|
|
56
|
+
bind:value={record[field.attribute] as string[]}
|
|
57
|
+
options={selectOptions}
|
|
58
|
+
disabled={fieldDisabled}
|
|
59
|
+
defaultExpanded={field.defaultExpanded ?? true}
|
|
60
|
+
/>
|
|
61
|
+
{/if}
|
|
62
|
+
|
|
63
|
+
{@render errorRow()}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type { Snippet } from 'svelte';
|
|
2
|
+
import type { FieldDefinition } from '../../../types/crud/fields.js';
|
|
3
|
+
declare function $$render<T extends object = Record<string, unknown>>(): {
|
|
4
|
+
props: {
|
|
5
|
+
field: FieldDefinition<T>;
|
|
6
|
+
record?: Record<string, unknown>;
|
|
7
|
+
parentRecord?: Record<string, unknown>;
|
|
8
|
+
readonly?: boolean;
|
|
9
|
+
labelRow: Snippet;
|
|
10
|
+
errorRow: Snippet;
|
|
11
|
+
};
|
|
12
|
+
exports: {};
|
|
13
|
+
bindings: "record";
|
|
14
|
+
slots: {};
|
|
15
|
+
events: {};
|
|
16
|
+
};
|
|
17
|
+
declare class __sveltets_Render<T extends object = Record<string, unknown>> {
|
|
18
|
+
props(): ReturnType<typeof $$render<T>>['props'];
|
|
19
|
+
events(): ReturnType<typeof $$render<T>>['events'];
|
|
20
|
+
slots(): ReturnType<typeof $$render<T>>['slots'];
|
|
21
|
+
bindings(): "record";
|
|
22
|
+
exports(): {};
|
|
23
|
+
}
|
|
24
|
+
interface $$IsomorphicComponent {
|
|
25
|
+
new <T extends object = Record<string, unknown>>(options: import('svelte').ComponentConstructorOptions<ReturnType<__sveltets_Render<T>['props']>>): import('svelte').SvelteComponent<ReturnType<__sveltets_Render<T>['props']>, ReturnType<__sveltets_Render<T>['events']>, ReturnType<__sveltets_Render<T>['slots']>> & {
|
|
26
|
+
$$bindings?: ReturnType<__sveltets_Render<T>['bindings']>;
|
|
27
|
+
} & ReturnType<__sveltets_Render<T>['exports']>;
|
|
28
|
+
<T extends object = Record<string, unknown>>(internal: unknown, props: ReturnType<__sveltets_Render<T>['props']> & {}): ReturnType<__sveltets_Render<T>['exports']>;
|
|
29
|
+
z_$$bindings?: ReturnType<__sveltets_Render<any>['bindings']>;
|
|
30
|
+
}
|
|
31
|
+
declare const TreeField: $$IsomorphicComponent;
|
|
32
|
+
type TreeField<T extends object = Record<string, unknown>> = InstanceType<typeof TreeField<T>>;
|
|
33
|
+
export default TreeField;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { FieldDefinition } from '../../../types/crud.js';
|
|
1
|
+
import type { FieldDefinition } from '../../../types/crud/fields.js';
|
|
2
2
|
export declare function seedField<T extends object = Record<string, unknown>>(f: FieldDefinition<T>, raw: unknown): unknown;
|
|
3
3
|
export declare function emptyRecord<T extends object = Record<string, unknown>>(fields: FieldDefinition<T>[]): Record<string, unknown>;
|
|
4
4
|
export declare function seedRecord<T extends object = Record<string, unknown>>(fields: FieldDefinition<T>[], source: Record<string, unknown>): Record<string, unknown>;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { FieldDefinition } from '../../../types/crud.js';
|
|
1
|
+
import type { FieldDefinition } from '../../../types/crud/fields.js';
|
|
2
2
|
export type FieldRow<T extends object = Record<string, unknown>> = FieldDefinition<T>[];
|
|
3
3
|
export type FieldGroup<T extends object = Record<string, unknown>> = {
|
|
4
4
|
title?: string;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { AttributeMetadata, AttributeType, SelectOption } from '../../../types/attribute.js';
|
|
2
|
-
import type { FieldDefinition } from '../../../types/crud.js';
|
|
2
|
+
import type { FieldDefinition } from '../../../types/crud/fields.js';
|
|
3
3
|
export declare function resolveOptions(m: AttributeMetadata, d: unknown): SelectOption[] | undefined;
|
|
4
4
|
export declare function resolveDefault(m: AttributeMetadata, d: unknown): unknown;
|
|
5
5
|
export declare function resolveFormatter(m: AttributeMetadata, d: unknown): import("../../../index.ts").CellFormatter<any, any> | undefined;
|
|
@@ -54,7 +54,7 @@ export function buildFieldDefinitions(meta, data, excludedFlag, excluded) {
|
|
|
54
54
|
default: resolveDefault(m, data),
|
|
55
55
|
options: resolveOptions(m, data),
|
|
56
56
|
dependentOptions: m.dependentOptions
|
|
57
|
-
? (record) => m.dependentOptions(data, record)
|
|
57
|
+
? (record, parent) => m.dependentOptions(data, record, parent)
|
|
58
58
|
: undefined,
|
|
59
59
|
search: m.search,
|
|
60
60
|
disabled: m.disabled,
|
|
@@ -68,10 +68,14 @@ export function buildFieldDefinitions(meta, data, excludedFlag, excluded) {
|
|
|
68
68
|
minLength: m.minLength,
|
|
69
69
|
maxLength: m.maxLength,
|
|
70
70
|
pattern: m.pattern,
|
|
71
|
+
validate: m.validate,
|
|
71
72
|
rows: m.rows,
|
|
72
73
|
fields: m.fields ? buildFieldDefinitions(m.fields, data, excludedFlag, new Set()) : undefined,
|
|
73
74
|
itemLabel: m.itemLabel,
|
|
75
|
+
revalidate: m.revalidate,
|
|
76
|
+
dependsOn: m.dependsOn,
|
|
74
77
|
defaultExpanded: m.defaultExpanded,
|
|
75
|
-
row: m.row
|
|
78
|
+
row: m.row,
|
|
79
|
+
actions: m.actions
|
|
76
80
|
}));
|
|
77
81
|
}
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import type { FieldDefinition } from '../../../types/crud.js';
|
|
1
|
+
import type { FieldDefinition } from '../../../types/crud/fields.js';
|
|
2
2
|
import type { RuneforgeStrings } from '../../../i18n/types.js';
|
|
3
3
|
export declare function validateAll<T extends object = Record<string, unknown>>(fields: FieldDefinition<T>[], formData: FormData, strings: RuneforgeStrings): Record<string, string>;
|
|
@@ -22,6 +22,11 @@ export function validateAll(fields, formData, strings) {
|
|
|
22
22
|
if (required && (!Array.isArray(items) || items.length === 0)) {
|
|
23
23
|
errors[field.attribute] = strings.required(fieldLabel(field));
|
|
24
24
|
}
|
|
25
|
+
if (!errors[field.attribute] && field.validate) {
|
|
26
|
+
const message = field.validate(items, record);
|
|
27
|
+
if (message)
|
|
28
|
+
errors[field.attribute] = message;
|
|
29
|
+
}
|
|
25
30
|
continue;
|
|
26
31
|
}
|
|
27
32
|
const val = String(formData.get(field.attribute) ?? '').trim();
|
|
@@ -57,6 +62,11 @@ export function validateAll(fields, formData, strings) {
|
|
|
57
62
|
errors[field.attribute] = strings.pattern(fieldLabel(field));
|
|
58
63
|
}
|
|
59
64
|
}
|
|
65
|
+
if (!errors[field.attribute] && field.validate) {
|
|
66
|
+
const message = field.validate(val, record);
|
|
67
|
+
if (message)
|
|
68
|
+
errors[field.attribute] = message;
|
|
69
|
+
}
|
|
60
70
|
}
|
|
61
71
|
return errors;
|
|
62
72
|
}
|
|
@@ -9,7 +9,8 @@
|
|
|
9
9
|
import { validateAll } from '../utils/validation.js';
|
|
10
10
|
import { groupFields } from '../utils/grouping.js';
|
|
11
11
|
import { applyDuplicateOmit, emptyRecord, seedRecord } from '../utils/embedded.js';
|
|
12
|
-
import type { ActionConfiguration
|
|
12
|
+
import type { ActionConfiguration } from '../../../types/crud/actions.js';
|
|
13
|
+
import type { FieldDefinition } from '../../../types/crud/fields.js';
|
|
13
14
|
import { getStrings } from '../../../i18n/context.js';
|
|
14
15
|
|
|
15
16
|
const strings = getStrings();
|
|
@@ -78,35 +79,37 @@
|
|
|
78
79
|
|
|
79
80
|
<div class="flex flex-col gap-6">
|
|
80
81
|
|
|
81
|
-
<
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
{
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
<
|
|
92
|
-
<
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
<
|
|
101
|
-
<
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
82
|
+
<div class="sticky-header sticky z-10 flex flex-col gap-6 bg-base-100 pb-2">
|
|
83
|
+
<Header
|
|
84
|
+
title={labelMany}
|
|
85
|
+
breadcrumbs={[
|
|
86
|
+
{ label: labelMany, icon: entityIcon, link: { href: '#', onclick: (e) => { e.preventDefault(); onCancel?.(); } }, prominent: true },
|
|
87
|
+
{ label: creation.label ?? labelOne, icon: icons.create },
|
|
88
|
+
]}
|
|
89
|
+
/>
|
|
90
|
+
|
|
91
|
+
{#if successMessage}
|
|
92
|
+
<div role="alert" class="alert alert-success">
|
|
93
|
+
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5 shrink-0" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
|
94
|
+
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12.75 11.25 15 15 9.75M21 12a9 9 0 1 1-18 0 9 9 0 0 1 18 0Z" />
|
|
95
|
+
</svg>
|
|
96
|
+
<span class="text-sm">{successMessage}</span>
|
|
97
|
+
</div>
|
|
98
|
+
{/if}
|
|
99
|
+
|
|
100
|
+
{#if errorEntries.length > 0}
|
|
101
|
+
<div role="alert" class="alert alert-error">
|
|
102
|
+
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5 shrink-0" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
|
103
|
+
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 14l2-2m0 0l2-2m-2 2l-2-2m2 2l2 2m7-2a9 9 0 11-18 0 9 9 0 0118 0z" />
|
|
104
|
+
</svg>
|
|
105
|
+
<ul class="list-disc list-inside text-sm">
|
|
106
|
+
{#each errorEntries as [key, msg] (key)}
|
|
107
|
+
<li>{msg}</li>
|
|
108
|
+
{/each}
|
|
109
|
+
</ul>
|
|
110
|
+
</div>
|
|
111
|
+
{/if}
|
|
112
|
+
</div>
|
|
110
113
|
|
|
111
114
|
<form
|
|
112
115
|
method="POST"
|
|
@@ -229,4 +232,8 @@
|
|
|
229
232
|
form {
|
|
230
233
|
max-width: var(--runeforge-form-max-width, 32rem);
|
|
231
234
|
}
|
|
235
|
+
|
|
236
|
+
.sticky-header {
|
|
237
|
+
top: var(--runeforge-sticky-header-top, 0);
|
|
238
|
+
}
|
|
232
239
|
</style>
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import type { ActionConfiguration
|
|
1
|
+
import type { ActionConfiguration } from '../../../types/crud/actions.js';
|
|
2
|
+
import type { FieldDefinition } from '../../../types/crud/fields.js';
|
|
2
3
|
declare function $$render<T extends object = Record<string, unknown>>(): {
|
|
3
4
|
props: {
|
|
4
5
|
labelOne?: string;
|
|
@@ -7,7 +7,8 @@
|
|
|
7
7
|
import { getIconSet } from '../../../icons/context.js';
|
|
8
8
|
import { defaultIconSet } from '../../../icons/sets/default.js';
|
|
9
9
|
import { groupFields } from '../utils/grouping.js';
|
|
10
|
-
import type { ActionConfiguration
|
|
10
|
+
import type { ActionConfiguration } from '../../../types/crud/actions.js';
|
|
11
|
+
import type { FieldDefinition } from '../../../types/crud/fields.js';
|
|
11
12
|
import { getStrings } from '../../../i18n/context.js';
|
|
12
13
|
|
|
13
14
|
const strings = getStrings();
|
|
@@ -67,13 +68,15 @@
|
|
|
67
68
|
|
|
68
69
|
<div class="flex flex-col gap-6">
|
|
69
70
|
|
|
70
|
-
<
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
{
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
71
|
+
<div class="sticky-header sticky z-10 bg-base-100 pb-2">
|
|
72
|
+
<Header
|
|
73
|
+
title={labelMany}
|
|
74
|
+
breadcrumbs={[
|
|
75
|
+
{ label: labelMany, icon: entityIcon, link: { href: '#', onclick: (e) => { e.preventDefault(); onCancel?.(); } }, prominent: true },
|
|
76
|
+
{ label: read.label ?? labelOne, icon: icons.view },
|
|
77
|
+
]}
|
|
78
|
+
/>
|
|
79
|
+
</div>
|
|
77
80
|
|
|
78
81
|
<div class="fields-panel mx-auto flex w-full flex-col gap-4 px-4">
|
|
79
82
|
{#each groups as group, i (group.title ?? `_ungrouped_${i}`)}
|
|
@@ -85,11 +88,11 @@
|
|
|
85
88
|
{#if row.length > 1}
|
|
86
89
|
<div class="flex flex-col gap-4 md:flex-row">
|
|
87
90
|
{#each row as field (field.attribute)}
|
|
88
|
-
<Field {field}
|
|
91
|
+
<Field {field} bind:record readonly class="md:min-w-0 md:flex-1" />
|
|
89
92
|
{/each}
|
|
90
93
|
</div>
|
|
91
94
|
{:else}
|
|
92
|
-
<Field field={row[0]}
|
|
95
|
+
<Field field={row[0]} bind:record readonly />
|
|
93
96
|
{/if}
|
|
94
97
|
{/each}
|
|
95
98
|
</div>
|
|
@@ -99,11 +102,11 @@
|
|
|
99
102
|
{#if row.length > 1}
|
|
100
103
|
<div class="flex flex-col gap-4 md:flex-row">
|
|
101
104
|
{#each row as field (field.attribute)}
|
|
102
|
-
<Field {field}
|
|
105
|
+
<Field {field} bind:record readonly class="md:min-w-0 md:flex-1" />
|
|
103
106
|
{/each}
|
|
104
107
|
</div>
|
|
105
108
|
{:else}
|
|
106
|
-
<Field field={row[0]}
|
|
109
|
+
<Field field={row[0]} bind:record readonly />
|
|
107
110
|
{/if}
|
|
108
111
|
{/each}
|
|
109
112
|
{/if}
|
|
@@ -121,4 +124,8 @@
|
|
|
121
124
|
.fields-panel {
|
|
122
125
|
max-width: var(--runeforge-form-max-width, 32rem);
|
|
123
126
|
}
|
|
127
|
+
|
|
128
|
+
.sticky-header {
|
|
129
|
+
top: var(--runeforge-sticky-header-top, 0);
|
|
130
|
+
}
|
|
124
131
|
</style>
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import type { ActionConfiguration
|
|
1
|
+
import type { ActionConfiguration } from '../../../types/crud/actions.js';
|
|
2
|
+
import type { FieldDefinition } from '../../../types/crud/fields.js';
|
|
2
3
|
declare function $$render<T extends object = Record<string, unknown>>(): {
|
|
3
4
|
props: {
|
|
4
5
|
labelOne?: string;
|
|
@@ -9,7 +9,8 @@
|
|
|
9
9
|
import { validateAll } from '../utils/validation.js';
|
|
10
10
|
import { groupFields } from '../utils/grouping.js';
|
|
11
11
|
import { applyDuplicateOmit, seedRecord } from '../utils/embedded.js';
|
|
12
|
-
import type { ActionConfiguration
|
|
12
|
+
import type { ActionConfiguration } from '../../../types/crud/actions.js';
|
|
13
|
+
import type { FieldDefinition } from '../../../types/crud/fields.js';
|
|
13
14
|
import { getStrings } from '../../../i18n/context.js';
|
|
14
15
|
|
|
15
16
|
const strings = getStrings();
|
|
@@ -80,26 +81,28 @@
|
|
|
80
81
|
|
|
81
82
|
<div class="flex flex-col gap-6">
|
|
82
83
|
|
|
83
|
-
<
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
{
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
<
|
|
94
|
-
<
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
84
|
+
<div class="sticky-header sticky z-10 flex flex-col gap-6 bg-base-100 pb-2">
|
|
85
|
+
<Header
|
|
86
|
+
title={labelMany}
|
|
87
|
+
breadcrumbs={[
|
|
88
|
+
{ label: labelMany, icon: entityIcon, link: { href: '#', onclick: (e) => { e.preventDefault(); onCancel?.(); } }, prominent: true },
|
|
89
|
+
{ label: update.label ?? labelOne, icon: icons.edit },
|
|
90
|
+
]}
|
|
91
|
+
/>
|
|
92
|
+
|
|
93
|
+
{#if errorEntries.length > 0}
|
|
94
|
+
<div role="alert" class="alert alert-error">
|
|
95
|
+
<svg xmlns="http://www.w3.org/2000/svg" class="h-5 w-5 shrink-0" fill="none" viewBox="0 0 24 24" stroke="currentColor">
|
|
96
|
+
<path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M10 14l2-2m0 0l2-2m-2 2l-2-2m2 2l2 2m7-2a9 9 0 11-18 0 9 9 0 0118 0z" />
|
|
97
|
+
</svg>
|
|
98
|
+
<ul class="list-disc list-inside text-sm">
|
|
99
|
+
{#each errorEntries as [key, msg] (key)}
|
|
100
|
+
<li>{msg}</li>
|
|
101
|
+
{/each}
|
|
102
|
+
</ul>
|
|
103
|
+
</div>
|
|
104
|
+
{/if}
|
|
105
|
+
</div>
|
|
103
106
|
|
|
104
107
|
<form
|
|
105
108
|
method="POST"
|
|
@@ -205,4 +208,8 @@
|
|
|
205
208
|
form {
|
|
206
209
|
max-width: var(--runeforge-form-max-width, 32rem);
|
|
207
210
|
}
|
|
211
|
+
|
|
212
|
+
.sticky-header {
|
|
213
|
+
top: var(--runeforge-sticky-header-top, 0);
|
|
214
|
+
}
|
|
208
215
|
</style>
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import type { ActionConfiguration
|
|
1
|
+
import type { ActionConfiguration } from '../../../types/crud/actions.js';
|
|
2
|
+
import type { FieldDefinition } from '../../../types/crud/fields.js';
|
|
2
3
|
declare function $$render<T extends object = Record<string, unknown>>(): {
|
|
3
4
|
props: {
|
|
4
5
|
labelOne?: string;
|
|
@@ -7,13 +7,13 @@
|
|
|
7
7
|
import { computeReorderChanges } from '../../utils/reorder.js';
|
|
8
8
|
import type {
|
|
9
9
|
ActionConfiguration,
|
|
10
|
-
ColumnDefinition,
|
|
11
10
|
CustomAction,
|
|
12
11
|
CustomBulkAction,
|
|
13
12
|
ListActions,
|
|
14
|
-
ListConfig,
|
|
15
13
|
ViewBasedCustomBulkAction
|
|
16
|
-
} from '../../../../types/crud.js';
|
|
14
|
+
} from '../../../../types/crud/actions.js';
|
|
15
|
+
import type { ColumnDefinition } from '../../../../types/crud/columns.js';
|
|
16
|
+
import type { ListConfig } from '../../../../types/crud/list-config.js';
|
|
17
17
|
import type {
|
|
18
18
|
FilterSnapshot,
|
|
19
19
|
ServerPagination,
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
import type { ActionConfiguration,
|
|
1
|
+
import type { ActionConfiguration, CustomAction, ListActions, ViewBasedCustomBulkAction } from '../../../../types/crud/actions.js';
|
|
2
|
+
import type { ColumnDefinition } from '../../../../types/crud/columns.js';
|
|
3
|
+
import type { ListConfig } from '../../../../types/crud/list-config.js';
|
|
2
4
|
import type { FilterSnapshot, ServerPagination, SortDirection, TableQuery } from '../../../../types/table.js';
|
|
3
5
|
declare function $$render<T extends object = Record<string, unknown>>(): {
|
|
4
6
|
props: {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<script lang="ts" generics="T extends object = Record<string, unknown>">
|
|
2
2
|
import Button from '../../../form/Button.svelte';
|
|
3
3
|
import Modal from '../../../Modal.svelte';
|
|
4
|
-
import type { CustomBulkAction } from '../../../../types/crud.js';
|
|
4
|
+
import type { CustomBulkAction } from '../../../../types/crud/actions.js';
|
|
5
5
|
import { getStrings } from '../../../../i18n/context.js';
|
|
6
6
|
|
|
7
7
|
const strings = getStrings();
|
|
@@ -4,12 +4,9 @@
|
|
|
4
4
|
import PaginatedTable from '../../../table/PaginatedTable.svelte';
|
|
5
5
|
import { getIconSet } from '../../../../icons/context.js';
|
|
6
6
|
import { defaultIconSet } from '../../../../icons/sets/default.js';
|
|
7
|
-
import type {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
ReorderConfiguration,
|
|
11
|
-
RowAction
|
|
12
|
-
} from '../../../../types/crud.js';
|
|
7
|
+
import type { ColumnDefinition } from '../../../../types/crud/columns.js';
|
|
8
|
+
import type { CustomAction, RowAction } from '../../../../types/crud/actions.js';
|
|
9
|
+
import type { ReorderConfiguration } from '../../../../types/crud/reorder.js';
|
|
13
10
|
import type {
|
|
14
11
|
FilterSnapshot,
|
|
15
12
|
ServerPagination,
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { SvelteSet } from 'svelte/reactivity';
|
|
2
|
-
import type { ColumnDefinition
|
|
2
|
+
import type { ColumnDefinition } from '../../../../types/crud/columns.js';
|
|
3
|
+
import type { CustomAction } from '../../../../types/crud/actions.js';
|
|
4
|
+
import type { ReorderConfiguration } from '../../../../types/crud/reorder.js';
|
|
3
5
|
import type { FilterSnapshot, ServerPagination, SortDirection, TableQuery } from '../../../../types/table.js';
|
|
4
6
|
declare function $$render<T extends object = Record<string, unknown>>(): {
|
|
5
7
|
props: {
|