@sierra-95/svelte-scaffold 1.0.72 → 1.0.73

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.
@@ -1 +1,8 @@
1
+ import type { Section } from '../index.js';
1
2
  export declare function validateLayoutMenuSections(sections: Array<any>): void;
3
+ export declare function filterSectionsByRole(sections: Section[], userRole: string): {
4
+ items: import("../index.js").SectionItem[];
5
+ label: string;
6
+ hidden?: boolean;
7
+ role?: string;
8
+ }[];
@@ -1,4 +1,5 @@
1
- import { setToastMessage } from '../index.js';
1
+ import { get } from 'svelte/store';
2
+ import { setToastMessage, layoutStore } from '../index.js';
2
3
  export function validateLayoutMenuSections(sections) {
3
4
  const seenPaths = new Set();
4
5
  for (const section of sections) {
@@ -22,3 +23,50 @@ export function validateLayoutMenuSections(sections) {
22
23
  }
23
24
  }
24
25
  }
26
+ function getRoleLevel(role) {
27
+ if (!role)
28
+ return 0;
29
+ const state = get(layoutStore);
30
+ return role in state.ROLE_LEVELS ? state.ROLE_LEVELS[role] : 0;
31
+ }
32
+ function hasAccess(userRole, requiredRole) {
33
+ if (!requiredRole)
34
+ return true;
35
+ return getRoleLevel(userRole) >= getRoleLevel(requiredRole);
36
+ }
37
+ function isDefined(value) {
38
+ return value != null;
39
+ }
40
+ export function filterSectionsByRole(sections, userRole) {
41
+ return sections
42
+ .map(section => {
43
+ // No access to section → remove entirely
44
+ if (!hasAccess(userRole, section.role))
45
+ return null;
46
+ const items = section.items
47
+ .map(item => {
48
+ const itemRole = item.role ?? section.role;
49
+ // No access to item → remove
50
+ if (!hasAccess(userRole, itemRole))
51
+ return null;
52
+ // Handle children
53
+ if (item.children) {
54
+ const children = item.children.filter((child) => {
55
+ const childRole = child.role ?? itemRole;
56
+ return hasAccess(userRole, childRole);
57
+ });
58
+ // No visible children → remove parent
59
+ if (children.length === 0)
60
+ return null;
61
+ return { ...item, children };
62
+ }
63
+ return item;
64
+ })
65
+ .filter(isDefined);
66
+ // No visible items → remove section
67
+ if (items.length === 0)
68
+ return null;
69
+ return { ...section, items };
70
+ })
71
+ .filter(isDefined);
72
+ }
@@ -3,13 +3,16 @@
3
3
  import { onMount } from 'svelte';
4
4
  import { page } from '$app/state';
5
5
  import { afterNavigate, beforeNavigate } from '$app/navigation';
6
- import { isLoading, validateLayoutMenuSections, GlobalSearch, layoutStore } from '../../../index.js';
6
+ import { isLoading, validateLayoutMenuSections, GlobalSearch, layoutStore, filterSectionsByRole } from '../../../index.js';
7
7
 
8
8
  export let toggleMenu: () => void;
9
9
  export let closeMobileMenu: () => void;
10
10
  export let isMenuOpen: boolean;
11
11
 
12
- $: sections = $layoutStore.sections;
12
+ $: sections = filterSectionsByRole(
13
+ $layoutStore.sections,
14
+ $layoutStore.userRole ?? 'user'
15
+ );
13
16
 
14
17
  function isParentActive(item: any, pathname: string) {
15
18
  if (item.path === '/') {
package/dist/index.d.ts CHANGED
@@ -50,7 +50,7 @@ export type { FileInputStoreMediaItem } from './stores/modules/fileInput.js';
50
50
  export { toastCarrier, setToastMessage, clearToastMessage } from './stores/modules/toast.js';
51
51
  export { layoutStore, resetLayoutStore } from './stores/modules/layout.js';
52
52
  export { getPreviewUrlForMedia, toggleSelectForMedia, removeFileForMedia, DOCUMENT_MIME_TYPES, IMAGE_MIME_TYPES_PREVIEW } from './Hooks/preview.js';
53
- export { validateLayoutMenuSections } from './Hooks/layout_menu.js';
53
+ export { validateLayoutMenuSections, filterSectionsByRole } from './Hooks/layout_menu.js';
54
54
  export { buttonRipple } from './Hooks/button.js';
55
55
  export { buildSearchIndex } from './Hooks/buildSearch.js';
56
56
  export { isValidEmail } from './Hooks/validateForms.js';
package/dist/index.js CHANGED
@@ -63,7 +63,7 @@ export { toastCarrier, setToastMessage, clearToastMessage } from './stores/modul
63
63
  export { layoutStore, resetLayoutStore } from './stores/modules/layout.js';
64
64
  //#######################HOOKS/UTILS########################
65
65
  export { getPreviewUrlForMedia, toggleSelectForMedia, removeFileForMedia, DOCUMENT_MIME_TYPES, IMAGE_MIME_TYPES_PREVIEW } from './Hooks/preview.js';
66
- export { validateLayoutMenuSections } from './Hooks/layout_menu.js';
66
+ export { validateLayoutMenuSections, filterSectionsByRole } from './Hooks/layout_menu.js';
67
67
  export { buttonRipple } from './Hooks/button.js';
68
68
  export { buildSearchIndex } from './Hooks/buildSearch.js';
69
69
  export { isValidEmail } from './Hooks/validateForms.js';
@@ -4,12 +4,14 @@ export type SectionItem = {
4
4
  label: string;
5
5
  icon?: string;
6
6
  hidden?: boolean;
7
+ role?: string;
7
8
  children?: SectionItem[];
8
9
  TOC?: Partial<Record<string, string>>;
9
10
  };
10
11
  export type Section = {
11
12
  label: string;
12
13
  hidden?: boolean;
14
+ role?: string;
13
15
  items: SectionItem[];
14
16
  };
15
17
  export type LayoutState = {
@@ -26,6 +28,8 @@ export type LayoutState = {
26
28
  toggleMenuSize: string;
27
29
  menuActiveIconColor: string;
28
30
  backgroundColor: string;
31
+ userRole?: string;
32
+ ROLE_LEVELS: Record<any, number>;
29
33
  };
30
34
  export declare const layoutStore: import("svelte/store").Writable<LayoutState>;
31
35
  export declare function resetLayoutStore(): void;
@@ -12,7 +12,9 @@ const defaultLayoutState = {
12
12
  toggleMenuColor: 'black',
13
13
  toggleMenuSize: "25px",
14
14
  menuActiveIconColor: 'var(--primary-bg)',
15
- backgroundColor: ''
15
+ backgroundColor: '',
16
+ userRole: 'user',
17
+ ROLE_LEVELS: { user: 1 }
16
18
  };
17
19
  export const layoutStore = writable({
18
20
  ...defaultLayoutState
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sierra-95/svelte-scaffold",
3
- "version": "1.0.72",
3
+ "version": "1.0.73",
4
4
  "scripts": {
5
5
  "dev": "vite dev",
6
6
  "build": "vite build && npm run prepack",