firstly 0.0.15 → 0.0.16-next.0
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/CHANGELOG.md +8 -0
- package/esm/ROUTES.d.ts +10 -2
- package/esm/ROUTES.js +5 -1
- package/esm/auth/Entities.js +1 -0
- package/esm/auth/server/handleAuth.js +2 -1
- package/esm/auth/server/handleGuard.d.ts +10 -4
- package/esm/auth/server/handleGuard.js +8 -41
- package/esm/auth/server/module.d.ts +28 -0
- package/esm/auth/server/module.js +3 -0
- package/esm/auth/static/assets/{Page-B1GE_oYi.d.ts → Page-BgIgl-Te.d.ts} +2 -2
- package/esm/auth/static/assets/{Page-CDHFtYuN.js → Page-BgIgl-Te.js} +1 -1
- package/esm/auth/static/assets/{Page-Dh8pvAo6.d.ts → Page-HDnoBhpE.d.ts} +2 -2
- package/esm/auth/static/assets/{Page-Dh8pvAo6.js → Page-HDnoBhpE.js} +2 -2
- package/esm/auth/static/assets/{Page-CDHFtYuN.d.ts → Page-f5pC21Yg.d.ts} +2 -2
- package/esm/auth/static/assets/{Page-B1GE_oYi.js → Page-f5pC21Yg.js} +1 -1
- package/esm/auth/static/assets/{index-7Nh2ct-y.js → index-DAjei0Ie.js} +2 -2
- package/esm/auth/static/index.html +4 -4
- package/esm/auth/types.d.ts +1 -0
- package/esm/helper.d.ts +1 -1
- package/esm/helper.js +4 -3
- package/esm/index.d.ts +5 -3
- package/esm/index.js +5 -3
- package/esm/mail/server/index.js +2 -1
- package/esm/svelte/FF_Cell.svelte +104 -0
- package/esm/svelte/FF_Cell.svelte.d.ts +24 -0
- package/esm/svelte/FF_Cell_Caption.svelte +20 -0
- package/esm/svelte/FF_Cell_Caption.svelte.d.ts +24 -0
- package/esm/svelte/FF_Cell_Display.svelte +61 -0
- package/esm/svelte/FF_Cell_Display.svelte.d.ts +22 -0
- package/esm/svelte/FF_Cell_Edit.svelte +104 -0
- package/esm/svelte/FF_Cell_Edit.svelte.d.ts +25 -0
- package/esm/svelte/FF_Cell_Error.svelte +20 -0
- package/esm/svelte/FF_Cell_Error.svelte.d.ts +24 -0
- package/esm/svelte/FF_Cell_Hint.svelte +20 -0
- package/esm/svelte/FF_Cell_Hint.svelte.d.ts +24 -0
- package/esm/svelte/FF_Config.svelte +29 -0
- package/esm/svelte/FF_Config.svelte.d.ts +9 -0
- package/esm/svelte/FF_Display.svelte +51 -0
- package/esm/svelte/FF_Display.svelte.d.ts +22 -0
- package/esm/svelte/FF_Edit.svelte +104 -0
- package/esm/svelte/FF_Edit.svelte.d.ts +25 -0
- package/esm/svelte/FF_Error.svelte +23 -0
- package/esm/svelte/FF_Error.svelte.d.ts +22 -0
- package/esm/svelte/FF_Field.svelte +62 -0
- package/esm/svelte/FF_Field.svelte.d.ts +22 -0
- package/esm/svelte/FF_Form.svelte +156 -0
- package/esm/svelte/FF_Form.svelte.d.ts +30 -0
- package/esm/svelte/FF_Grid.svelte +257 -0
- package/esm/svelte/FF_Grid.svelte.d.ts +31 -0
- package/esm/svelte/FF_Hint.svelte +21 -0
- package/esm/svelte/FF_Hint.svelte.d.ts +22 -0
- package/esm/svelte/FF_Label.svelte +23 -0
- package/esm/svelte/FF_Label.svelte.d.ts +22 -0
- package/esm/svelte/FF_Layout.svelte +62 -0
- package/esm/svelte/FF_Layout.svelte.d.ts +24 -0
- package/esm/svelte/FF_Repo.svelte.d.ts +69 -0
- package/esm/svelte/FF_Repo.svelte.js +170 -0
- package/esm/svelte/actions/intersection.d.ts +6 -0
- package/esm/svelte/actions/intersection.js +17 -0
- package/esm/svelte/class/SP.svelte.d.ts +61 -0
- package/esm/svelte/class/SP.svelte.js +412 -0
- package/esm/svelte/customField.d.ts +69 -0
- package/esm/svelte/customField.js +4 -0
- package/esm/svelte/dialog/DialogManagement.svelte +101 -0
- package/esm/svelte/dialog/DialogManagement.svelte.d.ts +18 -0
- package/esm/svelte/dialog/DialogPrimitive.svelte +157 -0
- package/esm/svelte/dialog/DialogPrimitive.svelte.d.ts +38 -0
- package/esm/svelte/dialog/dialog.d.ts +58 -0
- package/esm/svelte/dialog/dialog.js +130 -0
- package/esm/svelte/ff_Config.svelte.d.ts +91 -0
- package/esm/svelte/ff_Config.svelte.js +111 -0
- package/esm/svelte/firstly.css +14 -0
- package/esm/svelte/helpers/debounce.d.ts +1 -0
- package/esm/svelte/helpers/debounce.js +7 -0
- package/esm/svelte/helpers.d.ts +29 -0
- package/esm/svelte/helpers.js +38 -0
- package/esm/svelte/index.d.ts +32 -0
- package/esm/svelte/index.js +29 -0
- package/esm/svelte/tryCatch.d.ts +12 -0
- package/esm/svelte/tryCatch.js +18 -0
- package/esm/ui/Field.svelte +1 -1
- package/esm/ui/Grid.svelte +8 -2
- package/esm/ui/Grid2.svelte +354 -0
- package/esm/ui/Grid2.svelte.d.ts +58 -0
- package/esm/ui/GridLoading.svelte +33 -8
- package/esm/ui/GridLoading.svelte.d.ts +1 -0
- package/esm/ui/GridPaginate.svelte +0 -3
- package/esm/ui/GridPaginate.svelte.d.ts +0 -1
- package/esm/ui/GridPaginate2.svelte +25 -0
- package/esm/ui/GridPaginate2.svelte.d.ts +7 -0
- package/esm/ui/dialog/dialog.d.ts +3 -1
- package/esm/ui/dialog/dialog.js +2 -0
- package/esm/ui/link/LinkPlus.svelte +8 -6
- package/package.json +17 -2
- /package/esm/auth/static/assets/{index-7Nh2ct-y.d.ts → index-DAjei0Ie.d.ts} +0 -0
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
<script lang="ts" generics="valueType = unknown, entityType = unknown">
|
|
2
|
+
import type { CellMetadata } from './customField'
|
|
3
|
+
|
|
4
|
+
interface Props<valueType = unknown, entityType = unknown> {
|
|
5
|
+
key: string
|
|
6
|
+
ui: CellMetadata<valueType, entityType>['ui']
|
|
7
|
+
error?: string
|
|
8
|
+
class?: string
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
let { ui, key, class: localClass, error }: Props<valueType, entityType> = $props()
|
|
12
|
+
</script>
|
|
13
|
+
|
|
14
|
+
{#if ui?.component?.error === undefined || ui?.component?.error === 'show'}
|
|
15
|
+
<label data-ff-cell-error for={key} class={localClass}>{@html error}</label>
|
|
16
|
+
{:else if ui?.component?.error === 'remove'}
|
|
17
|
+
<!-- Nothing -->
|
|
18
|
+
{:else if ui?.component?.error === 'hide'}
|
|
19
|
+
<span data-ff-cell-error class={localClass}></span>
|
|
20
|
+
{/if}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { CellMetadata } from './customField';
|
|
2
|
+
interface Props<valueType = unknown, entityType = unknown> {
|
|
3
|
+
key: string;
|
|
4
|
+
ui: CellMetadata<valueType, entityType>['ui'];
|
|
5
|
+
error?: string;
|
|
6
|
+
class?: string;
|
|
7
|
+
}
|
|
8
|
+
declare class __sveltets_Render<valueType = unknown, entityType = unknown> {
|
|
9
|
+
props(): Props<valueType, entityType>;
|
|
10
|
+
events(): {};
|
|
11
|
+
slots(): {};
|
|
12
|
+
bindings(): "";
|
|
13
|
+
exports(): {};
|
|
14
|
+
}
|
|
15
|
+
interface $$IsomorphicComponent {
|
|
16
|
+
new <valueType = unknown, entityType = unknown>(options: import('svelte').ComponentConstructorOptions<ReturnType<__sveltets_Render<valueType, entityType>['props']>>): import('svelte').SvelteComponent<ReturnType<__sveltets_Render<valueType, entityType>['props']>, ReturnType<__sveltets_Render<valueType, entityType>['events']>, ReturnType<__sveltets_Render<valueType, entityType>['slots']>> & {
|
|
17
|
+
$$bindings?: ReturnType<__sveltets_Render<valueType, entityType>['bindings']>;
|
|
18
|
+
} & ReturnType<__sveltets_Render<valueType, entityType>['exports']>;
|
|
19
|
+
<valueType = unknown, entityType = unknown>(internal: unknown, props: ReturnType<__sveltets_Render<valueType, entityType>['props']> & {}): ReturnType<__sveltets_Render<valueType, entityType>['exports']>;
|
|
20
|
+
z_$$bindings?: ReturnType<__sveltets_Render<any, any>['bindings']>;
|
|
21
|
+
}
|
|
22
|
+
declare const FfCellError: $$IsomorphicComponent;
|
|
23
|
+
type FfCellError<valueType = unknown, entityType = unknown> = InstanceType<typeof FfCellError<valueType, entityType>>;
|
|
24
|
+
export default FfCellError;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
<script lang="ts" generics="valueType = unknown, entityType = unknown">
|
|
2
|
+
import type { CellMetadata } from './customField'
|
|
3
|
+
|
|
4
|
+
interface Props<valueType = unknown, entityType = unknown> {
|
|
5
|
+
key: string
|
|
6
|
+
ui: CellMetadata<valueType, entityType>['ui']
|
|
7
|
+
hint?: string
|
|
8
|
+
class?: string
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
let { ui, key, class: localClass, hint }: Props<valueType, entityType> = $props()
|
|
12
|
+
</script>
|
|
13
|
+
|
|
14
|
+
{#if ui?.component?.hint === undefined || ui?.component?.hint === 'show'}
|
|
15
|
+
<label data-ff-cell-hint for={key} class={localClass}>{@html hint}</label>
|
|
16
|
+
{:else if ui?.component?.hint === 'remove'}
|
|
17
|
+
<!-- Nothing -->
|
|
18
|
+
{:else if ui?.component?.hint === 'hide'}
|
|
19
|
+
<span data-ff-cell-hint class={localClass}></span>
|
|
20
|
+
{/if}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { CellMetadata } from './customField';
|
|
2
|
+
interface Props<valueType = unknown, entityType = unknown> {
|
|
3
|
+
key: string;
|
|
4
|
+
ui: CellMetadata<valueType, entityType>['ui'];
|
|
5
|
+
hint?: string;
|
|
6
|
+
class?: string;
|
|
7
|
+
}
|
|
8
|
+
declare class __sveltets_Render<valueType = unknown, entityType = unknown> {
|
|
9
|
+
props(): Props<valueType, entityType>;
|
|
10
|
+
events(): {};
|
|
11
|
+
slots(): {};
|
|
12
|
+
bindings(): "";
|
|
13
|
+
exports(): {};
|
|
14
|
+
}
|
|
15
|
+
interface $$IsomorphicComponent {
|
|
16
|
+
new <valueType = unknown, entityType = unknown>(options: import('svelte').ComponentConstructorOptions<ReturnType<__sveltets_Render<valueType, entityType>['props']>>): import('svelte').SvelteComponent<ReturnType<__sveltets_Render<valueType, entityType>['props']>, ReturnType<__sveltets_Render<valueType, entityType>['events']>, ReturnType<__sveltets_Render<valueType, entityType>['slots']>> & {
|
|
17
|
+
$$bindings?: ReturnType<__sveltets_Render<valueType, entityType>['bindings']>;
|
|
18
|
+
} & ReturnType<__sveltets_Render<valueType, entityType>['exports']>;
|
|
19
|
+
<valueType = unknown, entityType = unknown>(internal: unknown, props: ReturnType<__sveltets_Render<valueType, entityType>['props']> & {}): ReturnType<__sveltets_Render<valueType, entityType>['exports']>;
|
|
20
|
+
z_$$bindings?: ReturnType<__sveltets_Render<any, any>['bindings']>;
|
|
21
|
+
}
|
|
22
|
+
declare const FfCellHint: $$IsomorphicComponent;
|
|
23
|
+
type FfCellHint<valueType = unknown, entityType = unknown> = InstanceType<typeof FfCellHint<valueType, entityType>>;
|
|
24
|
+
export default FfCellHint;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { FF_Theme, setDynamicCustomField } from './'
|
|
3
|
+
import type { DynamicCustomField, Theme } from './'
|
|
4
|
+
import DialogManagement from './dialog/DialogManagement.svelte'
|
|
5
|
+
|
|
6
|
+
interface Props {
|
|
7
|
+
theme: Theme
|
|
8
|
+
dynamicCustomField?: DynamicCustomField
|
|
9
|
+
children?: import('svelte').Snippet
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
const { theme, dynamicCustomField, children }: Props = $props()
|
|
13
|
+
|
|
14
|
+
// Create a reactive theme instance
|
|
15
|
+
const themeManager = $state(new FF_Theme(theme))
|
|
16
|
+
|
|
17
|
+
// Update theme when prop changes
|
|
18
|
+
$effect(() => {
|
|
19
|
+
themeManager.setTheme(theme)
|
|
20
|
+
})
|
|
21
|
+
|
|
22
|
+
if (dynamicCustomField) {
|
|
23
|
+
setDynamicCustomField(dynamicCustomField)
|
|
24
|
+
}
|
|
25
|
+
</script>
|
|
26
|
+
|
|
27
|
+
<DialogManagement />
|
|
28
|
+
|
|
29
|
+
{@render children?.()}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { DynamicCustomField, Theme } from './';
|
|
2
|
+
interface Props {
|
|
3
|
+
theme: Theme;
|
|
4
|
+
dynamicCustomField?: DynamicCustomField;
|
|
5
|
+
children?: import('svelte').Snippet;
|
|
6
|
+
}
|
|
7
|
+
declare const FfConfig: import("svelte").Component<Props, {}, "">;
|
|
8
|
+
type FfConfig = ReturnType<typeof FfConfig>;
|
|
9
|
+
export default FfConfig;
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
<script lang="ts" generics="valueType = unknown, entityType = unknown">
|
|
2
|
+
import { getClasses, getDynamicCustomField, type DisplayTheme } from './'
|
|
3
|
+
import { isComponentObject, type CustomFieldDefaultProps } from './customField'
|
|
4
|
+
|
|
5
|
+
interface Props extends CustomFieldDefaultProps {
|
|
6
|
+
classes?: DisplayTheme
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
let { field, value, error, classes: localClasses = {} }: Props = $props()
|
|
10
|
+
|
|
11
|
+
// let valueList = getValueList(field) as { id: string; caption: string }[] | undefined
|
|
12
|
+
|
|
13
|
+
let classes = $derived(getClasses('display', localClasses))
|
|
14
|
+
const dynamicCustomField = getDynamicCustomField()?.({ field, value, error, mode: 'display' })
|
|
15
|
+
</script>
|
|
16
|
+
|
|
17
|
+
{#if field.options.ui?.component?.display}
|
|
18
|
+
{@const customField = field.options.ui?.component?.display}
|
|
19
|
+
{#if isComponentObject(customField)}
|
|
20
|
+
{@const Component = customField.component}
|
|
21
|
+
<Component {field} bind:value {error} {...customField.props} />
|
|
22
|
+
{:else}
|
|
23
|
+
{@const Component = customField}
|
|
24
|
+
<Component {field} bind:value {error} />
|
|
25
|
+
{/if}
|
|
26
|
+
{:else if dynamicCustomField}
|
|
27
|
+
{#if isComponentObject(dynamicCustomField)}
|
|
28
|
+
{@const Component = dynamicCustomField.component}
|
|
29
|
+
<Component {field} bind:value {error} {...dynamicCustomField.props} />
|
|
30
|
+
{:else}
|
|
31
|
+
{@const Component = dynamicCustomField}
|
|
32
|
+
<Component {field} bind:value {error} />
|
|
33
|
+
{/if}
|
|
34
|
+
{:else if field.inputType === 'checkbox'}
|
|
35
|
+
<input
|
|
36
|
+
disabled
|
|
37
|
+
data-ff-display-checkbox
|
|
38
|
+
class={classes?.checkbox}
|
|
39
|
+
type="checkbox"
|
|
40
|
+
checked={value as boolean}
|
|
41
|
+
/>
|
|
42
|
+
{:else}
|
|
43
|
+
{field.displayValue({ [field.key]: value } as Partial<entityType>)}
|
|
44
|
+
{/if}
|
|
45
|
+
|
|
46
|
+
<style>
|
|
47
|
+
[data-ff-display-checkbox] {
|
|
48
|
+
display: block;
|
|
49
|
+
margin: 0 auto;
|
|
50
|
+
}
|
|
51
|
+
</style>
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { type DisplayTheme } from './';
|
|
2
|
+
import { type CustomFieldDefaultProps } from './customField';
|
|
3
|
+
interface Props extends CustomFieldDefaultProps {
|
|
4
|
+
classes?: DisplayTheme;
|
|
5
|
+
}
|
|
6
|
+
declare class __sveltets_Render<valueType = unknown, entityType = unknown> {
|
|
7
|
+
props(): Props;
|
|
8
|
+
events(): {};
|
|
9
|
+
slots(): {};
|
|
10
|
+
bindings(): "";
|
|
11
|
+
exports(): {};
|
|
12
|
+
}
|
|
13
|
+
interface $$IsomorphicComponent {
|
|
14
|
+
new <valueType = unknown, entityType = unknown>(options: import('svelte').ComponentConstructorOptions<ReturnType<__sveltets_Render<valueType, entityType>['props']>>): import('svelte').SvelteComponent<ReturnType<__sveltets_Render<valueType, entityType>['props']>, ReturnType<__sveltets_Render<valueType, entityType>['events']>, ReturnType<__sveltets_Render<valueType, entityType>['slots']>> & {
|
|
15
|
+
$$bindings?: ReturnType<__sveltets_Render<valueType, entityType>['bindings']>;
|
|
16
|
+
} & ReturnType<__sveltets_Render<valueType, entityType>['exports']>;
|
|
17
|
+
<valueType = unknown, entityType = unknown>(internal: unknown, props: ReturnType<__sveltets_Render<valueType, entityType>['props']> & {}): ReturnType<__sveltets_Render<valueType, entityType>['exports']>;
|
|
18
|
+
z_$$bindings?: ReturnType<__sveltets_Render<any, any>['bindings']>;
|
|
19
|
+
}
|
|
20
|
+
declare const FfDisplay: $$IsomorphicComponent;
|
|
21
|
+
type FfDisplay<valueType = unknown, entityType = unknown> = InstanceType<typeof FfDisplay<valueType, entityType>>;
|
|
22
|
+
export default FfDisplay;
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
<script lang="ts" generics="valueType = unknown, entityType = unknown">
|
|
2
|
+
import { getValueList, type FieldMetadata } from 'remult'
|
|
3
|
+
|
|
4
|
+
import { getClasses, getDynamicCustomField } from '.'
|
|
5
|
+
import type { EditTheme } from './'
|
|
6
|
+
import { isComponentObject } from './customField'
|
|
7
|
+
|
|
8
|
+
const default_uid = $props.id()
|
|
9
|
+
|
|
10
|
+
interface Props {
|
|
11
|
+
uid?: string
|
|
12
|
+
field: FieldMetadata<valueType, entityType>
|
|
13
|
+
value: valueType
|
|
14
|
+
error?: string
|
|
15
|
+
classes?: EditTheme
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
let {
|
|
19
|
+
uid = default_uid,
|
|
20
|
+
field,
|
|
21
|
+
value = $bindable(),
|
|
22
|
+
error,
|
|
23
|
+
classes: localClasses = {},
|
|
24
|
+
}: Props = $props()
|
|
25
|
+
|
|
26
|
+
let valueList = getValueList(field) as { id: string; caption: string }[] | undefined
|
|
27
|
+
|
|
28
|
+
let classes = $derived(getClasses('edit', localClasses))
|
|
29
|
+
const dynamicCustomField = getDynamicCustomField()?.({ field, value, error, mode: 'edit' })
|
|
30
|
+
|
|
31
|
+
const fromInput = (val: any) => {
|
|
32
|
+
// console.log(`fromInput`, val)
|
|
33
|
+
const res = field.valueConverter.fromInput(val)
|
|
34
|
+
// if (res && field.inputType === 'datetime-local') {
|
|
35
|
+
// const date = new Date(res)
|
|
36
|
+
// date.setMinutes(date.getMinutes() - date.getTimezoneOffset())
|
|
37
|
+
// return date.toISOString().slice(0, 16)
|
|
38
|
+
// }
|
|
39
|
+
return res
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
const toInput = (val: any) => {
|
|
43
|
+
// console.log(`toInput1`, val)
|
|
44
|
+
const res = field.valueConverter.toInput(val)
|
|
45
|
+
// console.log(`toInput2`, res)
|
|
46
|
+
return res
|
|
47
|
+
}
|
|
48
|
+
</script>
|
|
49
|
+
|
|
50
|
+
{#if field.options.ui?.component?.edit}
|
|
51
|
+
{@const customField = field.options.ui?.component?.edit}
|
|
52
|
+
{#if isComponentObject(customField)}
|
|
53
|
+
{@const Component = customField.component}
|
|
54
|
+
<Component {field} bind:value {error} {...customField.props} />
|
|
55
|
+
{:else}
|
|
56
|
+
{@const Component = customField}
|
|
57
|
+
<Component {field} bind:value {error} />
|
|
58
|
+
{/if}
|
|
59
|
+
{:else if dynamicCustomField}
|
|
60
|
+
{#if isComponentObject(dynamicCustomField)}
|
|
61
|
+
{@const Component = dynamicCustomField.component}
|
|
62
|
+
<Component {field} bind:value {error} {...dynamicCustomField.props} />
|
|
63
|
+
{:else}
|
|
64
|
+
{@const Component = dynamicCustomField}
|
|
65
|
+
<Component {field} bind:value {error} />
|
|
66
|
+
{/if}
|
|
67
|
+
{:else if valueList}
|
|
68
|
+
<select data-ff-edit-select class={classes?.select} id={uid} bind:value>
|
|
69
|
+
{#each valueList as item (item.id)}
|
|
70
|
+
<option value={item}>{item.caption}</option>
|
|
71
|
+
{/each}
|
|
72
|
+
</select>
|
|
73
|
+
{:else if field.inputType === 'checkbox'}
|
|
74
|
+
<div style="display: flex; align-items: center; height: 3rem;">
|
|
75
|
+
<input
|
|
76
|
+
data-ff-edit-checkbox
|
|
77
|
+
class={classes?.checkbox}
|
|
78
|
+
id={uid}
|
|
79
|
+
type="checkbox"
|
|
80
|
+
bind:checked={value as boolean}
|
|
81
|
+
/>
|
|
82
|
+
</div>
|
|
83
|
+
{:else}
|
|
84
|
+
<input
|
|
85
|
+
autocomplete="off"
|
|
86
|
+
data-ff-edit-input
|
|
87
|
+
class={classes?.input}
|
|
88
|
+
id={uid}
|
|
89
|
+
type={field.options.inputType}
|
|
90
|
+
placeholder={field.options.ui?.placeholder}
|
|
91
|
+
bind:value={() => fromInput(value as any), (v) => (value = toInput(v) as valueType)}
|
|
92
|
+
step={field.options.ui?.step}
|
|
93
|
+
/>
|
|
94
|
+
{/if}
|
|
95
|
+
|
|
96
|
+
<style>
|
|
97
|
+
input[data-ff-edit-input] {
|
|
98
|
+
width: 100%;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
select[data-ff-edit-select] {
|
|
102
|
+
width: 100%;
|
|
103
|
+
}
|
|
104
|
+
</style>
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { type FieldMetadata } from 'remult';
|
|
2
|
+
import type { EditTheme } from './';
|
|
3
|
+
declare class __sveltets_Render<valueType = unknown, entityType = unknown> {
|
|
4
|
+
props(): {
|
|
5
|
+
uid?: string;
|
|
6
|
+
field: FieldMetadata<valueType, entityType>;
|
|
7
|
+
value: valueType;
|
|
8
|
+
error?: string;
|
|
9
|
+
classes?: EditTheme;
|
|
10
|
+
};
|
|
11
|
+
events(): {};
|
|
12
|
+
slots(): {};
|
|
13
|
+
bindings(): "value";
|
|
14
|
+
exports(): {};
|
|
15
|
+
}
|
|
16
|
+
interface $$IsomorphicComponent {
|
|
17
|
+
new <valueType = unknown, entityType = unknown>(options: import('svelte').ComponentConstructorOptions<ReturnType<__sveltets_Render<valueType, entityType>['props']>>): import('svelte').SvelteComponent<ReturnType<__sveltets_Render<valueType, entityType>['props']>, ReturnType<__sveltets_Render<valueType, entityType>['events']>, ReturnType<__sveltets_Render<valueType, entityType>['slots']>> & {
|
|
18
|
+
$$bindings?: ReturnType<__sveltets_Render<valueType, entityType>['bindings']>;
|
|
19
|
+
} & ReturnType<__sveltets_Render<valueType, entityType>['exports']>;
|
|
20
|
+
<valueType = unknown, entityType = unknown>(internal: unknown, props: ReturnType<__sveltets_Render<valueType, entityType>['props']> & {}): ReturnType<__sveltets_Render<valueType, entityType>['exports']>;
|
|
21
|
+
z_$$bindings?: ReturnType<__sveltets_Render<any, any>['bindings']>;
|
|
22
|
+
}
|
|
23
|
+
declare const FfEdit: $$IsomorphicComponent;
|
|
24
|
+
type FfEdit<valueType = unknown, entityType = unknown> = InstanceType<typeof FfEdit<valueType, entityType>>;
|
|
25
|
+
export default FfEdit;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
<script lang="ts" generics="valueType = unknown, entityType = unknown">
|
|
2
|
+
import { getClasses } from '.'
|
|
3
|
+
import type { CustomFieldDefaultProps } from './customField'
|
|
4
|
+
import type { ErrorTheme } from './ff_Config.svelte'
|
|
5
|
+
|
|
6
|
+
const default_uid = $props.id()
|
|
7
|
+
|
|
8
|
+
interface Props extends CustomFieldDefaultProps {
|
|
9
|
+
classes?: ErrorTheme
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
let { uid = default_uid, field, value, error, classes: localClasses = {} }: Props = $props()
|
|
13
|
+
|
|
14
|
+
let classes = $derived(getClasses('error', localClasses))
|
|
15
|
+
</script>
|
|
16
|
+
|
|
17
|
+
{#if field.options.ui?.component?.error === undefined || field.options.ui?.component?.error === 'show'}
|
|
18
|
+
<div data-ff-field-error class={classes.root}>{@html error}</div>
|
|
19
|
+
{:else if field.options.ui?.component?.error === 'remove'}
|
|
20
|
+
<!-- Nothing -->
|
|
21
|
+
{:else if field.options.ui?.component?.error === 'hide'}
|
|
22
|
+
<span class={classes.root}></span>
|
|
23
|
+
{/if}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { CustomFieldDefaultProps } from './customField';
|
|
2
|
+
import type { ErrorTheme } from './ff_Config.svelte';
|
|
3
|
+
interface Props extends CustomFieldDefaultProps {
|
|
4
|
+
classes?: ErrorTheme;
|
|
5
|
+
}
|
|
6
|
+
declare class __sveltets_Render<valueType = unknown, entityType = unknown> {
|
|
7
|
+
props(): Props;
|
|
8
|
+
events(): {};
|
|
9
|
+
slots(): {};
|
|
10
|
+
bindings(): "";
|
|
11
|
+
exports(): {};
|
|
12
|
+
}
|
|
13
|
+
interface $$IsomorphicComponent {
|
|
14
|
+
new <valueType = unknown, entityType = unknown>(options: import('svelte').ComponentConstructorOptions<ReturnType<__sveltets_Render<valueType, entityType>['props']>>): import('svelte').SvelteComponent<ReturnType<__sveltets_Render<valueType, entityType>['props']>, ReturnType<__sveltets_Render<valueType, entityType>['events']>, ReturnType<__sveltets_Render<valueType, entityType>['slots']>> & {
|
|
15
|
+
$$bindings?: ReturnType<__sveltets_Render<valueType, entityType>['bindings']>;
|
|
16
|
+
} & ReturnType<__sveltets_Render<valueType, entityType>['exports']>;
|
|
17
|
+
<valueType = unknown, entityType = unknown>(internal: unknown, props: ReturnType<__sveltets_Render<valueType, entityType>['props']> & {}): ReturnType<__sveltets_Render<valueType, entityType>['exports']>;
|
|
18
|
+
z_$$bindings?: ReturnType<__sveltets_Render<any, any>['bindings']>;
|
|
19
|
+
}
|
|
20
|
+
declare const FfError: $$IsomorphicComponent;
|
|
21
|
+
type FfError<valueType = unknown, entityType = unknown> = InstanceType<typeof FfError<valueType, entityType>>;
|
|
22
|
+
export default FfError;
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
<script lang="ts" generics="valueType = unknown, entityType = unknown">
|
|
2
|
+
import { FF_Edit, FF_Error, FF_Hint, FF_Label, getClasses, type FieldTheme } from './'
|
|
3
|
+
import type { CustomFieldDefaultProps } from './customField'
|
|
4
|
+
|
|
5
|
+
const default_uid = $props.id()
|
|
6
|
+
|
|
7
|
+
interface Props extends CustomFieldDefaultProps {
|
|
8
|
+
classes?: FieldTheme
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
let {
|
|
12
|
+
uid = default_uid,
|
|
13
|
+
field,
|
|
14
|
+
value = $bindable(),
|
|
15
|
+
error,
|
|
16
|
+
classes: localClasses = {},
|
|
17
|
+
}: Props = $props()
|
|
18
|
+
|
|
19
|
+
let classes = $derived(getClasses('field', localClasses))
|
|
20
|
+
</script>
|
|
21
|
+
|
|
22
|
+
<div
|
|
23
|
+
data-ff-field
|
|
24
|
+
class={classes.root}
|
|
25
|
+
style:--width={field.options.ui?.width}
|
|
26
|
+
style:--margin-left={field.options.ui?.marginLeft}
|
|
27
|
+
style:--margin-right={field.options.ui?.marginRight}
|
|
28
|
+
style:--width-mobile={field.options.ui?.mobile?.width}
|
|
29
|
+
style:--margin-left-mobile={field.options.ui?.mobile?.marginLeft}
|
|
30
|
+
style:--margin-right-mobile={field.options.ui?.mobile?.marginRight}
|
|
31
|
+
>
|
|
32
|
+
<FF_Label {uid} {field} {error} {value} />
|
|
33
|
+
<FF_Error {uid} {field} {error} {value} />
|
|
34
|
+
<FF_Edit {uid} {field} {error} bind:value />
|
|
35
|
+
<FF_Hint {uid} {field} {error} {value} />
|
|
36
|
+
</div>
|
|
37
|
+
|
|
38
|
+
<style>
|
|
39
|
+
[data-ff-field] {
|
|
40
|
+
display: flex;
|
|
41
|
+
flex-direction: column;
|
|
42
|
+
box-sizing: border-box;
|
|
43
|
+
flex: 1 1 calc(var(--width, 100) * 1%);
|
|
44
|
+
max-width: calc(var(--width, 100) * 1%);
|
|
45
|
+
padding: var(--ff-spacing);
|
|
46
|
+
margin-left: calc(var(--margin-left, 0) * 1%);
|
|
47
|
+
margin-right: calc(var(--margin-right, 0) * 1%);
|
|
48
|
+
|
|
49
|
+
/* For debugging purposes - outline that doesn't affect layout */
|
|
50
|
+
/* outline: 1px solid rgba(255, 0, 0, 0.5);
|
|
51
|
+
outline-offset: -1px; */
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
@media screen and (max-width: 40rem) {
|
|
55
|
+
[data-ff-field] {
|
|
56
|
+
flex: 1 1 calc(var(--width-mobile, 100) * 1%);
|
|
57
|
+
max-width: calc(var(--width-mobile, 100) * 1%);
|
|
58
|
+
margin-left: calc(var(--margin-left-mobile, 0) * 1%);
|
|
59
|
+
margin-right: calc(var(--margin-right-mobile, 0) * 1%);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
</style>
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { type FieldTheme } from './';
|
|
2
|
+
import type { CustomFieldDefaultProps } from './customField';
|
|
3
|
+
interface Props extends CustomFieldDefaultProps {
|
|
4
|
+
classes?: FieldTheme;
|
|
5
|
+
}
|
|
6
|
+
declare class __sveltets_Render<valueType = unknown, entityType = unknown> {
|
|
7
|
+
props(): Props;
|
|
8
|
+
events(): {};
|
|
9
|
+
slots(): {};
|
|
10
|
+
bindings(): "value";
|
|
11
|
+
exports(): {};
|
|
12
|
+
}
|
|
13
|
+
interface $$IsomorphicComponent {
|
|
14
|
+
new <valueType = unknown, entityType = unknown>(options: import('svelte').ComponentConstructorOptions<ReturnType<__sveltets_Render<valueType, entityType>['props']>>): import('svelte').SvelteComponent<ReturnType<__sveltets_Render<valueType, entityType>['props']>, ReturnType<__sveltets_Render<valueType, entityType>['events']>, ReturnType<__sveltets_Render<valueType, entityType>['slots']>> & {
|
|
15
|
+
$$bindings?: ReturnType<__sveltets_Render<valueType, entityType>['bindings']>;
|
|
16
|
+
} & ReturnType<__sveltets_Render<valueType, entityType>['exports']>;
|
|
17
|
+
<valueType = unknown, entityType = unknown>(internal: unknown, props: ReturnType<__sveltets_Render<valueType, entityType>['props']> & {}): ReturnType<__sveltets_Render<valueType, entityType>['exports']>;
|
|
18
|
+
z_$$bindings?: ReturnType<__sveltets_Render<any, any>['bindings']>;
|
|
19
|
+
}
|
|
20
|
+
declare const FfField: $$IsomorphicComponent;
|
|
21
|
+
type FfField<valueType = unknown, entityType = unknown> = InstanceType<typeof FfField<valueType, entityType>>;
|
|
22
|
+
export default FfField;
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
<script lang="ts" generics="entityType = unknown">
|
|
2
|
+
import { EntityError, getEntityRef } from 'remult'
|
|
3
|
+
|
|
4
|
+
import { FF_Field, getClasses } from './'
|
|
5
|
+
import type { FF_Repo, FieldGroup, FormTheme } from './'
|
|
6
|
+
|
|
7
|
+
const default_uid = $props.id()
|
|
8
|
+
|
|
9
|
+
interface Props<entityType> {
|
|
10
|
+
uid_prefix?: string
|
|
11
|
+
uid?: string
|
|
12
|
+
r: FF_Repo<entityType>
|
|
13
|
+
groups?: FieldGroup<entityType>[]
|
|
14
|
+
defaults?: Partial<entityType>
|
|
15
|
+
classes?: FormTheme
|
|
16
|
+
show?: {
|
|
17
|
+
title?: boolean
|
|
18
|
+
}
|
|
19
|
+
onSaved?: (item: entityType) => void
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
let {
|
|
23
|
+
uid_prefix = '',
|
|
24
|
+
uid = default_uid,
|
|
25
|
+
r,
|
|
26
|
+
groups,
|
|
27
|
+
defaults,
|
|
28
|
+
show = {
|
|
29
|
+
title: true,
|
|
30
|
+
},
|
|
31
|
+
classes: localClasses = {},
|
|
32
|
+
onSaved,
|
|
33
|
+
}: Props<entityType> = $props()
|
|
34
|
+
|
|
35
|
+
const ToUse = uid_prefix ? `${uid_prefix}-${uid}` : uid
|
|
36
|
+
|
|
37
|
+
let classes = $derived(getClasses('form', localClasses))
|
|
38
|
+
|
|
39
|
+
let errors = $state<Record<string, string>>({})
|
|
40
|
+
let globalError = $state<string | undefined>(undefined)
|
|
41
|
+
|
|
42
|
+
let valuesToUse = $state(r.item ? r.item : r.create(defaults))
|
|
43
|
+
let ref = $derived(getEntityRef(valuesToUse))
|
|
44
|
+
const groupsToUse: FieldGroup<entityType>[] = $derived(groups ?? r.getLayout()?.groups ?? [])
|
|
45
|
+
|
|
46
|
+
const onsubmit = async (e: Event) => {
|
|
47
|
+
e.preventDefault()
|
|
48
|
+
// r.loading.saving = true
|
|
49
|
+
// FF_Form.svelte:48 [svelte] ownership_invalid_mutation
|
|
50
|
+
// src/lib/svelte/FF_Form.svelte mutated a value owned by src/routes/demo/FF_Simple/+page.svelte. This is strongly discouraged. Consider passing values to child components with `bind:`, or use a callback instead
|
|
51
|
+
// https://svelte.dev/e/ownership_invalid_mutation
|
|
52
|
+
globalError = undefined
|
|
53
|
+
try {
|
|
54
|
+
if (ref.isNew()) {
|
|
55
|
+
const itemSaved = await ref.save()
|
|
56
|
+
r.items?.unshift(itemSaved)
|
|
57
|
+
if (r.aggregates && r.aggregates.$count !== undefined) {
|
|
58
|
+
r.aggregates.$count = r.aggregates.$count + 1
|
|
59
|
+
}
|
|
60
|
+
valuesToUse = r.create()
|
|
61
|
+
onSaved?.(itemSaved)
|
|
62
|
+
} else {
|
|
63
|
+
const itemSaved = await ref.save()
|
|
64
|
+
onSaved?.(itemSaved)
|
|
65
|
+
}
|
|
66
|
+
errors = {}
|
|
67
|
+
} catch (error) {
|
|
68
|
+
if (error instanceof EntityError) {
|
|
69
|
+
errors = error.modelState as Record<string, string>
|
|
70
|
+
} else {
|
|
71
|
+
// @ts-ignore
|
|
72
|
+
globalError = error.message
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
// r.loading.saving = false
|
|
76
|
+
}
|
|
77
|
+
</script>
|
|
78
|
+
|
|
79
|
+
<form data-ff-form class="{classes?.root} {r.metadata.key}" {onsubmit}>
|
|
80
|
+
<div data-ff-form-groups class={classes?.groups}>
|
|
81
|
+
{#each groupsToUse ?? [] as group (group.key)}
|
|
82
|
+
<div data-ff-form-group>
|
|
83
|
+
{#if show?.title}
|
|
84
|
+
<div data-ff-form-title>
|
|
85
|
+
<!-- {ref.isNew() ? 'Add' : 'Save'} -->
|
|
86
|
+
{group?.caption ?? r.metadata.caption}
|
|
87
|
+
</div>
|
|
88
|
+
{/if}
|
|
89
|
+
{#if group?.hint}
|
|
90
|
+
<div data-ff-form-hint>{@html group?.hint}</div>
|
|
91
|
+
{/if}
|
|
92
|
+
<div data-ff-form-fields class="{classes?.fields} {group.class}">
|
|
93
|
+
{#each group.fields as field}
|
|
94
|
+
<FF_Field
|
|
95
|
+
uid="{ToUse}-{field.key}"
|
|
96
|
+
{field}
|
|
97
|
+
bind:value={valuesToUse[field.key as keyof entityType]}
|
|
98
|
+
error={errors[field.key]}
|
|
99
|
+
/>
|
|
100
|
+
{/each}
|
|
101
|
+
</div>
|
|
102
|
+
</div>
|
|
103
|
+
{/each}
|
|
104
|
+
</div>
|
|
105
|
+
|
|
106
|
+
<div data-ff-form-actions class={classes?.actions}>
|
|
107
|
+
<button
|
|
108
|
+
data-ff-form-button
|
|
109
|
+
class={classes?.submitButton}
|
|
110
|
+
disabled={!r.metadata.apiInsertAllowed() || r.loading.saving}
|
|
111
|
+
>
|
|
112
|
+
{ref.isNew() ? 'Add' : 'Save'}{r.loading.saving ? '...' : ''}
|
|
113
|
+
</button>
|
|
114
|
+
{globalError}
|
|
115
|
+
</div>
|
|
116
|
+
{globalError}
|
|
117
|
+
<!-- TODO: display errors of field not in the form -->
|
|
118
|
+
</form>
|
|
119
|
+
|
|
120
|
+
<style>
|
|
121
|
+
[data-ff-form-title] {
|
|
122
|
+
width: 100%;
|
|
123
|
+
display: flex;
|
|
124
|
+
flex-wrap: wrap;
|
|
125
|
+
padding: var(--ff-spacing);
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
[data-ff-form-hint] {
|
|
129
|
+
width: 100%;
|
|
130
|
+
display: flex;
|
|
131
|
+
flex-wrap: wrap;
|
|
132
|
+
padding: var(--ff-spacing);
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
[data-ff-form-fields] {
|
|
136
|
+
width: 100%;
|
|
137
|
+
display: flex;
|
|
138
|
+
flex-wrap: wrap;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
/* To distribute as default css ? */
|
|
142
|
+
.ff-form-actions {
|
|
143
|
+
display: flex;
|
|
144
|
+
justify-content: flex-end;
|
|
145
|
+
margin: 1rem;
|
|
146
|
+
|
|
147
|
+
button {
|
|
148
|
+
border-radius: 0.5rem;
|
|
149
|
+
padding: 0.5rem 1rem;
|
|
150
|
+
background-color: green;
|
|
151
|
+
color: #fff;
|
|
152
|
+
border: none;
|
|
153
|
+
cursor: pointer;
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
</style>
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { FF_Repo, FieldGroup, FormTheme } from './';
|
|
2
|
+
interface Props<entityType> {
|
|
3
|
+
uid_prefix?: string;
|
|
4
|
+
uid?: string;
|
|
5
|
+
r: FF_Repo<entityType>;
|
|
6
|
+
groups?: FieldGroup<entityType>[];
|
|
7
|
+
defaults?: Partial<entityType>;
|
|
8
|
+
classes?: FormTheme;
|
|
9
|
+
show?: {
|
|
10
|
+
title?: boolean;
|
|
11
|
+
};
|
|
12
|
+
onSaved?: (item: entityType) => void;
|
|
13
|
+
}
|
|
14
|
+
declare class __sveltets_Render<entityType = unknown> {
|
|
15
|
+
props(): Props<entityType>;
|
|
16
|
+
events(): {};
|
|
17
|
+
slots(): {};
|
|
18
|
+
bindings(): "";
|
|
19
|
+
exports(): {};
|
|
20
|
+
}
|
|
21
|
+
interface $$IsomorphicComponent {
|
|
22
|
+
new <entityType = unknown>(options: import('svelte').ComponentConstructorOptions<ReturnType<__sveltets_Render<entityType>['props']>>): import('svelte').SvelteComponent<ReturnType<__sveltets_Render<entityType>['props']>, ReturnType<__sveltets_Render<entityType>['events']>, ReturnType<__sveltets_Render<entityType>['slots']>> & {
|
|
23
|
+
$$bindings?: ReturnType<__sveltets_Render<entityType>['bindings']>;
|
|
24
|
+
} & ReturnType<__sveltets_Render<entityType>['exports']>;
|
|
25
|
+
<entityType = unknown>(internal: unknown, props: ReturnType<__sveltets_Render<entityType>['props']> & {}): ReturnType<__sveltets_Render<entityType>['exports']>;
|
|
26
|
+
z_$$bindings?: ReturnType<__sveltets_Render<any>['bindings']>;
|
|
27
|
+
}
|
|
28
|
+
declare const FfForm: $$IsomorphicComponent;
|
|
29
|
+
type FfForm<entityType = unknown> = InstanceType<typeof FfForm<entityType>>;
|
|
30
|
+
export default FfForm;
|