@veiag/payload-enhanced-sidebar 0.1.0 → 0.1.1

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/README.md CHANGED
@@ -73,6 +73,15 @@ export default buildConfig({
73
73
  label: { en: 'Content', uk: 'Контент' },
74
74
  collections: ['posts', 'pages', 'categories'],
75
75
  },
76
+ // Link to external documentation
77
+ {
78
+ id: 'docs',
79
+ type: 'link',
80
+ href: 'https://payloadcms.com/',
81
+ icon: 'BookOpen',
82
+ isExternal: true,
83
+ label: { en: 'Documentation', uk: 'Документація' },
84
+ },
76
85
  // E-commerce tab with custom items
77
86
  {
78
87
  id: 'ecommerce',
@@ -104,6 +113,12 @@ export default buildConfig({
104
113
  label: { en: 'API Keys', uk: 'API Ключі' },
105
114
  // No group - will appear at the bottom
106
115
  },
116
+ {
117
+ slug:'external-link',
118
+ href: 'https://example.com',
119
+ isExternal: true,
120
+ label: { en: 'External Link', uk: 'Зовнішнє Посилання'}
121
+ }
107
122
  ],
108
123
  },
109
124
  ],
@@ -146,7 +161,8 @@ Array of tabs and links to show in the sidebar.
146
161
  | `type` | `'link'` | Yes | Link type |
147
162
  | `icon` | `string` | Yes | Lucide icon name |
148
163
  | `label` | `LocalizedString` | Yes | Link tooltip/label |
149
- | `href` | `string` | Yes | URL (relative to admin route) |
164
+ | `href` | `string` | Yes | URL |
165
+ | `isExternal` | `boolean` | No | If true, `href` is absolute URL, if not, `href` is relative to admin route |
150
166
 
151
167
  ### `customItems`
152
168
 
