@svadmin/ui 0.50.0 → 0.51.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/dist/components/AutoTable.svelte +223 -106
- package/dist/components/AutoTable.svelte.d.ts +5 -0
- package/dist/components/ListPage.svelte +16 -2
- package/dist/components/ListPage.svelte.d.ts +7 -1
- package/dist/components/ShowPage.svelte +65 -23
- package/dist/components/ShowPage.svelte.d.ts +3 -0
- package/dist/components/buttons/CloneButton.svelte +23 -2
- package/dist/components/buttons/CloneButton.svelte.d.ts +3 -0
- package/dist/components/buttons/CreateButton.svelte +22 -2
- package/dist/components/buttons/CreateButton.svelte.d.ts +3 -0
- package/dist/components/buttons/DeleteButton.svelte +23 -3
- package/dist/components/buttons/DeleteButton.svelte.d.ts +3 -0
- package/dist/components/buttons/EditButton.svelte +23 -2
- package/dist/components/buttons/EditButton.svelte.d.ts +3 -0
- package/dist/components/buttons/ExportButton.svelte +22 -3
- package/dist/components/buttons/ExportButton.svelte.d.ts +3 -0
- package/dist/components/buttons/ImportButton.svelte +39 -17
- package/dist/components/buttons/ImportButton.svelte.d.ts +3 -0
- package/dist/components/buttons/ListButton.svelte +13 -2
- package/dist/components/buttons/ListButton.svelte.d.ts +2 -0
- package/dist/components/buttons/RefreshButton.svelte +22 -2
- package/dist/components/buttons/RefreshButton.svelte.d.ts +3 -0
- package/dist/components/buttons/SaveButton.svelte +23 -2
- package/dist/components/buttons/SaveButton.svelte.d.ts +3 -0
- package/dist/components/buttons/ShowButton.svelte +24 -3
- package/dist/components/buttons/ShowButton.svelte.d.ts +3 -0
- package/dist/components/content/DescriptionList.svelte +125 -15
- package/dist/components/content/DescriptionList.svelte.d.ts +6 -2
- package/package.json +2 -2
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
+
import type { Snippet } from 'svelte';
|
|
2
3
|
import { useNavigation, useCan, useTranslation } from '@svadmin/core';
|
|
3
4
|
import { Button } from '../ui/button/index.js';
|
|
4
5
|
import { Copy } from '@lucide/svelte';
|
|
@@ -7,9 +8,19 @@
|
|
|
7
8
|
|
|
8
9
|
const i18n = useTranslation();
|
|
9
10
|
|
|
10
|
-
let {
|
|
11
|
+
let {
|
|
12
|
+
resource,
|
|
13
|
+
recordItemId,
|
|
14
|
+
label,
|
|
15
|
+
children,
|
|
16
|
+
hideText = false,
|
|
17
|
+
accessControl = { enabled: true, hideIfUnauthorized: true },
|
|
18
|
+
class: className = '',
|
|
19
|
+
} = $props<{
|
|
11
20
|
resource: string;
|
|
12
21
|
recordItemId: string | number;
|
|
22
|
+
label?: string;
|
|
23
|
+
children?: Snippet;
|
|
13
24
|
hideText?: boolean;
|
|
14
25
|
accessControl?: ButtonAccessControl;
|
|
15
26
|
class?: string;
|
|
@@ -24,6 +35,7 @@
|
|
|
24
35
|
queryOptions: { enabled: accessControl?.enabled ?? true }
|
|
25
36
|
}));
|
|
26
37
|
const hidden = $derived(accessControl?.hideIfUnauthorized && !can.allowed);
|
|
38
|
+
const displayText = $derived(label ?? i18n.t('common.clone'));
|
|
27
39
|
</script>
|
|
28
40
|
|
|
29
41
|
{#if !hidden}
|
|
@@ -31,10 +43,19 @@
|
|
|
31
43
|
variant="outline"
|
|
32
44
|
size={hideText ? 'icon' : 'sm'}
|
|
33
45
|
class={className}
|
|
46
|
+
aria-label={hideText ? displayText : undefined}
|
|
34
47
|
disabled={!can.allowed}
|
|
35
48
|
onclick={() => nav.clone(resource, recordItemId)}
|
|
36
49
|
>
|
|
37
50
|
<Copy class="h-4 w-4" />
|
|
38
|
-
{#if !hideText}
|
|
51
|
+
{#if !hideText}
|
|
52
|
+
<span class="ml-1">
|
|
53
|
+
{#if children}
|
|
54
|
+
{@render children()}
|
|
55
|
+
{:else}
|
|
56
|
+
{displayText}
|
|
57
|
+
{/if}
|
|
58
|
+
</span>
|
|
59
|
+
{/if}
|
|
39
60
|
</Button>
|
|
40
61
|
{/if}
|
|
@@ -1,7 +1,10 @@
|
|
|
1
|
+
import type { Snippet } from 'svelte';
|
|
1
2
|
import type { ButtonAccessControl } from './access-control';
|
|
2
3
|
type $$ComponentProps = {
|
|
3
4
|
resource: string;
|
|
4
5
|
recordItemId: string | number;
|
|
6
|
+
label?: string;
|
|
7
|
+
children?: Snippet;
|
|
5
8
|
hideText?: boolean;
|
|
6
9
|
accessControl?: ButtonAccessControl;
|
|
7
10
|
class?: string;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
+
import type { Snippet } from 'svelte';
|
|
2
3
|
import { useNavigation, useCan, useTranslation } from '@svadmin/core';
|
|
3
4
|
import { Button } from '../ui/button/index.js';
|
|
4
5
|
import { Plus } from '@lucide/svelte';
|
|
@@ -6,8 +7,17 @@
|
|
|
6
7
|
|
|
7
8
|
const i18n = useTranslation();
|
|
8
9
|
|
|
9
|
-
let {
|
|
10
|
+
let {
|
|
11
|
+
resource,
|
|
12
|
+
label,
|
|
13
|
+
children,
|
|
14
|
+
hideText = false,
|
|
15
|
+
accessControl = { enabled: true, hideIfUnauthorized: true },
|
|
16
|
+
class: className = '',
|
|
17
|
+
} = $props<{
|
|
10
18
|
resource: string;
|
|
19
|
+
label?: string;
|
|
20
|
+
children?: Snippet;
|
|
11
21
|
hideText?: boolean;
|
|
12
22
|
accessControl?: ButtonAccessControl;
|
|
13
23
|
class?: string;
|
|
@@ -22,6 +32,7 @@
|
|
|
22
32
|
queryOptions: { enabled: accessControl?.enabled ?? true }
|
|
23
33
|
}));
|
|
24
34
|
const hidden = $derived(accessControl?.hideIfUnauthorized && !can.allowed);
|
|
35
|
+
const displayText = $derived(label ?? i18n.t('common.create'));
|
|
25
36
|
</script>
|
|
26
37
|
|
|
27
38
|
{#if !hidden}
|
|
@@ -29,10 +40,19 @@
|
|
|
29
40
|
variant="default"
|
|
30
41
|
size={hideText ? 'icon' : 'default'}
|
|
31
42
|
class={className}
|
|
43
|
+
aria-label={hideText ? displayText : undefined}
|
|
32
44
|
disabled={!can.allowed}
|
|
33
45
|
onclick={() => nav.create(resource)}
|
|
34
46
|
>
|
|
35
47
|
<Plus class="h-4 w-4" />
|
|
36
|
-
{#if !hideText}
|
|
48
|
+
{#if !hideText}
|
|
49
|
+
<span class="ml-1">
|
|
50
|
+
{#if children}
|
|
51
|
+
{@render children()}
|
|
52
|
+
{:else}
|
|
53
|
+
{displayText}
|
|
54
|
+
{/if}
|
|
55
|
+
</span>
|
|
56
|
+
{/if}
|
|
37
57
|
</Button>
|
|
38
58
|
{/if}
|
|
@@ -1,6 +1,9 @@
|
|
|
1
|
+
import type { Snippet } from 'svelte';
|
|
1
2
|
import type { ButtonAccessControl } from './access-control';
|
|
2
3
|
type $$ComponentProps = {
|
|
3
4
|
resource: string;
|
|
5
|
+
label?: string;
|
|
6
|
+
children?: Snippet;
|
|
4
7
|
hideText?: boolean;
|
|
5
8
|
accessControl?: ButtonAccessControl;
|
|
6
9
|
class?: string;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
+
import type { Snippet } from 'svelte';
|
|
2
3
|
import { useDelete, useCan, useTranslation } from '@svadmin/core';
|
|
3
4
|
import { Button } from '../ui/button/index.js';
|
|
4
5
|
import { Trash2 } from '@lucide/svelte';
|
|
@@ -8,11 +9,20 @@
|
|
|
8
9
|
const i18n = useTranslation();
|
|
9
10
|
|
|
10
11
|
let {
|
|
11
|
-
resource,
|
|
12
|
-
|
|
12
|
+
resource,
|
|
13
|
+
recordItemId,
|
|
14
|
+
label,
|
|
15
|
+
children,
|
|
16
|
+
hideText = false,
|
|
17
|
+
accessControl = { enabled: true, hideIfUnauthorized: true },
|
|
18
|
+
onSuccess,
|
|
19
|
+
undoable = false,
|
|
20
|
+
class: className = '',
|
|
13
21
|
} = $props<{
|
|
14
22
|
resource: string;
|
|
15
23
|
recordItemId: string | number;
|
|
24
|
+
label?: string;
|
|
25
|
+
children?: Snippet;
|
|
16
26
|
hideText?: boolean;
|
|
17
27
|
accessControl?: ButtonAccessControl;
|
|
18
28
|
onSuccess?: () => void;
|
|
@@ -29,6 +39,7 @@
|
|
|
29
39
|
queryOptions: { enabled: accessControl?.enabled ?? true }
|
|
30
40
|
}));
|
|
31
41
|
const hidden = $derived(accessControl?.hideIfUnauthorized && !can.allowed);
|
|
42
|
+
const displayText = $derived(label ?? i18n.t('common.delete'));
|
|
32
43
|
let confirming = $state(false);
|
|
33
44
|
|
|
34
45
|
async function handleDelete() {
|
|
@@ -59,11 +70,20 @@
|
|
|
59
70
|
variant="ghost"
|
|
60
71
|
size={hideText ? 'icon' : 'sm'}
|
|
61
72
|
class="text-destructive hover:text-destructive {className}"
|
|
73
|
+
aria-label={hideText ? displayText : undefined}
|
|
62
74
|
disabled={!can.allowed}
|
|
63
75
|
onclick={handleDelete}
|
|
64
76
|
>
|
|
65
77
|
<Trash2 class="h-4 w-4" />
|
|
66
|
-
{#if !hideText}
|
|
78
|
+
{#if !hideText}
|
|
79
|
+
<span class="ml-1">
|
|
80
|
+
{#if children}
|
|
81
|
+
{@render children()}
|
|
82
|
+
{:else}
|
|
83
|
+
{displayText}
|
|
84
|
+
{/if}
|
|
85
|
+
</span>
|
|
86
|
+
{/if}
|
|
67
87
|
</Button>
|
|
68
88
|
{/if}
|
|
69
89
|
{/if}
|
|
@@ -1,7 +1,10 @@
|
|
|
1
|
+
import type { Snippet } from 'svelte';
|
|
1
2
|
import type { ButtonAccessControl } from './access-control';
|
|
2
3
|
type $$ComponentProps = {
|
|
3
4
|
resource: string;
|
|
4
5
|
recordItemId: string | number;
|
|
6
|
+
label?: string;
|
|
7
|
+
children?: Snippet;
|
|
5
8
|
hideText?: boolean;
|
|
6
9
|
accessControl?: ButtonAccessControl;
|
|
7
10
|
onSuccess?: () => void;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
+
import type { Snippet } from 'svelte';
|
|
2
3
|
import { useNavigation, useCan, useTranslation } from '@svadmin/core';
|
|
3
4
|
import { Button } from '../ui/button/index.js';
|
|
4
5
|
import { Pencil } from '@lucide/svelte';
|
|
@@ -7,9 +8,19 @@
|
|
|
7
8
|
|
|
8
9
|
const i18n = useTranslation();
|
|
9
10
|
|
|
10
|
-
let {
|
|
11
|
+
let {
|
|
12
|
+
resource,
|
|
13
|
+
recordItemId,
|
|
14
|
+
label,
|
|
15
|
+
children,
|
|
16
|
+
hideText = false,
|
|
17
|
+
accessControl = { enabled: true, hideIfUnauthorized: true },
|
|
18
|
+
class: className = '',
|
|
19
|
+
} = $props<{
|
|
11
20
|
resource: string;
|
|
12
21
|
recordItemId: string | number;
|
|
22
|
+
label?: string;
|
|
23
|
+
children?: Snippet;
|
|
13
24
|
hideText?: boolean;
|
|
14
25
|
accessControl?: ButtonAccessControl;
|
|
15
26
|
class?: string;
|
|
@@ -24,6 +35,7 @@
|
|
|
24
35
|
queryOptions: { enabled: accessControl?.enabled ?? true }
|
|
25
36
|
}));
|
|
26
37
|
const hidden = $derived(accessControl?.hideIfUnauthorized && !can.allowed);
|
|
38
|
+
const displayText = $derived(label ?? i18n.t('common.edit'));
|
|
27
39
|
</script>
|
|
28
40
|
|
|
29
41
|
{#if !hidden}
|
|
@@ -31,10 +43,19 @@
|
|
|
31
43
|
variant="outline"
|
|
32
44
|
size={hideText ? 'icon' : 'sm'}
|
|
33
45
|
class={className}
|
|
46
|
+
aria-label={hideText ? displayText : undefined}
|
|
34
47
|
disabled={!can.allowed}
|
|
35
48
|
onclick={() => nav.edit(resource, recordItemId)}
|
|
36
49
|
>
|
|
37
50
|
<Pencil class="h-4 w-4" />
|
|
38
|
-
{#if !hideText}
|
|
51
|
+
{#if !hideText}
|
|
52
|
+
<span class="ml-1">
|
|
53
|
+
{#if children}
|
|
54
|
+
{@render children()}
|
|
55
|
+
{:else}
|
|
56
|
+
{displayText}
|
|
57
|
+
{/if}
|
|
58
|
+
</span>
|
|
59
|
+
{/if}
|
|
39
60
|
</Button>
|
|
40
61
|
{/if}
|
|
@@ -1,7 +1,10 @@
|
|
|
1
|
+
import type { Snippet } from 'svelte';
|
|
1
2
|
import type { ButtonAccessControl } from './access-control';
|
|
2
3
|
type $$ComponentProps = {
|
|
3
4
|
resource: string;
|
|
4
5
|
recordItemId: string | number;
|
|
6
|
+
label?: string;
|
|
7
|
+
children?: Snippet;
|
|
5
8
|
hideText?: boolean;
|
|
6
9
|
accessControl?: ButtonAccessControl;
|
|
7
10
|
class?: string;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
+
import type { Snippet } from 'svelte';
|
|
2
3
|
import { useExport, useCan, useTranslation } from '@svadmin/core';
|
|
3
4
|
import { Button } from '../ui/button/index.js';
|
|
4
5
|
import { Download } from '@lucide/svelte';
|
|
@@ -6,8 +7,17 @@
|
|
|
6
7
|
|
|
7
8
|
const i18n = useTranslation();
|
|
8
9
|
|
|
9
|
-
let {
|
|
10
|
+
let {
|
|
11
|
+
resource,
|
|
12
|
+
label,
|
|
13
|
+
children,
|
|
14
|
+
hideText = false,
|
|
15
|
+
accessControl = { enabled: true, hideIfUnauthorized: true },
|
|
16
|
+
class: className = '',
|
|
17
|
+
} = $props<{
|
|
10
18
|
resource: string;
|
|
19
|
+
label?: string;
|
|
20
|
+
children?: Snippet;
|
|
11
21
|
hideText?: boolean;
|
|
12
22
|
accessControl?: ButtonAccessControl;
|
|
13
23
|
class?: string;
|
|
@@ -22,18 +32,27 @@
|
|
|
22
32
|
queryOptions: { enabled: accessControl?.enabled ?? true }
|
|
23
33
|
}));
|
|
24
34
|
const hidden = $derived(accessControl?.hideIfUnauthorized && !can.allowed);
|
|
35
|
+
const displayText = $derived(label ?? i18n.t('common.export'));
|
|
25
36
|
</script>
|
|
26
37
|
|
|
27
38
|
{#if !hidden}
|
|
28
|
-
|
|
29
39
|
<Button
|
|
30
40
|
variant="outline"
|
|
31
41
|
size={hideText ? 'icon' : 'sm'}
|
|
32
42
|
class={className}
|
|
43
|
+
aria-label={hideText ? displayText : undefined}
|
|
33
44
|
disabled={isLoading || !can.allowed}
|
|
34
45
|
onclick={triggerExport}
|
|
35
46
|
>
|
|
36
47
|
<Download class="h-4 w-4" />
|
|
37
|
-
{#if !hideText}
|
|
48
|
+
{#if !hideText}
|
|
49
|
+
<span class="ml-1">
|
|
50
|
+
{#if children}
|
|
51
|
+
{@render children()}
|
|
52
|
+
{:else}
|
|
53
|
+
{displayText}
|
|
54
|
+
{/if}
|
|
55
|
+
</span>
|
|
56
|
+
{/if}
|
|
38
57
|
</Button>
|
|
39
58
|
{/if}
|
|
@@ -1,6 +1,9 @@
|
|
|
1
|
+
import type { Snippet } from 'svelte';
|
|
1
2
|
import type { ButtonAccessControl } from './access-control';
|
|
2
3
|
type $$ComponentProps = {
|
|
3
4
|
resource: string;
|
|
5
|
+
label?: string;
|
|
6
|
+
children?: Snippet;
|
|
4
7
|
hideText?: boolean;
|
|
5
8
|
accessControl?: ButtonAccessControl;
|
|
6
9
|
class?: string;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
+
import type { Snippet } from 'svelte';
|
|
2
3
|
import { useImport, useCan, useTranslation } from '@svadmin/core';
|
|
3
4
|
import { Button } from '../ui/button/index.js';
|
|
4
5
|
import { Upload } from '@lucide/svelte';
|
|
@@ -6,8 +7,18 @@
|
|
|
6
7
|
|
|
7
8
|
const i18n = useTranslation();
|
|
8
9
|
|
|
9
|
-
let {
|
|
10
|
+
let {
|
|
11
|
+
resource,
|
|
12
|
+
label,
|
|
13
|
+
children,
|
|
14
|
+
hideText = false,
|
|
15
|
+
onFinish,
|
|
16
|
+
accessControl = { enabled: true, hideIfUnauthorized: true },
|
|
17
|
+
class: className = '',
|
|
18
|
+
} = $props<{
|
|
10
19
|
resource: string;
|
|
20
|
+
label?: string;
|
|
21
|
+
children?: Snippet;
|
|
11
22
|
hideText?: boolean;
|
|
12
23
|
onFinish?: (result: { succeeded: unknown[]; errored: { request: unknown; error: unknown }[] }) => void;
|
|
13
24
|
accessControl?: ButtonAccessControl;
|
|
@@ -21,6 +32,15 @@
|
|
|
21
32
|
onFinish: (result) => onFinish?.(result),
|
|
22
33
|
});
|
|
23
34
|
|
|
35
|
+
const can = useCan(() => ({
|
|
36
|
+
resource,
|
|
37
|
+
action: 'import',
|
|
38
|
+
params: accessControl?.params,
|
|
39
|
+
meta: accessControl?.meta,
|
|
40
|
+
queryOptions: { enabled: accessControl?.enabled ?? true },
|
|
41
|
+
}));
|
|
42
|
+
const hidden = $derived(accessControl?.hideIfUnauthorized && !can.allowed);
|
|
43
|
+
|
|
24
44
|
function triggerImport() {
|
|
25
45
|
fileInput?.click();
|
|
26
46
|
}
|
|
@@ -34,32 +54,34 @@
|
|
|
34
54
|
}
|
|
35
55
|
}
|
|
36
56
|
|
|
37
|
-
const
|
|
38
|
-
resource,
|
|
39
|
-
action: 'import',
|
|
40
|
-
params: accessControl?.params,
|
|
41
|
-
meta: accessControl?.meta,
|
|
42
|
-
queryOptions: { enabled: accessControl?.enabled ?? true }
|
|
43
|
-
}));
|
|
44
|
-
const hidden = $derived(accessControl?.hideIfUnauthorized && !can.allowed);
|
|
57
|
+
const displayText = $derived(label ?? i18n.t('common.import'));
|
|
45
58
|
</script>
|
|
46
59
|
|
|
47
60
|
{#if !hidden}
|
|
48
|
-
<input
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
/>
|
|
61
|
+
<input
|
|
62
|
+
type="file"
|
|
63
|
+
accept={importHook.inputProps.accept}
|
|
64
|
+
class="hidden"
|
|
65
|
+
bind:this={fileInput}
|
|
66
|
+
onchange={handleFileChange}
|
|
67
|
+
/>
|
|
55
68
|
<Button
|
|
56
69
|
variant="outline"
|
|
57
70
|
size={hideText ? 'icon' : 'sm'}
|
|
58
71
|
class={className}
|
|
72
|
+
aria-label={hideText ? displayText : undefined}
|
|
59
73
|
disabled={importHook.isLoading || !can.allowed}
|
|
60
74
|
onclick={triggerImport}
|
|
61
75
|
>
|
|
62
76
|
<Upload class="h-4 w-4" />
|
|
63
|
-
{#if !hideText}
|
|
77
|
+
{#if !hideText}
|
|
78
|
+
<span class="ml-1">
|
|
79
|
+
{#if children}
|
|
80
|
+
{@render children()}
|
|
81
|
+
{:else}
|
|
82
|
+
{displayText}
|
|
83
|
+
{/if}
|
|
84
|
+
</span>
|
|
85
|
+
{/if}
|
|
64
86
|
</Button>
|
|
65
87
|
{/if}
|
|
@@ -1,14 +1,16 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
+
import type { Snippet } from 'svelte';
|
|
2
3
|
import { useNavigation, getResource, useTranslation } from '@svadmin/core';
|
|
3
4
|
import { Button } from '../ui/button/index.js';
|
|
4
5
|
import { List } from '@lucide/svelte';
|
|
5
6
|
|
|
6
7
|
const i18n = useTranslation();
|
|
7
8
|
|
|
8
|
-
let { resource: resourceName, hideText = false, label, onBeforeNavigate, class: className = '' } = $props<{
|
|
9
|
+
let { resource: resourceName, hideText = false, label, children, onBeforeNavigate, class: className = '' } = $props<{
|
|
9
10
|
resource: string;
|
|
10
11
|
hideText?: boolean;
|
|
11
12
|
label?: string;
|
|
13
|
+
children?: Snippet;
|
|
12
14
|
onBeforeNavigate?: (navigate: () => void) => void;
|
|
13
15
|
class?: string;
|
|
14
16
|
}>();
|
|
@@ -30,8 +32,17 @@
|
|
|
30
32
|
variant="outline"
|
|
31
33
|
size={hideText ? 'icon' : 'sm'}
|
|
32
34
|
class={className}
|
|
35
|
+
aria-label={hideText ? displayLabel : undefined}
|
|
33
36
|
onclick={navigateToList}
|
|
34
37
|
>
|
|
35
38
|
<List class="h-4 w-4" />
|
|
36
|
-
{#if !hideText}
|
|
39
|
+
{#if !hideText}
|
|
40
|
+
<span class="ml-1">
|
|
41
|
+
{#if children}
|
|
42
|
+
{@render children()}
|
|
43
|
+
{:else}
|
|
44
|
+
{displayLabel}
|
|
45
|
+
{/if}
|
|
46
|
+
</span>
|
|
47
|
+
{/if}
|
|
37
48
|
</Button>
|
|
@@ -1,12 +1,21 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
+
import type { Snippet } from 'svelte';
|
|
2
3
|
import { useInvalidate, useTranslation } from '@svadmin/core';
|
|
3
4
|
import { Button } from '../ui/button/index.js';
|
|
4
5
|
import { RefreshCw } from '@lucide/svelte';
|
|
5
6
|
|
|
6
7
|
const i18n = useTranslation();
|
|
7
8
|
|
|
8
|
-
let {
|
|
9
|
+
let {
|
|
10
|
+
resource,
|
|
11
|
+
label,
|
|
12
|
+
children,
|
|
13
|
+
hideText = false,
|
|
14
|
+
class: className = '',
|
|
15
|
+
} = $props<{
|
|
9
16
|
resource: string;
|
|
17
|
+
label?: string;
|
|
18
|
+
children?: Snippet;
|
|
10
19
|
hideText?: boolean;
|
|
11
20
|
class?: string;
|
|
12
21
|
}>();
|
|
@@ -25,14 +34,25 @@
|
|
|
25
34
|
if (spinTimer) clearTimeout(spinTimer);
|
|
26
35
|
spinTimer = setTimeout(() => { spinning = false; }, 600);
|
|
27
36
|
}
|
|
37
|
+
|
|
38
|
+
const displayText = $derived(label ?? i18n.t('common.refresh'));
|
|
28
39
|
</script>
|
|
29
40
|
|
|
30
41
|
<Button
|
|
31
42
|
variant="ghost"
|
|
32
43
|
size={hideText ? 'icon' : 'sm'}
|
|
33
44
|
class={className}
|
|
45
|
+
aria-label={hideText ? displayText : undefined}
|
|
34
46
|
onclick={refresh}
|
|
35
47
|
>
|
|
36
48
|
<RefreshCw class="h-4 w-4 {spinning ? 'animate-spin' : ''}" />
|
|
37
|
-
{#if !hideText}
|
|
49
|
+
{#if !hideText}
|
|
50
|
+
<span class="ml-1">
|
|
51
|
+
{#if children}
|
|
52
|
+
{@render children()}
|
|
53
|
+
{:else}
|
|
54
|
+
{displayText}
|
|
55
|
+
{/if}
|
|
56
|
+
</span>
|
|
57
|
+
{/if}
|
|
38
58
|
</Button>
|
|
@@ -1,16 +1,28 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
+
import type { Snippet } from 'svelte';
|
|
2
3
|
import { useTranslation } from '@svadmin/core';
|
|
3
4
|
import { Button } from '../ui/button/index.js';
|
|
4
5
|
import { Save, Loader2 } from '@lucide/svelte';
|
|
5
6
|
|
|
6
7
|
const i18n = useTranslation();
|
|
7
8
|
|
|
8
|
-
let {
|
|
9
|
+
let {
|
|
10
|
+
loading = false,
|
|
11
|
+
label,
|
|
12
|
+
children,
|
|
13
|
+
hideText = false,
|
|
14
|
+
type = 'submit',
|
|
15
|
+
class: className = '',
|
|
16
|
+
} = $props<{
|
|
9
17
|
loading?: boolean;
|
|
18
|
+
label?: string;
|
|
19
|
+
children?: Snippet;
|
|
10
20
|
hideText?: boolean;
|
|
11
21
|
type?: 'submit' | 'button';
|
|
12
22
|
class?: string;
|
|
13
23
|
}>();
|
|
24
|
+
|
|
25
|
+
const displayText = $derived(label ?? i18n.t('common.save'));
|
|
14
26
|
</script>
|
|
15
27
|
|
|
16
28
|
<Button
|
|
@@ -18,6 +30,7 @@
|
|
|
18
30
|
variant="default"
|
|
19
31
|
size={hideText ? 'icon' : 'default'}
|
|
20
32
|
class={className}
|
|
33
|
+
aria-label={hideText ? displayText : undefined}
|
|
21
34
|
disabled={loading}
|
|
22
35
|
>
|
|
23
36
|
{#if loading}
|
|
@@ -25,5 +38,13 @@
|
|
|
25
38
|
{:else}
|
|
26
39
|
<Save class="h-4 w-4" />
|
|
27
40
|
{/if}
|
|
28
|
-
{#if !hideText}
|
|
41
|
+
{#if !hideText}
|
|
42
|
+
<span class="ml-1">
|
|
43
|
+
{#if children}
|
|
44
|
+
{@render children()}
|
|
45
|
+
{:else}
|
|
46
|
+
{displayText}
|
|
47
|
+
{/if}
|
|
48
|
+
</span>
|
|
49
|
+
{/if}
|
|
29
50
|
</Button>
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
+
import type { Snippet } from 'svelte';
|
|
2
3
|
import { useNavigation, useCan, useTranslation } from '@svadmin/core';
|
|
3
4
|
import { Button } from '../ui/button/index.js';
|
|
4
5
|
import { Eye } from '@lucide/svelte';
|
|
@@ -7,9 +8,20 @@
|
|
|
7
8
|
|
|
8
9
|
const i18n = useTranslation();
|
|
9
10
|
|
|
10
|
-
let {
|
|
11
|
+
let {
|
|
12
|
+
resource,
|
|
13
|
+
recordItemId,
|
|
14
|
+
label,
|
|
15
|
+
children,
|
|
16
|
+
hideText = false,
|
|
17
|
+
accessControl = { enabled: true, hideIfUnauthorized: true },
|
|
18
|
+
onBeforeNavigate,
|
|
19
|
+
class: className = '',
|
|
20
|
+
} = $props<{
|
|
11
21
|
resource: string;
|
|
12
22
|
recordItemId: string | number;
|
|
23
|
+
label?: string;
|
|
24
|
+
children?: Snippet;
|
|
13
25
|
hideText?: boolean;
|
|
14
26
|
accessControl?: ButtonAccessControl;
|
|
15
27
|
onBeforeNavigate?: (navigate: () => void) => void;
|
|
@@ -25,6 +37,7 @@
|
|
|
25
37
|
queryOptions: { enabled: accessControl?.enabled ?? true }
|
|
26
38
|
}));
|
|
27
39
|
const hidden = $derived(accessControl?.hideIfUnauthorized && !can.allowed);
|
|
40
|
+
const displayText = $derived(label ?? i18n.t('common.detail'));
|
|
28
41
|
|
|
29
42
|
function navigateToRecord() {
|
|
30
43
|
const navigate = () => nav.show(resource, recordItemId);
|
|
@@ -34,15 +47,23 @@
|
|
|
34
47
|
</script>
|
|
35
48
|
|
|
36
49
|
{#if !hidden}
|
|
37
|
-
|
|
38
50
|
<Button
|
|
39
51
|
variant="ghost"
|
|
40
52
|
size={hideText ? 'icon' : 'sm'}
|
|
41
53
|
class={className}
|
|
54
|
+
aria-label={hideText ? displayText : undefined}
|
|
42
55
|
disabled={!can.allowed}
|
|
43
56
|
onclick={navigateToRecord}
|
|
44
57
|
>
|
|
45
58
|
<Eye class="h-4 w-4" />
|
|
46
|
-
{#if !hideText}
|
|
59
|
+
{#if !hideText}
|
|
60
|
+
<span class="ml-1">
|
|
61
|
+
{#if children}
|
|
62
|
+
{@render children()}
|
|
63
|
+
{:else}
|
|
64
|
+
{displayText}
|
|
65
|
+
{/if}
|
|
66
|
+
</span>
|
|
67
|
+
{/if}
|
|
47
68
|
</Button>
|
|
48
69
|
{/if}
|
|
@@ -1,7 +1,10 @@
|
|
|
1
|
+
import type { Snippet } from 'svelte';
|
|
1
2
|
import type { ButtonAccessControl } from './access-control';
|
|
2
3
|
type $$ComponentProps = {
|
|
3
4
|
resource: string;
|
|
4
5
|
recordItemId: string | number;
|
|
6
|
+
label?: string;
|
|
7
|
+
children?: Snippet;
|
|
5
8
|
hideText?: boolean;
|
|
6
9
|
accessControl?: ButtonAccessControl;
|
|
7
10
|
onBeforeNavigate?: (navigate: () => void) => void;
|