@profidev/pleiades 1.9.0 → 1.9.2
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/dist/backend/util.svelte.d.ts +1 -1
- package/dist/backend/util.svelte.js +20 -20
- package/dist/components/form/base-form.svelte +61 -19
- package/dist/components/form/base-form.svelte.d.ts +11 -6
- package/dist/components/form/form-dialog.svelte +16 -8
- package/dist/components/form/form-dialog.svelte.d.ts +5 -2
- package/dist/components/form/login-other-options.svelte +10 -16
- package/dist/components/form/login-other-options.svelte.d.ts +1 -1
- package/dist/components/form/multistep-form.svelte +15 -5
- package/dist/components/form/multistep-form.svelte.d.ts +2 -1
- package/dist/components/form/types.d.ts +4 -3
- package/dist/components/nav/sidebar/sidebar-content.svelte +10 -6
- package/dist/components/nav/sidebar/sidebar-content.svelte.d.ts +1 -1
- package/dist/components/nav/sidebar/sidebar-user.svelte +10 -14
- package/dist/components/nav/sidebar/sidebar-user.svelte.d.ts +1 -1
- package/dist/components/nav/sidebar/sidebar.svelte +1 -1
- package/dist/components/nav/sidebar/sidebar.svelte.d.ts +1 -1
- package/dist/components/table/simple-table.svelte +1 -1
- package/dist/components/table/simple-table.svelte.d.ts +1 -1
- package/package.json +1 -1
|
@@ -8,7 +8,7 @@ export interface RequestOptions {
|
|
|
8
8
|
}
|
|
9
9
|
export declare const patch: <T = undefined>(path: string, options?: RequestOptions) => Promise<T | RequestError>;
|
|
10
10
|
export declare const put: <T = undefined>(path: string, options?: RequestOptions) => Promise<T | RequestError>;
|
|
11
|
-
export declare const
|
|
11
|
+
export declare const delete_req: <T = undefined>(path: string, options?: RequestOptions) => Promise<T | RequestError>;
|
|
12
12
|
export declare const post: <T = undefined>(path: string, options?: RequestOptions) => Promise<T | RequestError>;
|
|
13
13
|
export declare const get: <T = undefined>(path: string, options?: Omit<RequestOptions, "body">) => Promise<T | RequestError>;
|
|
14
14
|
export declare const request: <T = undefined>(path: string, method: string, { res_type, body, content_type, signal, fetch }?: RequestOptions) => Promise<T | RequestError>;
|
|
@@ -1,36 +1,36 @@
|
|
|
1
1
|
import { RequestError, ResponseType } from './types.svelte';
|
|
2
2
|
export const patch = async (path, options = {}) => await request(path, 'PATCH', options);
|
|
3
3
|
export const put = async (path, options = {}) => await request(path, 'PUT', options);
|
|
4
|
-
export const
|
|
4
|
+
export const delete_req = async (path, options = {}) => await request(path, 'DELETE', options);
|
|
5
5
|
export const post = async (path, options = {}) => await request(path, 'POST', options);
|
|
6
6
|
export const get = async (path, options = {}) => await request(path, 'GET', options);
|
|
7
7
|
// oxlint-disable-next-line complexity
|
|
8
8
|
export const request = async (path, method, { res_type, body, content_type, signal, fetch } = {}) => {
|
|
9
|
-
const
|
|
10
|
-
let
|
|
11
|
-
let
|
|
12
|
-
if (
|
|
13
|
-
|
|
9
|
+
const res_type_inner = res_type ?? ResponseType.None;
|
|
10
|
+
let content_type_inner = content_type;
|
|
11
|
+
let body_inner = body;
|
|
12
|
+
if (body_inner instanceof ArrayBuffer) {
|
|
13
|
+
content_type_inner = 'application/octet-stream';
|
|
14
14
|
}
|
|
15
|
-
else if (
|
|
16
|
-
|
|
17
|
-
|
|
15
|
+
else if (body_inner instanceof Blob) {
|
|
16
|
+
content_type_inner = body_inner.type;
|
|
17
|
+
body_inner = body_inner.stream();
|
|
18
18
|
}
|
|
19
|
-
else if (typeof
|
|
20
|
-
|
|
19
|
+
else if (typeof body_inner === 'string') {
|
|
20
|
+
content_type_inner = 'text/plain';
|
|
21
21
|
}
|
|
22
|
-
else if (typeof
|
|
23
|
-
|
|
24
|
-
|
|
22
|
+
else if (typeof body_inner === 'object' && body_inner !== null) {
|
|
23
|
+
content_type_inner = 'application/json';
|
|
24
|
+
body_inner = JSON.stringify(body_inner);
|
|
25
25
|
}
|
|
26
26
|
const headers = {};
|
|
27
|
-
if (
|
|
28
|
-
headers['Content-Type'] =
|
|
27
|
+
if (content_type_inner) {
|
|
28
|
+
headers['Content-Type'] = content_type_inner;
|
|
29
29
|
}
|
|
30
|
-
const
|
|
30
|
+
const fetch_inner = fetch ?? globalThis.fetch;
|
|
31
31
|
try {
|
|
32
|
-
const res = await
|
|
33
|
-
body:
|
|
32
|
+
const res = await fetch_inner(path, {
|
|
33
|
+
body: body_inner,
|
|
34
34
|
headers,
|
|
35
35
|
method,
|
|
36
36
|
signal
|
|
@@ -97,7 +97,7 @@ export const request = async (path, method, { res_type, body, content_type, sign
|
|
|
97
97
|
return RequestError.Other;
|
|
98
98
|
}
|
|
99
99
|
}
|
|
100
|
-
switch (
|
|
100
|
+
switch (res_type_inner) {
|
|
101
101
|
case ResponseType.Json: {
|
|
102
102
|
const json = await res.json();
|
|
103
103
|
// oxlint-disable-next-line no-unsafe-type-assertion
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
<script lang="ts" generics="V extends ZodValidationSchema">
|
|
2
|
-
import type { Snippet } from 'svelte';
|
|
2
|
+
import type { Component, Snippet } from 'svelte';
|
|
3
3
|
import { get } from 'svelte/store';
|
|
4
4
|
import {
|
|
5
5
|
defaults,
|
|
@@ -14,16 +14,18 @@
|
|
|
14
14
|
} from 'sveltekit-superforms/adapters';
|
|
15
15
|
import { FormButton } from '../ui/form/index.js';
|
|
16
16
|
import LoaderCircle from '@lucide/svelte/icons/loader-circle';
|
|
17
|
+
import RotateCCW from '@lucide/svelte/icons/rotate-ccw';
|
|
17
18
|
import type { ButtonVariant } from '../ui/button/index.js';
|
|
18
19
|
import { cn } from '../../utils.js';
|
|
19
20
|
import type { Error, FormEnctype, FormValue } from './types.js';
|
|
21
|
+
import { toast } from 'svelte-sonner';
|
|
20
22
|
|
|
21
23
|
interface Props {
|
|
22
24
|
schema: V;
|
|
23
25
|
initialValue?: Partial<FormValue<V>>;
|
|
24
26
|
onsubmit: (
|
|
25
27
|
form: FormValue<V>
|
|
26
|
-
) => Error | undefined | void | Promise<Error | undefined | void>;
|
|
28
|
+
) => Error<V> | undefined | void | Promise<Error<V> | undefined | void>;
|
|
27
29
|
children?: Snippet<
|
|
28
30
|
[{ props: { formData: SuperForm<FormValue<V>>; disabled: boolean } }]
|
|
29
31
|
>;
|
|
@@ -31,16 +33,27 @@
|
|
|
31
33
|
[
|
|
32
34
|
{
|
|
33
35
|
defaultBtn: Snippet<
|
|
34
|
-
[
|
|
36
|
+
[
|
|
37
|
+
{
|
|
38
|
+
className?: string;
|
|
39
|
+
variant?: ButtonVariant;
|
|
40
|
+
content: string;
|
|
41
|
+
icon?: Component;
|
|
42
|
+
}
|
|
43
|
+
]
|
|
35
44
|
>;
|
|
36
45
|
isLoading: boolean;
|
|
46
|
+
isError: boolean;
|
|
37
47
|
}
|
|
38
48
|
]
|
|
39
49
|
>;
|
|
40
50
|
isLoading?: boolean;
|
|
41
|
-
error?: string;
|
|
42
51
|
class?: string;
|
|
43
52
|
enctype?: FormEnctype;
|
|
53
|
+
noErrorToast?: boolean;
|
|
54
|
+
submitText?: string;
|
|
55
|
+
retryText?: string;
|
|
56
|
+
submitIcon?: Component;
|
|
44
57
|
}
|
|
45
58
|
|
|
46
59
|
let {
|
|
@@ -50,11 +63,16 @@
|
|
|
50
63
|
children,
|
|
51
64
|
footer = defaultFooter,
|
|
52
65
|
isLoading = $bindable(false),
|
|
53
|
-
error = $bindable(''),
|
|
54
66
|
class: className,
|
|
55
|
-
enctype
|
|
67
|
+
enctype,
|
|
68
|
+
noErrorToast,
|
|
69
|
+
submitText = 'Submit',
|
|
70
|
+
retryText = 'Retry',
|
|
71
|
+
submitIcon
|
|
56
72
|
}: Props = $props();
|
|
57
73
|
|
|
74
|
+
let isError = $state(false);
|
|
75
|
+
|
|
58
76
|
let form = superForm(
|
|
59
77
|
defaults(
|
|
60
78
|
initialValue,
|
|
@@ -66,7 +84,7 @@
|
|
|
66
84
|
onUpdate: async ({ form, cancel }) => {
|
|
67
85
|
if (!form.valid) return;
|
|
68
86
|
|
|
69
|
-
|
|
87
|
+
isError = false;
|
|
70
88
|
isLoading = true;
|
|
71
89
|
|
|
72
90
|
let ret = await onsubmit(form.data);
|
|
@@ -76,7 +94,12 @@
|
|
|
76
94
|
if (ret.field) {
|
|
77
95
|
setError(form, ret.field as '', ret.error, undefined);
|
|
78
96
|
} else {
|
|
79
|
-
if (ret.error !== '')
|
|
97
|
+
if (ret.error !== '') {
|
|
98
|
+
isError = true;
|
|
99
|
+
if (!noErrorToast) {
|
|
100
|
+
toast.error(ret.error);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
80
103
|
cancel();
|
|
81
104
|
}
|
|
82
105
|
}
|
|
@@ -105,21 +128,36 @@
|
|
|
105
128
|
|
|
106
129
|
<form method="POST" class={cn('grid gap-3', className)} use:enhance {enctype}>
|
|
107
130
|
{@render children?.({ props: { formData: form, disabled: isLoading } })}
|
|
108
|
-
{
|
|
109
|
-
<span class="text-destructive truncate text-sm">{error}</span>
|
|
110
|
-
{/if}
|
|
111
|
-
{@render footer({ defaultBtn: formButton, isLoading })}
|
|
131
|
+
{@render footer({ defaultBtn: formButton, isLoading, isError })}
|
|
112
132
|
</form>
|
|
113
133
|
|
|
114
|
-
{#snippet defaultFooter({
|
|
115
|
-
|
|
134
|
+
{#snippet defaultFooter({
|
|
135
|
+
defaultBtn
|
|
136
|
+
}: {
|
|
137
|
+
defaultBtn: Snippet<
|
|
138
|
+
[
|
|
139
|
+
{
|
|
140
|
+
className?: string;
|
|
141
|
+
variant?: ButtonVariant;
|
|
142
|
+
content: string;
|
|
143
|
+
icon?: Component;
|
|
144
|
+
}
|
|
145
|
+
]
|
|
146
|
+
>;
|
|
147
|
+
})}
|
|
148
|
+
{@render defaultBtn({
|
|
149
|
+
variant: isError ? 'destructive' : undefined,
|
|
150
|
+
content: isError ? retryText : submitText,
|
|
151
|
+
icon: submitIcon
|
|
152
|
+
})}
|
|
116
153
|
{/snippet}
|
|
117
154
|
|
|
118
|
-
{#snippet formButton(
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
155
|
+
{#snippet formButton(props: {
|
|
156
|
+
className?: string;
|
|
157
|
+
variant?: ButtonVariant;
|
|
158
|
+
content: string;
|
|
159
|
+
icon?: Component;
|
|
160
|
+
})}
|
|
123
161
|
{@const prop = { ...props }}
|
|
124
162
|
<FormButton
|
|
125
163
|
class={cn('cursor-pointer', prop.className)}
|
|
@@ -129,6 +167,10 @@
|
|
|
129
167
|
>
|
|
130
168
|
{#if isLoading}
|
|
131
169
|
<LoaderCircle class="mr-2 h-4 w-4 animate-spin" />
|
|
170
|
+
{:else if isError}
|
|
171
|
+
<RotateCCW class="mr-2 h-4 w-4" />
|
|
172
|
+
{:else if prop.icon}
|
|
173
|
+
<prop.icon class="mr-2 h-4 w-4" />
|
|
132
174
|
{/if}
|
|
133
175
|
{prop.content}
|
|
134
176
|
</FormButton>
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { Snippet } from 'svelte';
|
|
1
|
+
import type { Component, Snippet } from 'svelte';
|
|
2
2
|
import { type SuperForm } from 'sveltekit-superforms';
|
|
3
3
|
import { type ZodValidationSchema } from 'sveltekit-superforms/adapters';
|
|
4
4
|
import type { ButtonVariant } from '../ui/button/index.js';
|
|
@@ -7,7 +7,7 @@ declare function $$render<V extends ZodValidationSchema>(): {
|
|
|
7
7
|
props: {
|
|
8
8
|
schema: V;
|
|
9
9
|
initialValue?: Partial<FormValue<V>>;
|
|
10
|
-
onsubmit: (form: FormValue<V>) => Error | undefined | void | Promise<Error | undefined | void>;
|
|
10
|
+
onsubmit: (form: FormValue<V>) => Error<V> | undefined | void | Promise<Error<V> | undefined | void>;
|
|
11
11
|
children?: Snippet<[{
|
|
12
12
|
props: {
|
|
13
13
|
formData: SuperForm<FormValue<V>>;
|
|
@@ -19,19 +19,24 @@ declare function $$render<V extends ZodValidationSchema>(): {
|
|
|
19
19
|
className?: string;
|
|
20
20
|
variant?: ButtonVariant;
|
|
21
21
|
content: string;
|
|
22
|
-
|
|
22
|
+
icon?: Component;
|
|
23
|
+
}]>;
|
|
23
24
|
isLoading: boolean;
|
|
25
|
+
isError: boolean;
|
|
24
26
|
}]>;
|
|
25
27
|
isLoading?: boolean;
|
|
26
|
-
error?: string;
|
|
27
28
|
class?: string;
|
|
28
29
|
enctype?: FormEnctype;
|
|
30
|
+
noErrorToast?: boolean;
|
|
31
|
+
submitText?: string;
|
|
32
|
+
retryText?: string;
|
|
33
|
+
submitIcon?: Component;
|
|
29
34
|
};
|
|
30
35
|
exports: {
|
|
31
36
|
setValue: (value: FormValue<V>) => void;
|
|
32
37
|
getValue: () => FormValue<V>;
|
|
33
38
|
};
|
|
34
|
-
bindings: "
|
|
39
|
+
bindings: "isLoading";
|
|
35
40
|
slots: {};
|
|
36
41
|
events: {};
|
|
37
42
|
};
|
|
@@ -39,7 +44,7 @@ declare class __sveltets_Render<V extends ZodValidationSchema> {
|
|
|
39
44
|
props(): ReturnType<typeof $$render<V>>['props'];
|
|
40
45
|
events(): ReturnType<typeof $$render<V>>['events'];
|
|
41
46
|
slots(): ReturnType<typeof $$render<V>>['slots'];
|
|
42
|
-
bindings(): "
|
|
47
|
+
bindings(): "isLoading";
|
|
43
48
|
exports(): {
|
|
44
49
|
setValue: (value: import("zod/v4").infer<V>) => void;
|
|
45
50
|
getValue: () => import("zod/v4").infer<V>;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<script lang="ts" generics="V extends ZodValidationSchema">
|
|
2
2
|
import * as Dialog from '../ui/dialog/index.js';
|
|
3
|
-
import type { Snippet } from 'svelte';
|
|
3
|
+
import type { Component, Snippet } from 'svelte';
|
|
4
4
|
import {
|
|
5
5
|
Button,
|
|
6
6
|
type ButtonSize,
|
|
@@ -18,7 +18,9 @@
|
|
|
18
18
|
title: string;
|
|
19
19
|
description?: string;
|
|
20
20
|
confirm: string;
|
|
21
|
+
retryText?: string;
|
|
21
22
|
confirmVariant?: ButtonVariant;
|
|
23
|
+
confirmIcon?: Component;
|
|
22
24
|
open?: boolean;
|
|
23
25
|
class?: string;
|
|
24
26
|
isLoading?: boolean;
|
|
@@ -33,7 +35,7 @@
|
|
|
33
35
|
onopen?: () => boolean | Promise<boolean>;
|
|
34
36
|
onsubmit: (
|
|
35
37
|
form: FormValue<V>
|
|
36
|
-
) => Error | undefined | void | Promise<Error | undefined | void>;
|
|
38
|
+
) => Error<V> | undefined | void | Promise<Error<V> | undefined | void>;
|
|
37
39
|
children?: Snippet<
|
|
38
40
|
[{ props: { formData: SuperForm<FormValue<V>>; disabled: boolean } }]
|
|
39
41
|
>;
|
|
@@ -41,6 +43,7 @@
|
|
|
41
43
|
schema: V;
|
|
42
44
|
initialValue?: FormValue<V>;
|
|
43
45
|
enctype?: FormEnctype;
|
|
46
|
+
noErrorToast?: boolean;
|
|
44
47
|
}
|
|
45
48
|
|
|
46
49
|
let {
|
|
@@ -58,11 +61,13 @@
|
|
|
58
61
|
triggerInner,
|
|
59
62
|
schema,
|
|
60
63
|
initialValue,
|
|
61
|
-
enctype
|
|
64
|
+
enctype,
|
|
65
|
+
retryText = 'Retry',
|
|
66
|
+
confirmIcon,
|
|
67
|
+
noErrorToast
|
|
62
68
|
}: Props = $props();
|
|
63
69
|
|
|
64
70
|
let formComp: BaseForm<V> | undefined = $state();
|
|
65
|
-
let error = $state('');
|
|
66
71
|
let formSetValue = $derived(formComp?.setValue);
|
|
67
72
|
let formGetValue = $derived(formComp?.getValue);
|
|
68
73
|
|
|
@@ -78,7 +83,6 @@
|
|
|
78
83
|
isLoading = true;
|
|
79
84
|
if (await onopen()) {
|
|
80
85
|
open = true;
|
|
81
|
-
error = '';
|
|
82
86
|
}
|
|
83
87
|
isLoading = false;
|
|
84
88
|
};
|
|
@@ -120,16 +124,20 @@
|
|
|
120
124
|
<Form
|
|
121
125
|
bind:this={formComp}
|
|
122
126
|
bind:isLoading
|
|
123
|
-
bind:error
|
|
124
127
|
{schema}
|
|
125
128
|
{initialValue}
|
|
126
129
|
{enctype}
|
|
127
130
|
onsubmit={submit}
|
|
128
131
|
{children}
|
|
132
|
+
{noErrorToast}
|
|
129
133
|
>
|
|
130
|
-
{#snippet footer({ defaultBtn })}
|
|
134
|
+
{#snippet footer({ defaultBtn, isError })}
|
|
131
135
|
<Dialog.Footer>
|
|
132
|
-
{@render defaultBtn({
|
|
136
|
+
{@render defaultBtn({
|
|
137
|
+
variant: isError ? 'destructive' : confirmVariant,
|
|
138
|
+
content: isError ? retryText : confirm,
|
|
139
|
+
icon: confirmIcon
|
|
140
|
+
})}
|
|
133
141
|
</Dialog.Footer>
|
|
134
142
|
{/snippet}
|
|
135
143
|
</Form>
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { Snippet } from 'svelte';
|
|
1
|
+
import type { Component, Snippet } from 'svelte';
|
|
2
2
|
import { type ButtonSize, type ButtonVariant } from '../ui/button/index.js';
|
|
3
3
|
import { type SuperForm } from 'sveltekit-superforms';
|
|
4
4
|
import type { Error, FormEnctype, FormValue } from './types.js';
|
|
@@ -8,7 +8,9 @@ declare function $$render<V extends ZodValidationSchema>(): {
|
|
|
8
8
|
title: string;
|
|
9
9
|
description?: string;
|
|
10
10
|
confirm: string;
|
|
11
|
+
retryText?: string;
|
|
11
12
|
confirmVariant?: ButtonVariant;
|
|
13
|
+
confirmIcon?: Component;
|
|
12
14
|
open?: boolean;
|
|
13
15
|
class?: string;
|
|
14
16
|
isLoading?: boolean;
|
|
@@ -21,7 +23,7 @@ declare function $$render<V extends ZodValidationSchema>(): {
|
|
|
21
23
|
disabled?: boolean;
|
|
22
24
|
};
|
|
23
25
|
onopen?: () => boolean | Promise<boolean>;
|
|
24
|
-
onsubmit: (form: FormValue<V>) => Error | undefined | void | Promise<Error | undefined | void>;
|
|
26
|
+
onsubmit: (form: FormValue<V>) => Error<V> | undefined | void | Promise<Error<V> | undefined | void>;
|
|
25
27
|
children?: Snippet<[{
|
|
26
28
|
props: {
|
|
27
29
|
formData: SuperForm<FormValue<V>>;
|
|
@@ -32,6 +34,7 @@ declare function $$render<V extends ZodValidationSchema>(): {
|
|
|
32
34
|
schema: V;
|
|
33
35
|
initialValue?: FormValue<V>;
|
|
34
36
|
enctype?: FormEnctype;
|
|
37
|
+
noErrorToast?: boolean;
|
|
35
38
|
};
|
|
36
39
|
exports: {
|
|
37
40
|
openFn: () => Promise<void>;
|
|
@@ -1,32 +1,24 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
2
|
import KeyRound from '@lucide/svelte/icons/key-round';
|
|
3
3
|
import LoaderCircle from '@lucide/svelte/icons/loader-circle';
|
|
4
|
+
import RotateCcw from '@lucide/svelte/icons/rotate-ccw';
|
|
4
5
|
import { Button } from '../ui/button/index.js';
|
|
6
|
+
import { FieldSeparator } from '../ui/field/index.js';
|
|
5
7
|
|
|
6
8
|
interface Props {
|
|
7
9
|
isLoading: boolean;
|
|
8
10
|
passkeyClick: () => void;
|
|
9
|
-
passkeyError:
|
|
11
|
+
passkeyError: boolean;
|
|
10
12
|
}
|
|
11
13
|
|
|
12
14
|
let { isLoading, passkeyClick, passkeyError }: Props = $props();
|
|
13
15
|
</script>
|
|
14
16
|
|
|
15
|
-
<
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
</div>
|
|
19
|
-
<div class="relative flex justify-center text-xs uppercase">
|
|
20
|
-
<span class="bg-background text-muted-foreground px-2"
|
|
21
|
-
>Or continue with
|
|
22
|
-
</span>
|
|
23
|
-
</div>
|
|
24
|
-
</div>
|
|
25
|
-
{#if passkeyError !== ''}
|
|
26
|
-
<span class="text-destructive truncate text-sm">{passkeyError}</span>
|
|
27
|
-
{/if}
|
|
17
|
+
<FieldSeparator class="*:data-[slot=field-separator-content]:bg-card my-4"
|
|
18
|
+
>Or continue with</FieldSeparator
|
|
19
|
+
>
|
|
28
20
|
<Button
|
|
29
|
-
variant=
|
|
21
|
+
variant={passkeyError ? 'destructive' : 'outline'}
|
|
30
22
|
type="button"
|
|
31
23
|
disabled={isLoading}
|
|
32
24
|
onclick={passkeyClick}
|
|
@@ -34,8 +26,10 @@
|
|
|
34
26
|
>
|
|
35
27
|
{#if isLoading}
|
|
36
28
|
<LoaderCircle class="mr-2 h-4 w-4 animate-spin" />
|
|
29
|
+
{:else if passkeyError}
|
|
30
|
+
<RotateCcw />
|
|
37
31
|
{:else}
|
|
38
32
|
<KeyRound class="mr-2 h-4 w-4" />
|
|
39
33
|
{/if}
|
|
40
|
-
Passkey
|
|
34
|
+
{passkeyError ? 'Retry Passkey' : 'Passkey'}
|
|
41
35
|
</Button>
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
import Ban from '@lucide/svelte/icons/ban';
|
|
5
5
|
import CheckIcon from '@lucide/svelte/icons/check';
|
|
6
6
|
import Plus from '@lucide/svelte/icons/plus';
|
|
7
|
+
import RotateCCW from '@lucide/svelte/icons/rotate-ccw';
|
|
7
8
|
import { Badge } from '../ui/badge';
|
|
8
9
|
import { Button } from '../ui/button';
|
|
9
10
|
import * as Card from '../ui/card';
|
|
@@ -19,9 +20,10 @@
|
|
|
19
20
|
stages: Stage<T>[];
|
|
20
21
|
onsubmit: (
|
|
21
22
|
data: object
|
|
22
|
-
) => Error | undefined | void | Promise<Error | undefined | void>;
|
|
23
|
+
) => Error<any> | undefined | void | Promise<Error<any> | undefined | void>;
|
|
23
24
|
data?: T;
|
|
24
25
|
submitLabel?: string;
|
|
26
|
+
retryLabel?: string;
|
|
25
27
|
submitIcon?: Component;
|
|
26
28
|
cancelHref: string;
|
|
27
29
|
}
|
|
@@ -32,7 +34,8 @@
|
|
|
32
34
|
data = undefined as T,
|
|
33
35
|
submitLabel = 'Create',
|
|
34
36
|
submitIcon: SubmitIcon = Plus,
|
|
35
|
-
cancelHref
|
|
37
|
+
cancelHref,
|
|
38
|
+
retryLabel = 'Retry'
|
|
36
39
|
}: Props<T> = $props();
|
|
37
40
|
|
|
38
41
|
let stage = $state(0);
|
|
@@ -96,7 +99,7 @@
|
|
|
96
99
|
bind:isLoading
|
|
97
100
|
{data}
|
|
98
101
|
>
|
|
99
|
-
{#snippet footer({ isLoading })}
|
|
102
|
+
{#snippet footer({ isLoading, isError })}
|
|
100
103
|
<Card.Footer
|
|
101
104
|
class="w-full gap-2 border-none bg-transparent px-0 pt-0"
|
|
102
105
|
>
|
|
@@ -124,11 +127,18 @@
|
|
|
124
127
|
<Ban />
|
|
125
128
|
Cancel
|
|
126
129
|
</Button>
|
|
127
|
-
<Button
|
|
130
|
+
<Button
|
|
131
|
+
class="cursor-pointer"
|
|
132
|
+
type="submit"
|
|
133
|
+
disabled={isLoading}
|
|
134
|
+
variant={isError ? 'destructive' : undefined}
|
|
135
|
+
>
|
|
128
136
|
{#if stage === stages.length - 1}
|
|
129
|
-
{submitLabel}
|
|
137
|
+
{isError ? retryLabel : submitLabel}
|
|
130
138
|
{#if isLoading}
|
|
131
139
|
<Spinner />
|
|
140
|
+
{:else if isError}
|
|
141
|
+
<RotateCCW />
|
|
132
142
|
{:else}
|
|
133
143
|
<SubmitIcon />
|
|
134
144
|
{/if}
|
|
@@ -2,9 +2,10 @@ import { type Error, type Stage } from './types';
|
|
|
2
2
|
import type { Component } from 'svelte';
|
|
3
3
|
interface Props<T> {
|
|
4
4
|
stages: Stage<T>[];
|
|
5
|
-
onsubmit: (data: object) => Error | undefined | void | Promise<Error | undefined | void>;
|
|
5
|
+
onsubmit: (data: object) => Error<any> | undefined | void | Promise<Error<any> | undefined | void>;
|
|
6
6
|
data?: T;
|
|
7
7
|
submitLabel?: string;
|
|
8
|
+
retryLabel?: string;
|
|
8
9
|
submitIcon?: Component;
|
|
9
10
|
cancelHref: string;
|
|
10
11
|
}
|
|
@@ -6,16 +6,17 @@ export type { SuperForm, FormPath, FormPathLeaves } from 'sveltekit-superforms';
|
|
|
6
6
|
export type { ZodValidationSchema };
|
|
7
7
|
export type FormRecord = Record<string, unknown>;
|
|
8
8
|
export type FormValue<V extends ZodValidationSchema> = z.infer<V>;
|
|
9
|
-
export interface Error {
|
|
10
|
-
field?:
|
|
9
|
+
export interface Error<V extends ZodValidationSchema> {
|
|
10
|
+
field?: keyof FormValue<V>;
|
|
11
11
|
error: string;
|
|
12
12
|
}
|
|
13
13
|
export type FormEnctype = 'application/x-www-form-urlencoded' | 'multipart/form-data' | 'text/plain' | undefined | null;
|
|
14
14
|
export interface StageProps<T = undefined> {
|
|
15
15
|
initialValue?: any;
|
|
16
|
-
onsubmit: ComponentProps<
|
|
16
|
+
onsubmit: ComponentProps<BaseForm<any>>['onsubmit'];
|
|
17
17
|
footer: Snippet<[{
|
|
18
18
|
isLoading: boolean;
|
|
19
|
+
isError: boolean;
|
|
19
20
|
}]>;
|
|
20
21
|
isLoading: boolean;
|
|
21
22
|
data: T;
|
|
@@ -8,10 +8,10 @@
|
|
|
8
8
|
|
|
9
9
|
interface Props {
|
|
10
10
|
items: NavGroup[];
|
|
11
|
-
user
|
|
11
|
+
user?: SidebarUserInfo;
|
|
12
12
|
}
|
|
13
13
|
|
|
14
|
-
const { items, user
|
|
14
|
+
const { items, user }: Props = $props();
|
|
15
15
|
|
|
16
16
|
const filteredItems = (items: NavGroup[], user: SidebarUserInfo) =>
|
|
17
17
|
items
|
|
@@ -29,11 +29,15 @@
|
|
|
29
29
|
const current = (filteredItems: NavGroup[]) =>
|
|
30
30
|
filteredItems
|
|
31
31
|
.flatMap((group) => group.items)
|
|
32
|
-
.filter(
|
|
32
|
+
.filter(
|
|
33
|
+
(item) =>
|
|
34
|
+
(page.url.pathname.startsWith(item.href) && item.href !== '/') ||
|
|
35
|
+
item.href === page.url.pathname
|
|
36
|
+
)
|
|
33
37
|
.sort((a, b) => b.href.length - a.href.length)[0] ?? undefined;
|
|
34
38
|
</script>
|
|
35
39
|
|
|
36
|
-
{#
|
|
40
|
+
{#if !user}
|
|
37
41
|
<Sidebar.Group>
|
|
38
42
|
<Sidebar.GroupLabel>Loading...</Sidebar.GroupLabel>
|
|
39
43
|
<Sidebar.Menu>
|
|
@@ -44,7 +48,7 @@
|
|
|
44
48
|
{/each}
|
|
45
49
|
</Sidebar.Menu>
|
|
46
50
|
</Sidebar.Group>
|
|
47
|
-
{:
|
|
51
|
+
{:else}
|
|
48
52
|
{@const filtered = filteredItems(items, user)}
|
|
49
53
|
{#each filtered as group}
|
|
50
54
|
<Sidebar.Group>
|
|
@@ -70,4 +74,4 @@
|
|
|
70
74
|
</Sidebar.Menu>
|
|
71
75
|
</Sidebar.Group>
|
|
72
76
|
{/each}
|
|
73
|
-
{/
|
|
77
|
+
{/if}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { NavGroup, SidebarUserInfo } from './types';
|
|
2
2
|
interface Props {
|
|
3
3
|
items: NavGroup[];
|
|
4
|
-
user
|
|
4
|
+
user?: SidebarUserInfo;
|
|
5
5
|
}
|
|
6
6
|
declare const SidebarContent: import("svelte").Component<Props, {}, "">;
|
|
7
7
|
type SidebarContent = ReturnType<typeof SidebarContent>;
|
|
@@ -11,12 +11,12 @@
|
|
|
11
11
|
import { Skeleton } from '../../ui/skeleton';
|
|
12
12
|
|
|
13
13
|
interface Props {
|
|
14
|
-
user
|
|
14
|
+
user?: SidebarUserInfo;
|
|
15
15
|
avatar?: string;
|
|
16
16
|
logout: () => Promise<{ error?: any }>;
|
|
17
17
|
}
|
|
18
18
|
|
|
19
|
-
let { logout, user
|
|
19
|
+
let { logout, user, avatar }: Props = $props();
|
|
20
20
|
|
|
21
21
|
const sidebar = Sidebar.useSidebar();
|
|
22
22
|
</script>
|
|
@@ -32,19 +32,17 @@
|
|
|
32
32
|
{...props}
|
|
33
33
|
>
|
|
34
34
|
<Avatar.Root class="size-8 rounded-lg">
|
|
35
|
-
{
|
|
36
|
-
<Avatar.Image src={avatar} alt={user.name} />
|
|
37
|
-
{/await}
|
|
35
|
+
<Avatar.Image src={avatar} alt={user?.name} />
|
|
38
36
|
<Avatar.Fallback class="rounded-full">?</Avatar.Fallback>
|
|
39
37
|
</Avatar.Root>
|
|
40
38
|
<div class="grid flex-1 text-start text-sm leading-tight">
|
|
41
|
-
{#
|
|
39
|
+
{#if !user}
|
|
42
40
|
<Skeleton class="mb-1 h-4" />
|
|
43
41
|
<Skeleton class="h-3" />
|
|
44
|
-
{:
|
|
42
|
+
{:else}
|
|
45
43
|
<span class="truncate font-medium">{user.name}</span>
|
|
46
44
|
<span class="truncate text-xs">{user.email}</span>
|
|
47
|
-
{/
|
|
45
|
+
{/if}
|
|
48
46
|
</div>
|
|
49
47
|
<ChevronsUpDownIcon class="ms-auto size-4" />
|
|
50
48
|
</Sidebar.MenuButton>
|
|
@@ -59,19 +57,17 @@
|
|
|
59
57
|
<DropdownMenu.Label class="p-0 font-normal">
|
|
60
58
|
<div class="flex items-center gap-2 px-1 py-1.5 text-start text-sm">
|
|
61
59
|
<Avatar.Root class="size-8 rounded-lg">
|
|
62
|
-
{
|
|
63
|
-
<Avatar.Image src={avatar} alt={user.name} />
|
|
64
|
-
{/await}
|
|
60
|
+
<Avatar.Image src={avatar} alt={user?.name} />
|
|
65
61
|
<Avatar.Fallback class="rounded-full">?</Avatar.Fallback>
|
|
66
62
|
</Avatar.Root>
|
|
67
63
|
<div class="grid flex-1 text-start text-sm leading-tight">
|
|
68
|
-
{#
|
|
64
|
+
{#if !user}
|
|
69
65
|
<Skeleton class="mb-1 h-4" />
|
|
70
66
|
<Skeleton class="h-3" />
|
|
71
|
-
{:
|
|
67
|
+
{:else}
|
|
72
68
|
<span class="truncate font-medium">{user.name}</span>
|
|
73
69
|
<span class="truncate text-xs">{user.email}</span>
|
|
74
|
-
{/
|
|
70
|
+
{/if}
|
|
75
71
|
</div>
|
|
76
72
|
</div>
|
|
77
73
|
</DropdownMenu.Label>
|
|
@@ -2,7 +2,7 @@ import * as Sidebar from '../../ui/sidebar';
|
|
|
2
2
|
import type { Component, Snippet } from 'svelte';
|
|
3
3
|
import type { NavGroup, SidebarUserInfo } from './types';
|
|
4
4
|
interface Props {
|
|
5
|
-
user
|
|
5
|
+
user?: SidebarUserInfo;
|
|
6
6
|
avatar?: string;
|
|
7
7
|
children: Snippet;
|
|
8
8
|
version: string;
|
|
@@ -38,7 +38,7 @@ declare function $$render<CV extends ZodValidationSchema, EV extends ZodValidati
|
|
|
38
38
|
startEdit?: (item: T) => void | Promise<void>;
|
|
39
39
|
createClass?: string;
|
|
40
40
|
editClass?: string;
|
|
41
|
-
errorMappings?: { [key in RequestError]?: Error
|
|
41
|
+
errorMappings?: { [key in RequestError]?: Error<any>; };
|
|
42
42
|
columnData: CD;
|
|
43
43
|
};
|
|
44
44
|
exports: {};
|