@profidev/pleiades 1.8.1 → 1.9.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/nav/sidebar/sidebar-content.svelte +44 -33
- package/dist/components/nav/sidebar/sidebar-content.svelte.d.ts +1 -1
- package/dist/components/nav/sidebar/sidebar-header.svelte +4 -2
- package/dist/components/nav/sidebar/sidebar-header.svelte.d.ts +1 -0
- package/dist/components/nav/sidebar/sidebar-user.svelte +27 -12
- package/dist/components/nav/sidebar/sidebar-user.svelte.d.ts +3 -3
- package/dist/components/nav/sidebar/sidebar.svelte +16 -10
- package/dist/components/nav/sidebar/sidebar.svelte.d.ts +3 -1
- package/package.json +3 -1
|
@@ -3,60 +3,71 @@
|
|
|
3
3
|
import * as Sidebar from '../../ui/sidebar';
|
|
4
4
|
import type {
|
|
5
5
|
NavGroup,
|
|
6
|
-
NavItem,
|
|
7
6
|
SidebarUserInfo
|
|
8
7
|
} from './types';
|
|
9
8
|
|
|
10
9
|
interface Props {
|
|
11
10
|
items: NavGroup[];
|
|
12
|
-
user: SidebarUserInfo
|
|
11
|
+
user: SidebarUserInfo | Promise<SidebarUserInfo>;
|
|
13
12
|
}
|
|
14
13
|
|
|
15
|
-
const { items, user }: Props = $props();
|
|
14
|
+
const { items, user: userPromise }: Props = $props();
|
|
16
15
|
|
|
17
|
-
|
|
16
|
+
const filteredItems = (items: NavGroup[], user: SidebarUserInfo) =>
|
|
18
17
|
items
|
|
19
|
-
.map((group) => {
|
|
20
|
-
group
|
|
18
|
+
.map((group) => ({
|
|
19
|
+
...group,
|
|
20
|
+
items: group.items.filter((item) => {
|
|
21
21
|
if (item.requiredPermission) {
|
|
22
|
-
return user
|
|
22
|
+
return user?.permissions.includes(item.requiredPermission);
|
|
23
23
|
}
|
|
24
24
|
return true;
|
|
25
|
-
})
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
.filter((item) => item.items.length > 0)
|
|
29
|
-
);
|
|
25
|
+
})
|
|
26
|
+
}))
|
|
27
|
+
.filter((item) => item.items.length > 0);
|
|
30
28
|
|
|
31
|
-
|
|
29
|
+
const current = (filteredItems: NavGroup[]) =>
|
|
32
30
|
filteredItems
|
|
33
31
|
.flatMap((group) => group.items)
|
|
34
32
|
.filter((item) => page.url.pathname.startsWith(item.href))
|
|
35
|
-
.sort((a, b) => b.href.length - a.href.length)[0] ?? undefined
|
|
36
|
-
);
|
|
33
|
+
.sort((a, b) => b.href.length - a.href.length)[0] ?? undefined;
|
|
37
34
|
</script>
|
|
38
35
|
|
|
39
|
-
{#
|
|
36
|
+
{#await userPromise}
|
|
40
37
|
<Sidebar.Group>
|
|
41
|
-
<Sidebar.GroupLabel>
|
|
42
|
-
<Sidebar.Menu
|
|
43
|
-
{#each
|
|
38
|
+
<Sidebar.GroupLabel>Loading...</Sidebar.GroupLabel>
|
|
39
|
+
<Sidebar.Menu>
|
|
40
|
+
{#each Array.from({ length: 3 }) as _}
|
|
44
41
|
<Sidebar.MenuItem>
|
|
45
|
-
<Sidebar.
|
|
46
|
-
tooltipContent={item.label}
|
|
47
|
-
class={item.href === current?.href ? 'bg-muted' : ''}
|
|
48
|
-
>
|
|
49
|
-
{#snippet child({ props })}
|
|
50
|
-
<a href={item.href} {...props}>
|
|
51
|
-
{#if item.icon}
|
|
52
|
-
<item.icon />
|
|
53
|
-
{/if}
|
|
54
|
-
<span>{item.label}</span>
|
|
55
|
-
</a>
|
|
56
|
-
{/snippet}
|
|
57
|
-
</Sidebar.MenuButton>
|
|
42
|
+
<Sidebar.MenuSkeleton />
|
|
58
43
|
</Sidebar.MenuItem>
|
|
59
44
|
{/each}
|
|
60
45
|
</Sidebar.Menu>
|
|
61
46
|
</Sidebar.Group>
|
|
62
|
-
{
|
|
47
|
+
{:then user}
|
|
48
|
+
{@const filtered = filteredItems(items, user)}
|
|
49
|
+
{#each filtered as group}
|
|
50
|
+
<Sidebar.Group>
|
|
51
|
+
<Sidebar.GroupLabel>{group.label}</Sidebar.GroupLabel>
|
|
52
|
+
<Sidebar.Menu class="gap-1">
|
|
53
|
+
{#each group.items as item}
|
|
54
|
+
<Sidebar.MenuItem>
|
|
55
|
+
<Sidebar.MenuButton
|
|
56
|
+
tooltipContent={item.label}
|
|
57
|
+
class={item.href === current(filtered)?.href ? 'bg-muted' : ''}
|
|
58
|
+
>
|
|
59
|
+
{#snippet child({ props })}
|
|
60
|
+
<a href={item.href} {...props}>
|
|
61
|
+
{#if item.icon}
|
|
62
|
+
<item.icon />
|
|
63
|
+
{/if}
|
|
64
|
+
<span>{item.label}</span>
|
|
65
|
+
</a>
|
|
66
|
+
{/snippet}
|
|
67
|
+
</Sidebar.MenuButton>
|
|
68
|
+
</Sidebar.MenuItem>
|
|
69
|
+
{/each}
|
|
70
|
+
</Sidebar.Menu>
|
|
71
|
+
</Sidebar.Group>
|
|
72
|
+
{/each}
|
|
73
|
+
{/await}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { NavGroup, SidebarUserInfo } from './types';
|
|
2
2
|
interface Props {
|
|
3
3
|
items: NavGroup[];
|
|
4
|
-
user: SidebarUserInfo
|
|
4
|
+
user: SidebarUserInfo | Promise<SidebarUserInfo>;
|
|
5
5
|
}
|
|
6
6
|
declare const SidebarContent: import("svelte").Component<Props, {}, "">;
|
|
7
7
|
type SidebarContent = ReturnType<typeof SidebarContent>;
|
|
@@ -4,14 +4,16 @@
|
|
|
4
4
|
import PanelLeftOpen from '@lucide/svelte/icons/panel-left-open';
|
|
5
5
|
import PanelLeftClose from '@lucide/svelte/icons/panel-left-close';
|
|
6
6
|
import type { Component } from 'svelte';
|
|
7
|
+
import { cn } from '../../../utils';
|
|
7
8
|
|
|
8
9
|
interface Props {
|
|
9
10
|
version: string;
|
|
10
11
|
app_name: string;
|
|
12
|
+
iconClass?: string;
|
|
11
13
|
app_icon?: Component;
|
|
12
14
|
}
|
|
13
15
|
|
|
14
|
-
let { version, app_name, app_icon }: Props = $props();
|
|
16
|
+
let { version, app_name, app_icon, iconClass }: Props = $props();
|
|
15
17
|
|
|
16
18
|
let sidebar = Sidebar.useSidebar();
|
|
17
19
|
let isOpen = $derived(sidebar.props.open());
|
|
@@ -30,7 +32,7 @@
|
|
|
30
32
|
<div
|
|
31
33
|
class="bg-sidebar-primary text-sidebar-primary-foreground flex aspect-square size-8 items-center justify-center rounded-lg"
|
|
32
34
|
>
|
|
33
|
-
<AppIcon class=
|
|
35
|
+
<AppIcon class={cn('size-4 text-[#9db6ed]', iconClass)} />
|
|
34
36
|
</div>
|
|
35
37
|
<div class="flex flex-col gap-0.5 leading-none">
|
|
36
38
|
<span class="font-medium text-nowrap">{app_name}</span>
|
|
@@ -7,15 +7,16 @@
|
|
|
7
7
|
import SettingsIcon from '@lucide/svelte/icons/settings';
|
|
8
8
|
import { goto } from '$app/navigation';
|
|
9
9
|
import { disconnectWebsocket } from '../../../backend/updater.svelte';
|
|
10
|
+
import type { SidebarUserInfo } from './types';
|
|
11
|
+
import { Skeleton } from '../../ui/skeleton';
|
|
10
12
|
|
|
11
13
|
interface Props {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
avatar: string;
|
|
14
|
+
user: SidebarUserInfo | Promise<SidebarUserInfo>;
|
|
15
|
+
avatar?: string;
|
|
15
16
|
logout: () => Promise<{ error?: any }>;
|
|
16
17
|
}
|
|
17
18
|
|
|
18
|
-
let {
|
|
19
|
+
let { logout, user: userPromise, avatar }: Props = $props();
|
|
19
20
|
|
|
20
21
|
const sidebar = Sidebar.useSidebar();
|
|
21
22
|
</script>
|
|
@@ -31,12 +32,19 @@
|
|
|
31
32
|
{...props}
|
|
32
33
|
>
|
|
33
34
|
<Avatar.Root class="size-8 rounded-lg">
|
|
34
|
-
|
|
35
|
-
|
|
35
|
+
{#await userPromise then user}
|
|
36
|
+
<Avatar.Image src={avatar} alt={user.name} />
|
|
37
|
+
{/await}
|
|
38
|
+
<Avatar.Fallback class="rounded-full">?</Avatar.Fallback>
|
|
36
39
|
</Avatar.Root>
|
|
37
40
|
<div class="grid flex-1 text-start text-sm leading-tight">
|
|
38
|
-
|
|
39
|
-
|
|
41
|
+
{#await userPromise}
|
|
42
|
+
<Skeleton class="mb-1 h-4" />
|
|
43
|
+
<Skeleton class="h-3" />
|
|
44
|
+
{:then user}
|
|
45
|
+
<span class="truncate font-medium">{user.name}</span>
|
|
46
|
+
<span class="truncate text-xs">{user.email}</span>
|
|
47
|
+
{/await}
|
|
40
48
|
</div>
|
|
41
49
|
<ChevronsUpDownIcon class="ms-auto size-4" />
|
|
42
50
|
</Sidebar.MenuButton>
|
|
@@ -51,12 +59,19 @@
|
|
|
51
59
|
<DropdownMenu.Label class="p-0 font-normal">
|
|
52
60
|
<div class="flex items-center gap-2 px-1 py-1.5 text-start text-sm">
|
|
53
61
|
<Avatar.Root class="size-8 rounded-lg">
|
|
54
|
-
|
|
55
|
-
|
|
62
|
+
{#await userPromise then user}
|
|
63
|
+
<Avatar.Image src={avatar} alt={user.name} />
|
|
64
|
+
{/await}
|
|
65
|
+
<Avatar.Fallback class="rounded-full">?</Avatar.Fallback>
|
|
56
66
|
</Avatar.Root>
|
|
57
67
|
<div class="grid flex-1 text-start text-sm leading-tight">
|
|
58
|
-
|
|
59
|
-
|
|
68
|
+
{#await userPromise}
|
|
69
|
+
<Skeleton class="mb-1 h-4" />
|
|
70
|
+
<Skeleton class="h-3" />
|
|
71
|
+
{:then user}
|
|
72
|
+
<span class="truncate font-medium">{user.name}</span>
|
|
73
|
+
<span class="truncate text-xs">{user.email}</span>
|
|
74
|
+
{/await}
|
|
60
75
|
</div>
|
|
61
76
|
</div>
|
|
62
77
|
</DropdownMenu.Label>
|
|
@@ -7,34 +7,40 @@
|
|
|
7
7
|
import type { NavGroup, SidebarUserInfo } from './types';
|
|
8
8
|
|
|
9
9
|
interface Props {
|
|
10
|
-
user: SidebarUserInfo
|
|
10
|
+
user: SidebarUserInfo | Promise<SidebarUserInfo>;
|
|
11
|
+
avatar?: string;
|
|
11
12
|
children: Snippet;
|
|
12
13
|
version: string;
|
|
13
14
|
app_name: string;
|
|
14
15
|
app_icon?: Component;
|
|
16
|
+
iconClass?: string;
|
|
15
17
|
items: NavGroup[];
|
|
16
18
|
logout: () => Promise<{ error?: any }>;
|
|
17
19
|
}
|
|
18
20
|
|
|
19
|
-
const {
|
|
20
|
-
|
|
21
|
+
const {
|
|
22
|
+
children,
|
|
23
|
+
user,
|
|
24
|
+
avatar,
|
|
25
|
+
version,
|
|
26
|
+
app_name,
|
|
27
|
+
app_icon,
|
|
28
|
+
items,
|
|
29
|
+
logout,
|
|
30
|
+
iconClass
|
|
31
|
+
}: Props = $props();
|
|
21
32
|
</script>
|
|
22
33
|
|
|
23
34
|
<Sidebar.Provider>
|
|
24
35
|
<Sidebar.Root collapsible="icon" variant="floating">
|
|
25
36
|
<Sidebar.Header>
|
|
26
|
-
<SidebarHeader {app_name} {app_icon} {version} />
|
|
37
|
+
<SidebarHeader {app_name} {app_icon} {version} {iconClass} />
|
|
27
38
|
</Sidebar.Header>
|
|
28
39
|
<Sidebar.Content>
|
|
29
40
|
<SidebarContent {items} {user} />
|
|
30
41
|
</Sidebar.Content>
|
|
31
42
|
<Sidebar.Footer>
|
|
32
|
-
<SidebarUser
|
|
33
|
-
name={user.name}
|
|
34
|
-
email={user.email}
|
|
35
|
-
avatar={`data:image/webp;base64,${user.avatar || ''}`}
|
|
36
|
-
{logout}
|
|
37
|
-
/>
|
|
43
|
+
<SidebarUser {avatar} {user} {logout} />
|
|
38
44
|
</Sidebar.Footer>
|
|
39
45
|
</Sidebar.Root>
|
|
40
46
|
<Sidebar.Inset>
|
|
@@ -2,11 +2,13 @@ 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: SidebarUserInfo
|
|
5
|
+
user: SidebarUserInfo | Promise<SidebarUserInfo>;
|
|
6
|
+
avatar?: string;
|
|
6
7
|
children: Snippet;
|
|
7
8
|
version: string;
|
|
8
9
|
app_name: string;
|
|
9
10
|
app_icon?: Component;
|
|
11
|
+
iconClass?: string;
|
|
10
12
|
items: NavGroup[];
|
|
11
13
|
logout: () => Promise<{
|
|
12
14
|
error?: any;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@profidev/pleiades",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.9.0",
|
|
4
4
|
"repository": {
|
|
5
5
|
"type": "git",
|
|
6
6
|
"url": "https://github.com/Profiidev/pleiades"
|
|
@@ -796,6 +796,7 @@
|
|
|
796
796
|
"zod": "^4.0.0"
|
|
797
797
|
},
|
|
798
798
|
"devDependencies": {
|
|
799
|
+
"@fontsource-variable/inter": "5.2.8",
|
|
799
800
|
"@jsrepo/transform-oxfmt": "^7.0.0",
|
|
800
801
|
"@sveltejs/adapter-auto": "7.0.1",
|
|
801
802
|
"@sveltejs/package": "2.5.7",
|
|
@@ -808,6 +809,7 @@
|
|
|
808
809
|
"oxlint-tsgolint": "0.23.0",
|
|
809
810
|
"prettier-plugin-svelte": "4.0.1",
|
|
810
811
|
"publint": "0.3.21",
|
|
812
|
+
"shadcn-svelte": "1.2.7",
|
|
811
813
|
"svelte-check": "4.4.8",
|
|
812
814
|
"tailwindcss": "4.3.0",
|
|
813
815
|
"tw-animate-css": "1.4.0",
|