@@ -155,7 +171,7 @@ Custom items can be added to any tab:
155
171
  ```typescript
156
172
  {
157
173
  slug: 'unique-slug', // Required: unique identifier
158
- href: '/path', // Required: URL (relative to admin route)
174
+ href: '/path', // Required: URL
159
175
  label: { en: 'Label' }, // Required: display label
160
176
  group: { en: 'Group Name' }, // Optional: merge into existing group or create new
161
177
  isExternal: true, // Optional: if true, href is absolute URL
@@ -72,6 +72,7 @@ export const SidebarContent = ({ afterNavLinks, beforeNavLinks, groups, navPrefe
72
72
  slug: item.slug,
73
73
  type: 'custom',
74
74
  href: item.href,
75
+ isExternal: item.isExternal,
75
76
  label: item.label
76
77
  });
77
78
  } else {
@@ -82,6 +83,7 @@ export const SidebarContent = ({ afterNavLinks, beforeNavLinks, groups, navPrefe
82
83
  slug: item.slug,
83
84
  type: 'custom',
84
85
  href: item.href,
86
+ isExternal: item.isExternal,
85
87
  label: item.label
86
88
  }
87
89
  ],
@@ -99,6 +101,7 @@ export const SidebarContent = ({ afterNavLinks, beforeNavLinks, groups, navPrefe
99
101
  slug: item.slug,
100
102
  type: 'custom',
101
103
  href: item.href,
104
+ isExternal: item.isExternal,
102
105
  label: item.label
103
106
  })),
104
107
  label: ''
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/components/EnhancedSidebar/SidebarContent.tsx"],"sourcesContent":["'use client'\nimport type { NavPreferences } from 'payload'\n\nimport { useTranslation } from '@payloadcms/ui'\nimport React, { useEffect, useMemo, useState } from 'react'\n\nimport type {\n EnhancedSidebarConfig,\n ExtendedGroup,\n SidebarTabContent as SidebarTabContentType,\n SidebarTabItem,\n} from '../../types'\n\nimport { extractLocalizedValue } from '../../utils'\nimport { EnhancedSidebarClient } from './index.client'\nimport { SidebarWrapper } from './SidebarWrapper'\nimport { TabsBar } from './TabsBar'\n\nconst baseClass = 'enhanced-sidebar'\n\nexport type SidebarContentProps = {\n afterNavLinks?: React.ReactNode\n beforeNavLinks?: React.ReactNode\n groups: ExtendedGroup[]\n navPreferences: NavPreferences | null\n sidebarConfig: EnhancedSidebarConfig\n}\n\nconst STORAGE_KEY = 'payload-enhanced-sidebar-active-tab'\n\nexport const SidebarContent: React.FC<SidebarContentProps> = ({\n afterNavLinks,\n beforeNavLinks,\n groups,\n navPreferences,\n sidebarConfig,\n}) => {\n const { i18n } = useTranslation()\n const currentLang = i18n.language\n\n const tabs = sidebarConfig.tabs?.filter((t): t is SidebarTabContentType => t.type === 'tab') ?? []\n const defaultTabId = tabs[0]?.id ?? 'default'\n\n // Always start with default to match server render\n const [activeTabId, setActiveTabId] = useState(defaultTabId)\n\n // Read from localStorage only after hydration\n useEffect(() => {\n const stored = localStorage.getItem(STORAGE_KEY)\n if (stored && tabs.some((t) => t.id === stored)) {\n setActiveTabId(stored)\n }\n }, []) // eslint-disable-line react-hooks/exhaustive-deps\n\n // Persist to localStorage on change\n useEffect(() => {\n localStorage.setItem(STORAGE_KEY, activeTabId)\n }, [activeTabId])\n\n const activeTab = tabs.find((tab) => tab.id === activeTabId)\n\n // Build groups for the active tab\n const filteredGroups = useMemo(() => {\n if (!activeTab) {\n return groups\n }\n\n const { collections: tabCollections, customItems, globals: tabGlobals } = activeTab\n\n // If no specific collections/globals defined, show all\n const showAll = !tabCollections && !tabGlobals\n const allowedSlugs = new Set([...(tabCollections ?? []), ...(tabGlobals ?? [])])\n\n let result: ExtendedGroup[] = []\n\n if (showAll) {\n result = groups.map((g) => ({ ...g, entities: [...g.entities] }))\n } else if (allowedSlugs.size > 0) {\n result = groups\n .map((group) => ({\n ...group,\n entities: group.entities.filter((entity) => allowedSlugs.has(entity.slug)),\n }))\n .filter((group) => group.entities.length > 0)\n }\n\n // Merge custom items into groups\n if (customItems && customItems.length > 0) {\n const ungroupedItems: SidebarTabItem[] = []\n\n for (const item of customItems) {\n if (item.group) {\n // Get localized group name for comparison\n const itemGroupLabel = extractLocalizedValue(item.group, currentLang)\n\n // Find existing group by comparing localized labels\n const existingGroup = result.find((g) => {\n const groupLabel = extractLocalizedValue(g.label, currentLang)\n return groupLabel === itemGroupLabel\n })\n\n if (existingGroup) {\n existingGroup.entities.push({\n slug: item.slug,\n type: 'custom',\n href: item.href,\n label: item.label,\n })\n } else {\n // Create new group\n result.push({\n entities: [\n {\n slug: item.slug,\n type: 'custom',\n href: item.href,\n label: item.label,\n },\n ],\n label: item.group,\n })\n }\n } else {\n ungroupedItems.push(item)\n }\n }\n\n // Add ungrouped items at the end\n if (ungroupedItems.length > 0) {\n result.push({\n entities: ungroupedItems.map((item) => ({\n slug: item.slug,\n type: 'custom',\n href: item.href,\n label: item.label,\n })),\n label: '',\n })\n }\n }\n\n return result\n }, [activeTab, groups, currentLang])\n\n return (\n <SidebarWrapper baseClass={baseClass}>\n <TabsBar\n activeTabId={activeTabId}\n onTabChange={setActiveTabId}\n sidebarConfig={sidebarConfig}\n />\n <nav className={`${baseClass}__content`}>\n <div className={`${baseClass}__content-scroll`}>\n {beforeNavLinks}\n <EnhancedSidebarClient groups={filteredGroups} navPreferences={navPreferences} />\n {afterNavLinks}\n </div>\n </nav>\n </SidebarWrapper>\n )\n}\n"],"names":["useTranslation","React","useEffect","useMemo","useState","extractLocalizedValue","EnhancedSidebarClient","SidebarWrapper","TabsBar","baseClass","STORAGE_KEY","SidebarContent","afterNavLinks","beforeNavLinks","groups","navPreferences","sidebarConfig","i18n","currentLang","language","tabs","filter","t","type","defaultTabId","id","activeTabId","setActiveTabId","stored","localStorage","getItem","some","setItem","activeTab","find","tab","filteredGroups","collections","tabCollections","customItems","globals","tabGlobals","showAll","allowedSlugs","Set","result","map","g","entities","size","group","entity","has","slug","length","ungroupedItems","item","itemGroupLabel","existingGroup","groupLabel","label","push","href","onTabChange","nav","className","div"],"mappings":"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"}
1
+ {"version":3,"sources":["../../../src/components/EnhancedSidebar/SidebarContent.tsx"],"sourcesContent":["'use client'\nimport type { NavPreferences } from 'payload'\n\nimport { useTranslation } from '@payloadcms/ui'\nimport React, { useEffect, useMemo, useState } from 'react'\n\nimport type {\n EnhancedSidebarConfig,\n ExtendedEntity,\n ExtendedGroup,\n SidebarTabContent as SidebarTabContentType,\n SidebarTabItem,\n} from '../../types'\n\nimport { extractLocalizedValue } from '../../utils'\nimport { EnhancedSidebarClient } from './index.client'\nimport { SidebarWrapper } from './SidebarWrapper'\nimport { TabsBar } from './TabsBar'\n\nconst baseClass = 'enhanced-sidebar'\n\nexport type SidebarContentProps = {\n afterNavLinks?: React.ReactNode\n beforeNavLinks?: React.ReactNode\n groups: ExtendedGroup[]\n navPreferences: NavPreferences | null\n sidebarConfig: EnhancedSidebarConfig\n}\n\nconst STORAGE_KEY = 'payload-enhanced-sidebar-active-tab'\n\nexport const SidebarContent: React.FC<SidebarContentProps> = ({\n afterNavLinks,\n beforeNavLinks,\n groups,\n navPreferences,\n sidebarConfig,\n}) => {\n const { i18n } = useTranslation()\n const currentLang = i18n.language\n\n const tabs = sidebarConfig.tabs?.filter((t): t is SidebarTabContentType => t.type === 'tab') ?? []\n const defaultTabId = tabs[0]?.id ?? 'default'\n\n // Always start with default to match server render\n const [activeTabId, setActiveTabId] = useState(defaultTabId)\n\n // Read from localStorage only after hydration\n useEffect(() => {\n const stored = localStorage.getItem(STORAGE_KEY)\n if (stored && tabs.some((t) => t.id === stored)) {\n setActiveTabId(stored)\n }\n }, []) // eslint-disable-line react-hooks/exhaustive-deps\n\n // Persist to localStorage on change\n useEffect(() => {\n localStorage.setItem(STORAGE_KEY, activeTabId)\n }, [activeTabId])\n\n const activeTab = tabs.find((tab) => tab.id === activeTabId)\n\n // Build groups for the active tab\n const filteredGroups = useMemo(() => {\n if (!activeTab) {\n return groups\n }\n\n const { collections: tabCollections, customItems, globals: tabGlobals } = activeTab\n\n // If no specific collections/globals defined, show all\n const showAll = !tabCollections && !tabGlobals\n const allowedSlugs = new Set([...(tabCollections ?? []), ...(tabGlobals ?? [])])\n\n let result: ExtendedGroup[] = []\n\n if (showAll) {\n result = groups.map((g) => ({ ...g, entities: [...g.entities] }))\n } else if (allowedSlugs.size > 0) {\n result = groups\n .map((group) => ({\n ...group,\n entities: group.entities.filter((entity) => allowedSlugs.has(entity.slug)),\n }))\n .filter((group) => group.entities.length > 0)\n }\n\n // Merge custom items into groups\n if (customItems && customItems.length > 0) {\n const ungroupedItems: SidebarTabItem[] = []\n\n for (const item of customItems) {\n if (item.group) {\n // Get localized group name for comparison\n const itemGroupLabel = extractLocalizedValue(item.group, currentLang)\n\n // Find existing group by comparing localized labels\n const existingGroup = result.find((g) => {\n const groupLabel = extractLocalizedValue(g.label, currentLang)\n return groupLabel === itemGroupLabel\n })\n\n if (existingGroup) {\n existingGroup.entities.push({\n slug: item.slug,\n type: 'custom',\n href: item.href,\n isExternal: item.isExternal,\n label: item.label,\n } as ExtendedEntity)\n } else {\n // Create new group\n result.push({\n entities: [\n {\n slug: item.slug,\n type: 'custom',\n href: item.href,\n isExternal: item.isExternal,\n label: item.label,\n } as ExtendedEntity,\n ],\n label: item.group,\n })\n }\n } else {\n ungroupedItems.push(item)\n }\n }\n\n // Add ungrouped items at the end\n if (ungroupedItems.length > 0) {\n result.push({\n entities: ungroupedItems.map((item) => ({\n slug: item.slug,\n type: 'custom',\n href: item.href,\n isExternal: item.isExternal,\n label: item.label,\n })) as ExtendedEntity[],\n label: '',\n })\n }\n }\n\n return result\n }, [activeTab, groups, currentLang])\n\n return (\n <SidebarWrapper baseClass={baseClass}>\n <TabsBar\n activeTabId={activeTabId}\n onTabChange={setActiveTabId}\n sidebarConfig={sidebarConfig}\n />\n <nav className={`${baseClass}__content`}>\n <div className={`${baseClass}__content-scroll`}>\n {beforeNavLinks}\n <EnhancedSidebarClient groups={filteredGroups} navPreferences={navPreferences} />\n {afterNavLinks}\n </div>\n </nav>\n </SidebarWrapper>\n )\n}\n"],"names":["useTranslation","React","useEffect","useMemo","useState","extractLocalizedValue","EnhancedSidebarClient","SidebarWrapper","TabsBar","baseClass","STORAGE_KEY","SidebarContent","afterNavLinks","beforeNavLinks","groups","navPreferences","sidebarConfig","i18n","currentLang","language","tabs","filter","t","type","defaultTabId","id","activeTabId","setActiveTabId","stored","localStorage","getItem","some","setItem","activeTab","find","tab","filteredGroups","collections","tabCollections","customItems","globals","tabGlobals","showAll","allowedSlugs","Set","result","map","g","entities","size","group","entity","has","slug","length","ungroupedItems","item","itemGroupLabel","existingGroup","groupLabel","label","push","href","isExternal","onTabChange","nav","className","div"],"mappings":"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"}
@@ -29,7 +29,7 @@ export const TabsBar = ({ activeTabId, onTabChange, sidebarConfig })=>{
29
29
  };
30
30
  const renderLink = (link)=>{
31
31
  const label = getTranslation(link.label, i18n);
32
- const href = formatAdminURL({
32
+ const href = link.isExternal ? link.href : formatAdminURL({
33
33
  adminRoute,
34
34
  path: link.href
35
35
  });
@@ -38,6 +38,7 @@ export const TabsBar = ({ activeTabId, onTabChange, sidebarConfig })=>{
38
38
  return /*#__PURE__*/ _jsx(Link, {
39
39
  className: `${tabsBaseClass}__link ${isActive ? `${tabsBaseClass}__link--active` : ''}`,
40
40
  href: href,
41
+ target: link.isExternal ? '_blank' : undefined,
41
42
  title: label,
42
43
  children: /*#__PURE__*/ _jsx(Icon, {
43
44
  name: link.icon,
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../../src/components/EnhancedSidebar/TabsBar/index.tsx"],"sourcesContent":["'use client'\n\nimport { getTranslation } from '@payloadcms/translations'\nimport { Link, useConfig, useTranslation } from '@payloadcms/ui'\nimport { usePathname } from 'next/navigation'\nimport { formatAdminURL } from 'payload/shared'\nimport React from 'react'\n\nimport type { EnhancedSidebarConfig, SidebarTabContent, SidebarTabLink } from '../../../types'\n\nimport { Icon } from '../Icon'\nimport './index.scss'\n\nconst tabsBaseClass = 'tabs-bar'\n\nexport type TabsBarProps = {\n activeTabId: string\n onTabChange: (tabId: string) => void\n sidebarConfig: EnhancedSidebarConfig\n}\n\nexport const TabsBar: React.FC<TabsBarProps> = ({ activeTabId, onTabChange, sidebarConfig }) => {\n const { i18n } = useTranslation()\n const pathname = usePathname()\n\n const {\n config: {\n admin: {\n routes: { logout: logoutRoute },\n },\n routes: { admin: adminRoute },\n },\n } = useConfig()\n\n const showLogout = sidebarConfig.showLogout !== false\n\n const renderTab = (tab: SidebarTabContent) => {\n const label = getTranslation(tab.label, i18n)\n const isActive = activeTabId === tab.id\n\n return (\n <button\n className={`${tabsBaseClass}__tab ${isActive ? `${tabsBaseClass}__tab--active` : ''}`}\n key={tab.id}\n onClick={() => onTabChange(tab.id)}\n title={label}\n type=\"button\"\n >\n <Icon name={tab.icon} size={20} />\n </button>\n )\n }\n\n const renderLink = (link: SidebarTabLink) => {\n const label = getTranslation(link.label, i18n)\n const href = formatAdminURL({ adminRoute, path: link.href as `/${string}` })\n\n // Check if this link is active\n const isActive = pathname === href || (link.href === '/' && pathname === adminRoute)\n\n return (\n <Link\n className={`${tabsBaseClass}__link ${isActive ? `${tabsBaseClass}__link--active` : ''}`}\n href={href}\n key={link.id}\n title={label}\n >\n <Icon name={link.icon} size={20} />\n </Link>\n )\n }\n\n const renderTabItem = (item: SidebarTabContent | SidebarTabLink) => {\n if (item.type === 'tab') {\n return renderTab(item)\n }\n return renderLink(item)\n }\n\n const tabItems = sidebarConfig.tabs ?? []\n\n return (\n <div className={tabsBaseClass}>\n <div className={`${tabsBaseClass}__tabs`}>{tabItems.map(renderTabItem)}</div>\n\n {showLogout && (\n <div className={`${tabsBaseClass}__actions`}>\n <Link\n className={`${tabsBaseClass}__action`}\n href={formatAdminURL({\n adminRoute,\n path: logoutRoute,\n })}\n title={getTranslation({ en: 'Logout', uk: 'Вийти' }, i18n)}\n type=\"button\"\n >\n <Icon name=\"LogOut\" size={20} />\n </Link>\n </div>\n )}\n </div>\n )\n}\n"],"names":["getTranslation","Link","useConfig","useTranslation","usePathname","formatAdminURL","React","Icon","tabsBaseClass","TabsBar","activeTabId","onTabChange","sidebarConfig","i18n","pathname","config","admin","routes","logout","logoutRoute","adminRoute","showLogout","renderTab","tab","label","isActive","id","button","className","onClick","title","type","name","icon","size","renderLink","link","href","path","renderTabItem","item","tabItems","tabs","div","map","en","uk"],"mappings":"AAAA;;AAEA,SAASA,cAAc,QAAQ,2BAA0B;AACzD,SAASC,IAAI,EAAEC,SAAS,EAAEC,cAAc,QAAQ,iBAAgB;AAChE,SAASC,WAAW,QAAQ,kBAAiB;AAC7C,SAASC,cAAc,QAAQ,iBAAgB;AAC/C,OAAOC,WAAW,QAAO;AAIzB,SAASC,IAAI,QAAQ,UAAS;AAC9B,OAAO,eAAc;AAErB,MAAMC,gBAAgB;AAQtB,OAAO,MAAMC,UAAkC,CAAC,EAAEC,WAAW,EAAEC,WAAW,EAAEC,aAAa,EAAE;IACzF,MAAM,EAAEC,IAAI,EAAE,GAAGV;IACjB,MAAMW,WAAWV;IAEjB,MAAM,EACJW,QAAQ,EACNC,OAAO,EACLC,QAAQ,EAAEC,QAAQC,WAAW,EAAE,EAChC,EACDF,QAAQ,EAAED,OAAOI,UAAU,EAAE,EAC9B,EACF,GAAGlB;IAEJ,MAAMmB,aAAaT,cAAcS,UAAU,KAAK;IAEhD,MAAMC,YAAY,CAACC;QACjB,MAAMC,QAAQxB,eAAeuB,IAAIC,KAAK,EAAEX;QACxC,MAAMY,WAAWf,gBAAgBa,IAAIG,EAAE;QAEvC,qBACE,KAACC;YACCC,WAAW,GAAGpB,cAAc,MAAM,EAAEiB,WAAW,GAAGjB,cAAc,aAAa,CAAC,GAAG,IAAI;YAErFqB,SAAS,IAAMlB,YAAYY,IAAIG,EAAE;YACjCI,OAAON;YACPO,MAAK;sBAEL,cAAA,KAACxB;gBAAKyB,MAAMT,IAAIU,IAAI;gBAAEC,MAAM;;WALvBX,IAAIG,EAAE;IAQjB;IAEA,MAAMS,aAAa,CAACC;QAClB,MAAMZ,QAAQxB,eAAeoC,KAAKZ,KAAK,EAAEX;QACzC,MAAMwB,OAAOhC,eAAe;YAAEe;YAAYkB,MAAMF,KAAKC,IAAI;QAAiB;QAE1E,+BAA+B;QAC/B,MAAMZ,WAAWX,aAAauB,QAASD,KAAKC,IAAI,KAAK,OAAOvB,aAAaM;QAEzE,qBACE,KAACnB;YACC2B,WAAW,GAAGpB,cAAc,OAAO,EAAEiB,WAAW,GAAGjB,cAAc,cAAc,CAAC,GAAG,IAAI;YACvF6B,MAAMA;YAENP,OAAON;sBAEP,cAAA,KAACjB;gBAAKyB,MAAMI,KAAKH,IAAI;gBAAEC,MAAM;;WAHxBE,KAAKV,EAAE;IAMlB;IAEA,MAAMa,gBAAgB,CAACC;QACrB,IAAIA,KAAKT,IAAI,KAAK,OAAO;YACvB,OAAOT,UAAUkB;QACnB;QACA,OAAOL,WAAWK;IACpB;IAEA,MAAMC,WAAW7B,cAAc8B,IAAI,IAAI,EAAE;IAEzC,qBACE,MAACC;QAAIf,WAAWpB;;0BACd,KAACmC;gBAAIf,WAAW,GAAGpB,cAAc,MAAM,CAAC;0BAAGiC,SAASG,GAAG,CAACL;;YAEvDlB,4BACC,KAACsB;gBAAIf,WAAW,GAAGpB,cAAc,SAAS,CAAC;0BACzC,cAAA,KAACP;oBACC2B,WAAW,GAAGpB,cAAc,QAAQ,CAAC;oBACrC6B,MAAMhC,eAAe;wBACnBe;wBACAkB,MAAMnB;oBACR;oBACAW,OAAO9B,eAAe;wBAAE6C,IAAI;wBAAUC,IAAI;oBAAQ,GAAGjC;oBACrDkB,MAAK;8BAEL,cAAA,KAACxB;wBAAKyB,MAAK;wBAASE,MAAM;;;;;;AAMtC,EAAC"}
1
+ {"version":3,"sources":["../../../../src/components/EnhancedSidebar/TabsBar/index.tsx"],"sourcesContent":["'use client'\n\nimport { getTranslation } from '@payloadcms/translations'\nimport { Link, useConfig, useTranslation } from '@payloadcms/ui'\nimport { usePathname } from 'next/navigation'\nimport { formatAdminURL } from 'payload/shared'\nimport React from 'react'\n\nimport type { EnhancedSidebarConfig, SidebarTabContent, SidebarTabLink } from '../../../types'\n\nimport { Icon } from '../Icon'\nimport './index.scss'\n\nconst tabsBaseClass = 'tabs-bar'\n\nexport type TabsBarProps = {\n activeTabId: string\n onTabChange: (tabId: string) => void\n sidebarConfig: EnhancedSidebarConfig\n}\n\nexport const TabsBar: React.FC<TabsBarProps> = ({ activeTabId, onTabChange, sidebarConfig }) => {\n const { i18n } = useTranslation()\n const pathname = usePathname()\n\n const {\n config: {\n admin: {\n routes: { logout: logoutRoute },\n },\n routes: { admin: adminRoute },\n },\n } = useConfig()\n\n const showLogout = sidebarConfig.showLogout !== false\n\n const renderTab = (tab: SidebarTabContent) => {\n const label = getTranslation(tab.label, i18n)\n const isActive = activeTabId === tab.id\n\n return (\n <button\n className={`${tabsBaseClass}__tab ${isActive ? `${tabsBaseClass}__tab--active` : ''}`}\n key={tab.id}\n onClick={() => onTabChange(tab.id)}\n title={label}\n type=\"button\"\n >\n <Icon name={tab.icon} size={20} />\n </button>\n )\n }\n\n const renderLink = (link: SidebarTabLink) => {\n const label = getTranslation(link.label, i18n)\n const href = link.isExternal ? link.href : formatAdminURL({ adminRoute, path: link.href })\n\n // Check if this link is active\n const isActive = pathname === href || (link.href === '/' && pathname === adminRoute)\n\n return (\n <Link\n className={`${tabsBaseClass}__link ${isActive ? `${tabsBaseClass}__link--active` : ''}`}\n href={href}\n key={link.id}\n target={link.isExternal ? '_blank' : undefined}\n title={label}\n >\n <Icon name={link.icon} size={20} />\n </Link>\n )\n }\n\n const renderTabItem = (item: SidebarTabContent | SidebarTabLink) => {\n if (item.type === 'tab') {\n return renderTab(item)\n }\n return renderLink(item)\n }\n\n const tabItems = sidebarConfig.tabs ?? []\n\n return (\n <div className={tabsBaseClass}>\n <div className={`${tabsBaseClass}__tabs`}>{tabItems.map(renderTabItem)}</div>\n\n {showLogout && (\n <div className={`${tabsBaseClass}__actions`}>\n <Link\n className={`${tabsBaseClass}__action`}\n href={formatAdminURL({\n adminRoute,\n path: logoutRoute,\n })}\n title={getTranslation({ en: 'Logout', uk: 'Вийти' }, i18n)}\n type=\"button\"\n >\n <Icon name=\"LogOut\" size={20} />\n </Link>\n </div>\n )}\n </div>\n )\n}\n"],"names":["getTranslation","Link","useConfig","useTranslation","usePathname","formatAdminURL","React","Icon","tabsBaseClass","TabsBar","activeTabId","onTabChange","sidebarConfig","i18n","pathname","config","admin","routes","logout","logoutRoute","adminRoute","showLogout","renderTab","tab","label","isActive","id","button","className","onClick","title","type","name","icon","size","renderLink","link","href","isExternal","path","target","undefined","renderTabItem","item","tabItems","tabs","div","map","en","uk"],"mappings":"AAAA;;AAEA,SAASA,cAAc,QAAQ,2BAA0B;AACzD,SAASC,IAAI,EAAEC,SAAS,EAAEC,cAAc,QAAQ,iBAAgB;AAChE,SAASC,WAAW,QAAQ,kBAAiB;AAC7C,SAASC,cAAc,QAAQ,iBAAgB;AAC/C,OAAOC,WAAW,QAAO;AAIzB,SAASC,IAAI,QAAQ,UAAS;AAC9B,OAAO,eAAc;AAErB,MAAMC,gBAAgB;AAQtB,OAAO,MAAMC,UAAkC,CAAC,EAAEC,WAAW,EAAEC,WAAW,EAAEC,aAAa,EAAE;IACzF,MAAM,EAAEC,IAAI,EAAE,GAAGV;IACjB,MAAMW,WAAWV;IAEjB,MAAM,EACJW,QAAQ,EACNC,OAAO,EACLC,QAAQ,EAAEC,QAAQC,WAAW,EAAE,EAChC,EACDF,QAAQ,EAAED,OAAOI,UAAU,EAAE,EAC9B,EACF,GAAGlB;IAEJ,MAAMmB,aAAaT,cAAcS,UAAU,KAAK;IAEhD,MAAMC,YAAY,CAACC;QACjB,MAAMC,QAAQxB,eAAeuB,IAAIC,KAAK,EAAEX;QACxC,MAAMY,WAAWf,gBAAgBa,IAAIG,EAAE;QAEvC,qBACE,KAACC;YACCC,WAAW,GAAGpB,cAAc,MAAM,EAAEiB,WAAW,GAAGjB,cAAc,aAAa,CAAC,GAAG,IAAI;YAErFqB,SAAS,IAAMlB,YAAYY,IAAIG,EAAE;YACjCI,OAAON;YACPO,MAAK;sBAEL,cAAA,KAACxB;gBAAKyB,MAAMT,IAAIU,IAAI;gBAAEC,MAAM;;WALvBX,IAAIG,EAAE;IAQjB;IAEA,MAAMS,aAAa,CAACC;QAClB,MAAMZ,QAAQxB,eAAeoC,KAAKZ,KAAK,EAAEX;QACzC,MAAMwB,OAAOD,KAAKE,UAAU,GAAGF,KAAKC,IAAI,GAAGhC,eAAe;YAAEe;YAAYmB,MAAMH,KAAKC,IAAI;QAAC;QAExF,+BAA+B;QAC/B,MAAMZ,WAAWX,aAAauB,QAASD,KAAKC,IAAI,KAAK,OAAOvB,aAAaM;QAEzE,qBACE,KAACnB;YACC2B,WAAW,GAAGpB,cAAc,OAAO,EAAEiB,WAAW,GAAGjB,cAAc,cAAc,CAAC,GAAG,IAAI;YACvF6B,MAAMA;YAENG,QAAQJ,KAAKE,UAAU,GAAG,WAAWG;YACrCX,OAAON;sBAEP,cAAA,KAACjB;gBAAKyB,MAAMI,KAAKH,IAAI;gBAAEC,MAAM;;WAJxBE,KAAKV,EAAE;IAOlB;IAEA,MAAMgB,gBAAgB,CAACC;QACrB,IAAIA,KAAKZ,IAAI,KAAK,OAAO;YACvB,OAAOT,UAAUqB;QACnB;QACA,OAAOR,WAAWQ;IACpB;IAEA,MAAMC,WAAWhC,cAAciC,IAAI,IAAI,EAAE;IAEzC,qBACE,MAACC;QAAIlB,WAAWpB;;0BACd,KAACsC;gBAAIlB,WAAW,GAAGpB,cAAc,MAAM,CAAC;0BAAGoC,SAASG,GAAG,CAACL;;YAEvDrB,4BACC,KAACyB;gBAAIlB,WAAW,GAAGpB,cAAc,SAAS,CAAC;0BACzC,cAAA,KAACP;oBACC2B,WAAW,GAAGpB,cAAc,QAAQ,CAAC;oBACrC6B,MAAMhC,eAAe;wBACnBe;wBACAmB,MAAMpB;oBACR;oBACAW,OAAO9B,eAAe;wBAAEgD,IAAI;wBAAUC,IAAI;oBAAQ,GAAGpC;oBACrDkB,MAAK;8BAEL,cAAA,KAACxB;wBAAKyB,MAAK;wBAASE,MAAM;;;;;;AAMtC,EAAC"}
@@ -2,6 +2,7 @@
2
2
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
3
3
  import { getTranslation } from '@payloadcms/translations';
4
4
  import { Link, NavGroup, useConfig, useTranslation } from '@payloadcms/ui';
5
+ import { EntityType } from '@payloadcms/ui/shared';
5
6
  import { usePathname } from 'next/navigation.js';
6
7
  import { formatAdminURL } from 'payload/shared';
7
8
  import React, { Fragment } from 'react';
@@ -20,14 +21,16 @@ export const EnhancedSidebarClient = ({ groups, navPreferences })=>{
20
21
  const entityType = entity.type;
21
22
  let href;
22
23
  let id;
23
- // Check for collection (Will break if EntityType enum changes)
24
- if (entityType === 'collection') {
24
+ // Check for collection
25
+ //@ts-expect-error Idk why typescript is complaining here
26
+ if (entityType === EntityType.collection) {
25
27
  href = formatAdminURL({
26
28
  adminRoute,
27
29
  path: `/collections/${slug}`
28
30
  });
29
31
  id = `nav-${slug}`;
30
- } else if (entityType === 'global') {
32
+ //@ts-expect-error Idk why typescript is complaining here
33
+ } else if (entityType === EntityType.global) {
31
34
  href = formatAdminURL({
32
35
  adminRoute,
33
36
  path: `/globals/${slug}`
@@ -35,12 +38,15 @@ export const EnhancedSidebarClient = ({ groups, navPreferences })=>{
35
38
  id = `nav-global-${slug}`;
36
39
  } else if (entityType === 'custom' && entity.href) {
37
40
  // Custom item with href
38
- const customHref = entity.href;
39
- href = formatAdminURL({
40
- adminRoute,
41
- path: customHref
42
- });
43
41
  id = `nav-custom-${slug}`;
42
+ if (entity.isExternal) {
43
+ href = entity.href;
44
+ } else {
45
+ href = formatAdminURL({
46
+ adminRoute,
47
+ path: entity.href
48
+ });
49
+ }
44
50
  } else {
45
51
  return null;
46
52
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/components/EnhancedSidebar/index.client.tsx"],"sourcesContent":["'use client'\nimport type { NavPreferences } from 'payload'\nimport type { ExtendedGroup } from 'src/types'\n\nimport { getTranslation } from '@payloadcms/translations'\nimport { Link, NavGroup, useConfig, useTranslation } from '@payloadcms/ui'\nimport { usePathname } from 'next/navigation.js'\nimport { formatAdminURL } from 'payload/shared'\nimport React, { Fragment } from 'react'\n\nconst baseClass = 'enhanced-sidebar'\n\nexport const EnhancedSidebarClient: React.FC<{\n groups: ExtendedGroup[]\n navPreferences: NavPreferences | null\n}> = ({ groups, navPreferences }) => {\n const pathname = usePathname()\n\n const {\n config: {\n routes: { admin: adminRoute },\n },\n } = useConfig()\n\n const { i18n } = useTranslation()\n\n return (\n <Fragment>\n {groups.map(({ entities, label }, key) => {\n // Handle empty label (ungrouped items)\n const groupLabel = label || ''\n const isUngrouped = !label || (typeof label === 'string' && label === '')\n\n const content = entities.map((entity, i) => {\n const { slug, label: entityLabel } = entity\n const entityType = entity.type\n let href: string\n let id: string\n\n // Check for collection (Will break if EntityType enum changes)\n if (entityType === 'collection') {\n href = formatAdminURL({ adminRoute, path: `/collections/${slug}` })\n id = `nav-${slug}`\n } else if (entityType === 'global') {\n href = formatAdminURL({ adminRoute, path: `/globals/${slug}` })\n id = `nav-global-${slug}`\n } else if (entityType === 'custom' && entity.href) {\n // Custom item with href\n const customHref = entity.href\n href = formatAdminURL({ adminRoute, path: customHref as `/${string}` })\n id = `nav-custom-${slug}`\n } else {\n return null\n }\n\n const isActive =\n pathname.startsWith(href) && ['/', undefined].includes(pathname[href.length])\n\n const Label = (\n <>\n {isActive && <div className={`${baseClass}__link-indicator`} />}\n <span className={`${baseClass}__link-label`}>\n {getTranslation(entityLabel, i18n)}\n </span>\n </>\n )\n\n if (pathname === href) {\n return (\n <div className={`${baseClass}__link`} id={id} key={i}>\n {Label}\n </div>\n )\n }\n\n return (\n <Link className={`${baseClass}__link`} href={href} id={id} key={i} prefetch={false}>\n {Label}\n </Link>\n )\n })\n\n // For ungrouped items, render without NavGroup wrapper\n if (isUngrouped) {\n return <Fragment key={key}>{content}</Fragment>\n }\n\n // Get translated label for NavGroup\n const translatedLabel = getTranslation(groupLabel, i18n)\n\n return (\n <NavGroup\n isOpen={navPreferences?.groups?.[translatedLabel]?.open}\n key={key}\n label={translatedLabel}\n >\n {content}\n </NavGroup>\n )\n })}\n </Fragment>\n )\n}\n"],"names":["getTranslation","Link","NavGroup","useConfig","useTranslation","usePathname","formatAdminURL","React","Fragment","baseClass","EnhancedSidebarClient","groups","navPreferences","pathname","config","routes","admin","adminRoute","i18n","map","entities","label","key","groupLabel","isUngrouped","content","entity","i","slug","entityLabel","entityType","type","href","id","path","customHref","isActive","startsWith","undefined","includes","length","Label","div","className","span","prefetch","translatedLabel","isOpen","open"],"mappings":"AAAA;;AAIA,SAASA,cAAc,QAAQ,2BAA0B;AACzD,SAASC,IAAI,EAAEC,QAAQ,EAAEC,SAAS,EAAEC,cAAc,QAAQ,iBAAgB;AAC1E,SAASC,WAAW,QAAQ,qBAAoB;AAChD,SAASC,cAAc,QAAQ,iBAAgB;AAC/C,OAAOC,SAASC,QAAQ,QAAQ,QAAO;AAEvC,MAAMC,YAAY;AAElB,OAAO,MAAMC,wBAGR,CAAC,EAAEC,MAAM,EAAEC,cAAc,EAAE;IAC9B,MAAMC,WAAWR;IAEjB,MAAM,EACJS,QAAQ,EACNC,QAAQ,EAAEC,OAAOC,UAAU,EAAE,EAC9B,EACF,GAAGd;IAEJ,MAAM,EAAEe,IAAI,EAAE,GAAGd;IAEjB,qBACE,KAACI;kBACEG,OAAOQ,GAAG,CAAC,CAAC,EAAEC,QAAQ,EAAEC,KAAK,EAAE,EAAEC;YAChC,uCAAuC;YACvC,MAAMC,aAAaF,SAAS;YAC5B,MAAMG,cAAc,CAACH,SAAU,OAAOA,UAAU,YAAYA,UAAU;YAEtE,MAAMI,UAAUL,SAASD,GAAG,CAAC,CAACO,QAAQC;gBACpC,MAAM,EAAEC,IAAI,EAAEP,OAAOQ,WAAW,EAAE,GAAGH;gBACrC,MAAMI,aAAaJ,OAAOK,IAAI;gBAC9B,IAAIC;gBACJ,IAAIC;gBAEJ,+DAA+D;gBAC/D,IAAIH,eAAe,cAAc;oBAC/BE,OAAO1B,eAAe;wBAAEW;wBAAYiB,MAAM,CAAC,aAAa,EAAEN,MAAM;oBAAC;oBACjEK,KAAK,CAAC,IAAI,EAAEL,MAAM;gBACpB,OAAO,IAAIE,eAAe,UAAU;oBAClCE,OAAO1B,eAAe;wBAAEW;wBAAYiB,MAAM,CAAC,SAAS,EAAEN,MAAM;oBAAC;oBAC7DK,KAAK,CAAC,WAAW,EAAEL,MAAM;gBAC3B,OAAO,IAAIE,eAAe,YAAYJ,OAAOM,IAAI,EAAE;oBACjD,wBAAwB;oBACxB,MAAMG,aAAaT,OAAOM,IAAI;oBAC9BA,OAAO1B,eAAe;wBAAEW;wBAAYiB,MAAMC;oBAA2B;oBACrEF,KAAK,CAAC,WAAW,EAAEL,MAAM;gBAC3B,OAAO;oBACL,OAAO;gBACT;gBAEA,MAAMQ,WACJvB,SAASwB,UAAU,CAACL,SAAS;oBAAC;oBAAKM;iBAAU,CAACC,QAAQ,CAAC1B,QAAQ,CAACmB,KAAKQ,MAAM,CAAC;gBAE9E,MAAMC,sBACJ;;wBACGL,0BAAY,KAACM;4BAAIC,WAAW,GAAGlC,UAAU,gBAAgB,CAAC;;sCAC3D,KAACmC;4BAAKD,WAAW,GAAGlC,UAAU,YAAY,CAAC;sCACxCT,eAAe6B,aAAaX;;;;gBAKnC,IAAIL,aAAamB,MAAM;oBACrB,qBACE,KAACU;wBAAIC,WAAW,GAAGlC,UAAU,MAAM,CAAC;wBAAEwB,IAAIA;kCACvCQ;uBADgDd;gBAIvD;gBAEA,qBACE,KAAC1B;oBAAK0C,WAAW,GAAGlC,UAAU,MAAM,CAAC;oBAAEuB,MAAMA;oBAAMC,IAAIA;oBAAYY,UAAU;8BAC1EJ;mBAD6Dd;YAIpE;YAEA,uDAAuD;YACvD,IAAIH,aAAa;gBACf,qBAAO,KAAChB;8BAAoBiB;mBAANH;YACxB;YAEA,oCAAoC;YACpC,MAAMwB,kBAAkB9C,eAAeuB,YAAYL;YAEnD,qBACE,KAAChB;gBACC6C,QAAQnC,gBAAgBD,QAAQ,CAACmC,gBAAgB,EAAEE;gBAEnD3B,OAAOyB;0BAENrB;eAHIH;QAMX;;AAGN,EAAC"}
1
+ {"version":3,"sources":["../../../src/components/EnhancedSidebar/index.client.tsx"],"sourcesContent":["'use client'\nimport type { NavPreferences } from 'payload'\nimport type { ExtendedGroup } from 'src/types'\n\nimport { getTranslation } from '@payloadcms/translations'\nimport { Link, NavGroup, useConfig, useTranslation } from '@payloadcms/ui'\nimport { EntityType } from '@payloadcms/ui/shared'\nimport { usePathname } from 'next/navigation.js'\nimport { formatAdminURL } from 'payload/shared'\nimport React, { Fragment } from 'react'\n\nconst baseClass = 'enhanced-sidebar'\n\nexport const EnhancedSidebarClient: React.FC<{\n groups: ExtendedGroup[]\n navPreferences: NavPreferences | null\n}> = ({ groups, navPreferences }) => {\n const pathname = usePathname()\n\n const {\n config: {\n routes: { admin: adminRoute },\n },\n } = useConfig()\n\n const { i18n } = useTranslation()\n\n return (\n <Fragment>\n {groups.map(({ entities, label }, key) => {\n // Handle empty label (ungrouped items)\n const groupLabel = label || ''\n const isUngrouped = !label || (typeof label === 'string' && label === '')\n\n const content = entities.map((entity, i) => {\n const { slug, label: entityLabel } = entity\n const entityType = entity.type\n let href: string\n let id: string\n\n // Check for collection\n //@ts-expect-error Idk why typescript is complaining here\n if (entityType === EntityType.collection) {\n href = formatAdminURL({ adminRoute, path: `/collections/${slug}` })\n id = `nav-${slug}`\n //@ts-expect-error Idk why typescript is complaining here\n } else if (entityType === EntityType.global) {\n href = formatAdminURL({ adminRoute, path: `/globals/${slug}` })\n id = `nav-global-${slug}`\n } else if (entityType === 'custom' && entity.href) {\n // Custom item with href\n id = `nav-custom-${slug}`\n if (entity.isExternal) {\n href = entity.href\n } else {\n href = formatAdminURL({ adminRoute, path: entity.href })\n }\n } else {\n return null\n }\n\n const isActive =\n pathname.startsWith(href) && ['/', undefined].includes(pathname[href.length])\n\n const Label = (\n <>\n {isActive && <div className={`${baseClass}__link-indicator`} />}\n <span className={`${baseClass}__link-label`}>\n {getTranslation(entityLabel, i18n)}\n </span>\n </>\n )\n\n if (pathname === href) {\n return (\n <div className={`${baseClass}__link`} id={id} key={i}>\n {Label}\n </div>\n )\n }\n\n return (\n <Link className={`${baseClass}__link`} href={href} id={id} key={i} prefetch={false}>\n {Label}\n </Link>\n )\n })\n\n // For ungrouped items, render without NavGroup wrapper\n if (isUngrouped) {\n return <Fragment key={key}>{content}</Fragment>\n }\n\n // Get translated label for NavGroup\n const translatedLabel = getTranslation(groupLabel, i18n)\n\n return (\n <NavGroup\n isOpen={navPreferences?.groups?.[translatedLabel]?.open}\n key={key}\n label={translatedLabel}\n >\n {content}\n </NavGroup>\n )\n })}\n </Fragment>\n )\n}\n"],"names":["getTranslation","Link","NavGroup","useConfig","useTranslation","EntityType","usePathname","formatAdminURL","React","Fragment","baseClass","EnhancedSidebarClient","groups","navPreferences","pathname","config","routes","admin","adminRoute","i18n","map","entities","label","key","groupLabel","isUngrouped","content","entity","i","slug","entityLabel","entityType","type","href","id","collection","path","global","isExternal","isActive","startsWith","undefined","includes","length","Label","div","className","span","prefetch","translatedLabel","isOpen","open"],"mappings":"AAAA;;AAIA,SAASA,cAAc,QAAQ,2BAA0B;AACzD,SAASC,IAAI,EAAEC,QAAQ,EAAEC,SAAS,EAAEC,cAAc,QAAQ,iBAAgB;AAC1E,SAASC,UAAU,QAAQ,wBAAuB;AAClD,SAASC,WAAW,QAAQ,qBAAoB;AAChD,SAASC,cAAc,QAAQ,iBAAgB;AAC/C,OAAOC,SAASC,QAAQ,QAAQ,QAAO;AAEvC,MAAMC,YAAY;AAElB,OAAO,MAAMC,wBAGR,CAAC,EAAEC,MAAM,EAAEC,cAAc,EAAE;IAC9B,MAAMC,WAAWR;IAEjB,MAAM,EACJS,QAAQ,EACNC,QAAQ,EAAEC,OAAOC,UAAU,EAAE,EAC9B,EACF,GAAGf;IAEJ,MAAM,EAAEgB,IAAI,EAAE,GAAGf;IAEjB,qBACE,KAACK;kBACEG,OAAOQ,GAAG,CAAC,CAAC,EAAEC,QAAQ,EAAEC,KAAK,EAAE,EAAEC;YAChC,uCAAuC;YACvC,MAAMC,aAAaF,SAAS;YAC5B,MAAMG,cAAc,CAACH,SAAU,OAAOA,UAAU,YAAYA,UAAU;YAEtE,MAAMI,UAAUL,SAASD,GAAG,CAAC,CAACO,QAAQC;gBACpC,MAAM,EAAEC,IAAI,EAAEP,OAAOQ,WAAW,EAAE,GAAGH;gBACrC,MAAMI,aAAaJ,OAAOK,IAAI;gBAC9B,IAAIC;gBACJ,IAAIC;gBAEJ,uBAAuB;gBACvB,yDAAyD;gBACzD,IAAIH,eAAe1B,WAAW8B,UAAU,EAAE;oBACxCF,OAAO1B,eAAe;wBAAEW;wBAAYkB,MAAM,CAAC,aAAa,EAAEP,MAAM;oBAAC;oBACjEK,KAAK,CAAC,IAAI,EAAEL,MAAM;gBAClB,yDAAyD;gBAC3D,OAAO,IAAIE,eAAe1B,WAAWgC,MAAM,EAAE;oBAC3CJ,OAAO1B,eAAe;wBAAEW;wBAAYkB,MAAM,CAAC,SAAS,EAAEP,MAAM;oBAAC;oBAC7DK,KAAK,CAAC,WAAW,EAAEL,MAAM;gBAC3B,OAAO,IAAIE,eAAe,YAAYJ,OAAOM,IAAI,EAAE;oBACjD,wBAAwB;oBACxBC,KAAK,CAAC,WAAW,EAAEL,MAAM;oBACzB,IAAIF,OAAOW,UAAU,EAAE;wBACrBL,OAAON,OAAOM,IAAI;oBACpB,OAAO;wBACLA,OAAO1B,eAAe;4BAAEW;4BAAYkB,MAAMT,OAAOM,IAAI;wBAAC;oBACxD;gBACF,OAAO;oBACL,OAAO;gBACT;gBAEA,MAAMM,WACJzB,SAAS0B,UAAU,CAACP,SAAS;oBAAC;oBAAKQ;iBAAU,CAACC,QAAQ,CAAC5B,QAAQ,CAACmB,KAAKU,MAAM,CAAC;gBAE9E,MAAMC,sBACJ;;wBACGL,0BAAY,KAACM;4BAAIC,WAAW,GAAGpC,UAAU,gBAAgB,CAAC;;sCAC3D,KAACqC;4BAAKD,WAAW,GAAGpC,UAAU,YAAY,CAAC;sCACxCV,eAAe8B,aAAaX;;;;gBAKnC,IAAIL,aAAamB,MAAM;oBACrB,qBACE,KAACY;wBAAIC,WAAW,GAAGpC,UAAU,MAAM,CAAC;wBAAEwB,IAAIA;kCACvCU;uBADgDhB;gBAIvD;gBAEA,qBACE,KAAC3B;oBAAK6C,WAAW,GAAGpC,UAAU,MAAM,CAAC;oBAAEuB,MAAMA;oBAAMC,IAAIA;oBAAYc,UAAU;8BAC1EJ;mBAD6DhB;YAIpE;YAEA,uDAAuD;YACvD,IAAIH,aAAa;gBACf,qBAAO,KAAChB;8BAAoBiB;mBAANH;YACxB;YAEA,oCAAoC;YACpC,MAAM0B,kBAAkBjD,eAAewB,YAAYL;YAEnD,qBACE,KAACjB;gBACCgD,QAAQrC,gBAAgBD,QAAQ,CAACqC,gBAAgB,EAAEE;gBAEnD7B,OAAO2B;0BAENvB;eAHIH;QAMX;;AAGN,EAAC"}
package/dist/types.d.ts CHANGED
@@ -35,12 +35,7 @@ export interface SidebarTabContent {
35
35
  label: LocalizedString;
36
36
  type: 'tab';
37
37
  }
38
- /**
39
- * Sidebar link that navigates to a URL (not a tab)
40
- */
41
- export interface SidebarTabLink {
42
- /** Link href (relative to admin route) */
43
- href: string;
38
+ interface SidebarTabLinkBase {
44
39
  /** Icon name from lucide-react */
45
40
  icon: IconName;
46
41
  /** Unique identifier */
@@ -49,6 +44,20 @@ export interface SidebarTabLink {
49
44
  label: LocalizedString;
50
45
  type: 'link';
51
46
  }
47
+ interface SidebarTabLinkExternal extends SidebarTabLinkBase {
48
+ /** Link href (absolute URL) */
49
+ href: string;
50
+ isExternal: true;
51
+ }
52
+ interface SidebarTabLinkInternal extends SidebarTabLinkBase {
53
+ /** Link href (relative to admin route) */
54
+ href: '' | `/${string}`;
55
+ isExternal?: false;
56
+ }
57
+ /**
58
+ * Sidebar link that navigates to a URL (not a tab)
59
+ */
60
+ export type SidebarTabLink = SidebarTabLinkExternal | SidebarTabLinkInternal;
52
61
  /**
53
62
  * A tab or link in the sidebar tabs bar
54
63
  */
@@ -119,12 +128,20 @@ export type GenericCollectionDocument = {
119
128
  [key: string]: number | string;
120
129
  id: string;
121
130
  };
122
- export type ExtendedEntity = {
123
- href?: string;
131
+ interface BaseExtendedEntity {
124
132
  label: Record<string, string> | string;
125
133
  slug: string;
126
134
  type: 'collection' | 'custom' | 'global';
127
- };
135
+ }
136
+ interface InternalExtendedEntity extends BaseExtendedEntity {
137
+ href?: '' | `/${string}`;
138
+ isExternal?: false;
139
+ }
140
+ interface ExternalExtendedEntity extends BaseExtendedEntity {
141
+ href: string;
142
+ isExternal: true;
143
+ }
144
+ export type ExtendedEntity = ExternalExtendedEntity | InternalExtendedEntity;
128
145
  export type ExtendedGroup = {
129
146
  entities: ExtendedEntity[];
130
147
  label: Record<string, string> | string;
package/dist/types.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/types.ts"],"sourcesContent":["import type { icons, LucideIcon } from 'lucide-react'\nimport type { CollectionSlug, GlobalSlug } from 'payload'\n\nexport type IconName = keyof typeof icons\n\nexport type LocalizedString = { [locale: string]: string } | string\n\nexport type InternalIcon = IconName | LucideIcon\n\n// ============================================\n// Enhanced Sidebar Types\n// ============================================\n\n/**\n * Sidebar tab that shows content when selected\n */\nexport interface SidebarTabContent {\n /**\n * Collections to show in this tab.\n * If not specified, no collections are shown (unless items are specified).\n * Use collection slugs.\n */\n collections?: CollectionSlug[]\n /**\n * Custom items to add to this tab.\n * Items with `group` will be merged into matching collection groups.\n * Items without `group` will be shown at the bottom as a flat list.\n */\n customItems?: SidebarTabItem[]\n /**\n * Globals to show in this tab.\n * If not specified, no globals are shown.\n * Use global slugs.\n */\n globals?: GlobalSlug[]\n /** Icon name from lucide-react */\n icon: IconName\n /** Unique identifier for the tab */\n id: string\n /** Tooltip/label for the tab */\n label: LocalizedString\n type: 'tab'\n}\n\n/**\n * Sidebar link that navigates to a URL (not a tab)\n */\nexport interface SidebarTabLink {\n /** Link href (relative to admin route) */\n href: string\n /** Icon name from lucide-react */\n icon: IconName\n /** Unique identifier */\n id: string\n /** Tooltip/label */\n label: LocalizedString\n type: 'link'\n}\n\n/**\n * A tab or link in the sidebar tabs bar\n */\nexport type SidebarTab = SidebarTabContent | SidebarTabLink\n\ninterface BaseSidebarTabItem {\n /**\n * Group to add this item to.\n * If matches an existing collection group label, item will be merged into that group.\n * If no match found, a new group will be created.\n * If not specified, item will be shown at the bottom as ungrouped.\n */\n group?: LocalizedString\n /** Display label */\n label: LocalizedString\n /** Unique slug for the item */\n slug: string\n}\ninterface ExternalHrefItem extends BaseSidebarTabItem {\n /** Link href (absolute URL or relative to root) */\n href: string\n /** Whether the link is external, without admin route prefix. */\n isExternal: true\n}\n\ninterface InternalHrefItem extends BaseSidebarTabItem {\n /** Link href (relative to admin route) */\n href: '' | `/${string}`\n /** Whether the link is external, without admin route prefix. */\n isExternal?: false\n}\n/**\n * Custom item inside a sidebar tab\n */\nexport type SidebarTabItem = ExternalHrefItem | InternalHrefItem\n\n/**\n * Configuration for the enhanced sidebar\n */\nexport interface EnhancedSidebarConfig {\n /**\n * Disable the plugin\n * @default false\n */\n disabled?: boolean\n\n /**\n * Custom icons for collections and globals in the default tab.\n */\n icons?: {\n collections?: Partial<Record<CollectionSlug, IconName>>\n globals?: Partial<Record<GlobalSlug, IconName>>\n }\n\n /**\n * Show logout button at the bottom of the tabs bar.\n * @default true\n */\n showLogout?: boolean\n\n /**\n * Tabs and links to show in the sidebar tabs bar.\n * Order matters - items are rendered top to bottom.\n *\n * @default [{ type: 'tab', id: 'default', icon: 'LayoutGrid', label: 'Collections' }]\n */\n tabs?: SidebarTab[]\n}\n\n/**\n * Generic document type for collections, with dynamic keys.\n * We assume values are either string or number for simplicity, useAsTitle is making sure of that.\n */\nexport type GenericCollectionDocument = {\n [key: string]: number | string\n id: string\n}\n\nexport type ExtendedEntity = {\n href?: string\n label: Record<string, string> | string\n slug: string\n type: 'collection' | 'custom' | 'global'\n}\n\nexport type ExtendedGroup = {\n entities: ExtendedEntity[]\n label: Record<string, string> | string\n}\n"],"names":[],"mappings":"AAgJA,WAGC"}
1
+ {"version":3,"sources":["../src/types.ts"],"sourcesContent":["import type { icons, LucideIcon } from 'lucide-react'\nimport type { CollectionSlug, GlobalSlug } from 'payload'\n\nexport type IconName = keyof typeof icons\n\nexport type LocalizedString = { [locale: string]: string } | string\n\nexport type InternalIcon = IconName | LucideIcon\n\n// ============================================\n// Enhanced Sidebar Types\n// ============================================\n\n/**\n * Sidebar tab that shows content when selected\n */\nexport interface SidebarTabContent {\n /**\n * Collections to show in this tab.\n * If not specified, no collections are shown (unless items are specified).\n * Use collection slugs.\n */\n collections?: CollectionSlug[]\n /**\n * Custom items to add to this tab.\n * Items with `group` will be merged into matching collection groups.\n * Items without `group` will be shown at the bottom as a flat list.\n */\n customItems?: SidebarTabItem[]\n /**\n * Globals to show in this tab.\n * If not specified, no globals are shown.\n * Use global slugs.\n */\n globals?: GlobalSlug[]\n /** Icon name from lucide-react */\n icon: IconName\n /** Unique identifier for the tab */\n id: string\n /** Tooltip/label for the tab */\n label: LocalizedString\n type: 'tab'\n}\n\ninterface SidebarTabLinkBase {\n /** Icon name from lucide-react */\n icon: IconName\n /** Unique identifier */\n id: string\n /** Tooltip/label */\n label: LocalizedString\n type: 'link'\n}\ninterface SidebarTabLinkExternal extends SidebarTabLinkBase {\n /** Link href (absolute URL) */\n href: string\n isExternal: true\n}\ninterface SidebarTabLinkInternal extends SidebarTabLinkBase {\n /** Link href (relative to admin route) */\n href: '' | `/${string}`\n isExternal?: false\n}\n/**\n * Sidebar link that navigates to a URL (not a tab)\n */\nexport type SidebarTabLink = SidebarTabLinkExternal | SidebarTabLinkInternal\n/**\n * A tab or link in the sidebar tabs bar\n */\nexport type SidebarTab = SidebarTabContent | SidebarTabLink\n\ninterface BaseSidebarTabItem {\n /**\n * Group to add this item to.\n * If matches an existing collection group label, item will be merged into that group.\n * If no match found, a new group will be created.\n * If not specified, item will be shown at the bottom as ungrouped.\n */\n group?: LocalizedString\n /** Display label */\n label: LocalizedString\n /** Unique slug for the item */\n slug: string\n}\ninterface ExternalHrefItem extends BaseSidebarTabItem {\n /** Link href (absolute URL or relative to root) */\n href: string\n /** Whether the link is external, without admin route prefix. */\n isExternal: true\n}\n\ninterface InternalHrefItem extends BaseSidebarTabItem {\n /** Link href (relative to admin route) */\n href: '' | `/${string}`\n /** Whether the link is external, without admin route prefix. */\n isExternal?: false\n}\n/**\n * Custom item inside a sidebar tab\n */\nexport type SidebarTabItem = ExternalHrefItem | InternalHrefItem\n\n/**\n * Configuration for the enhanced sidebar\n */\nexport interface EnhancedSidebarConfig {\n /**\n * Disable the plugin\n * @default false\n */\n disabled?: boolean\n\n /**\n * Custom icons for collections and globals in the default tab.\n */\n icons?: {\n collections?: Partial<Record<CollectionSlug, IconName>>\n globals?: Partial<Record<GlobalSlug, IconName>>\n }\n\n /**\n * Show logout button at the bottom of the tabs bar.\n * @default true\n */\n showLogout?: boolean\n\n /**\n * Tabs and links to show in the sidebar tabs bar.\n * Order matters - items are rendered top to bottom.\n *\n * @default [{ type: 'tab', id: 'default', icon: 'LayoutGrid', label: 'Collections' }]\n */\n tabs?: SidebarTab[]\n}\n\n/**\n * Generic document type for collections, with dynamic keys.\n * We assume values are either string or number for simplicity, useAsTitle is making sure of that.\n */\nexport type GenericCollectionDocument = {\n [key: string]: number | string\n id: string\n}\n\ninterface BaseExtendedEntity {\n label: Record<string, string> | string\n slug: string\n type: 'collection' | 'custom' | 'global'\n}\n\ninterface InternalExtendedEntity extends BaseExtendedEntity {\n href?: '' | `/${string}`\n isExternal?: false\n}\n\ninterface ExternalExtendedEntity extends BaseExtendedEntity {\n href: string\n isExternal: true\n}\n\nexport type ExtendedEntity = ExternalExtendedEntity | InternalExtendedEntity\n\nexport type ExtendedGroup = {\n entities: ExtendedEntity[]\n label: Record<string, string> | string\n}\n"],"names":[],"mappings":"AAmKA,WAGC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@veiag/payload-enhanced-sidebar",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "An enhanced sidebar plugin for Payload CMS with tabbed navigation to organize collections and globals.",
5
5
  "author": "VeiaG",
6
6
  "license": "MIT",
@@ -1,6 +0,0 @@
1
- import React from 'react';
2
- import type { SidebarTabItem } from '../../types';
3
- export type CustomTabContentProps = {
4
- items: SidebarTabItem[];
5
- };
6
- export declare const CustomTabContent: React.FC<CustomTabContentProps>;
@@ -1,35 +0,0 @@
1
- 'use client';
2
- import { jsx as _jsx } from "react/jsx-runtime";
3
- import { getTranslation } from '@payloadcms/translations';
4
- import { Link, useConfig, useTranslation } from '@payloadcms/ui';
5
- import { usePathname } from 'next/navigation.js';
6
- import { formatAdminURL } from 'payload/shared';
7
- import React from 'react';
8
- const baseClass = 'enhanced-sidebar';
9
- export const CustomTabContent = ({ items })=>{
10
- const { i18n } = useTranslation();
11
- const pathname = usePathname();
12
- const { config: { routes: { admin: adminRoute } } } = useConfig();
13
- return /*#__PURE__*/ _jsx("div", {
14
- className: `${baseClass}__custom-items`,
15
- children: items.map((item)=>{
16
- const href = item.isExternal ? item.href : formatAdminURL({
17
- adminRoute,
18
- path: item.href
19
- });
20
- const label = getTranslation(item.label, i18n);
21
- const isActive = pathname.startsWith(href);
22
- return /*#__PURE__*/ _jsx(Link, {
23
- className: `${baseClass}__link ${isActive ? `${baseClass}__link--active` : ''}`,
24
- href: href,
25
- prefetch: false,
26
- children: /*#__PURE__*/ _jsx("span", {
27
- className: `${baseClass}__link-label`,
28
- children: label
29
- })
30
- }, item.slug);
31
- })
32
- });
33
- };
34
-
35
- //# sourceMappingURL=CustomTabContent.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../../../src/components/EnhancedSidebar/CustomTabContent.tsx"],"sourcesContent":["'use client'\n\nimport { getTranslation } from '@payloadcms/translations'\nimport { Link, useConfig, useTranslation } from '@payloadcms/ui'\nimport { usePathname } from 'next/navigation.js'\nimport { formatAdminURL } from 'payload/shared'\nimport React from 'react'\n\nimport type { SidebarTabItem } from '../../types'\n\nconst baseClass = 'enhanced-sidebar'\n\nexport type CustomTabContentProps = {\n items: SidebarTabItem[]\n}\n\nexport const CustomTabContent: React.FC<CustomTabContentProps> = ({ items }) => {\n const { i18n } = useTranslation()\n const pathname = usePathname()\n\n const {\n config: {\n routes: { admin: adminRoute },\n },\n } = useConfig()\n\n return (\n <div className={`${baseClass}__custom-items`}>\n {items.map((item) => {\n const href = item.isExternal ? item.href : formatAdminURL({ adminRoute, path: item.href })\n const label = getTranslation(item.label, i18n)\n const isActive = pathname.startsWith(href)\n\n return (\n <Link\n className={`${baseClass}__link ${isActive ? `${baseClass}__link--active` : ''}`}\n href={href}\n key={item.slug}\n prefetch={false}\n >\n <span className={`${baseClass}__link-label`}>{label}</span>\n </Link>\n )\n })}\n </div>\n )\n}\n"],"names":["getTranslation","Link","useConfig","useTranslation","usePathname","formatAdminURL","React","baseClass","CustomTabContent","items","i18n","pathname","config","routes","admin","adminRoute","div","className","map","item","href","isExternal","path","label","isActive","startsWith","prefetch","span","slug"],"mappings":"AAAA;;AAEA,SAASA,cAAc,QAAQ,2BAA0B;AACzD,SAASC,IAAI,EAAEC,SAAS,EAAEC,cAAc,QAAQ,iBAAgB;AAChE,SAASC,WAAW,QAAQ,qBAAoB;AAChD,SAASC,cAAc,QAAQ,iBAAgB;AAC/C,OAAOC,WAAW,QAAO;AAIzB,MAAMC,YAAY;AAMlB,OAAO,MAAMC,mBAAoD,CAAC,EAAEC,KAAK,EAAE;IACzE,MAAM,EAAEC,IAAI,EAAE,GAAGP;IACjB,MAAMQ,WAAWP;IAEjB,MAAM,EACJQ,QAAQ,EACNC,QAAQ,EAAEC,OAAOC,UAAU,EAAE,EAC9B,EACF,GAAGb;IAEJ,qBACE,KAACc;QAAIC,WAAW,GAAGV,UAAU,cAAc,CAAC;kBACzCE,MAAMS,GAAG,CAAC,CAACC;YACV,MAAMC,OAAOD,KAAKE,UAAU,GAAGF,KAAKC,IAAI,GAAGf,eAAe;gBAAEU;gBAAYO,MAAMH,KAAKC,IAAI;YAAC;YACxF,MAAMG,QAAQvB,eAAemB,KAAKI,KAAK,EAAEb;YACzC,MAAMc,WAAWb,SAASc,UAAU,CAACL;YAErC,qBACE,KAACnB;gBACCgB,WAAW,GAAGV,UAAU,OAAO,EAAEiB,WAAW,GAAGjB,UAAU,cAAc,CAAC,GAAG,IAAI;gBAC/Ea,MAAMA;gBAENM,UAAU;0BAEV,cAAA,KAACC;oBAAKV,WAAW,GAAGV,UAAU,YAAY,CAAC;8BAAGgB;;eAHzCJ,KAAKS,IAAI;QAMpB;;AAGN,EAAC"}