Sidebar.stories.tsx 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521
  1. import * as React from 'react';
  2. import { ModuleDefinition, Sidebar } from './Sidebar';
  3. import { SearchModuleDefinition } from './modules/Search';
  4. import { MainMenuModuleDefinition } from './modules/MainMenu';
  5. import { PageExplorerMenuItemDefinition } from './menu/PageExplorerMenuItem';
  6. import { LinkMenuItemDefinition } from './menu/LinkMenuItem';
  7. import { SubMenuItemDefinition } from './menu/SubMenuItem';
  8. import { WagtailBrandingModuleDefinition } from './modules/WagtailBranding';
  9. import { range } from '../../utils/range';
  10. export default {
  11. title: 'Sidebar/Sidebar',
  12. parameters: { layout: 'fullscreen' },
  13. };
  14. function searchModule(): SearchModuleDefinition {
  15. return new SearchModuleDefinition('/admin/search/');
  16. }
  17. function bogStandardMenuModule(): MainMenuModuleDefinition {
  18. return new MainMenuModuleDefinition(
  19. [
  20. new PageExplorerMenuItemDefinition(
  21. {
  22. name: 'explorer',
  23. label: 'Pages',
  24. url: '/admin/pages',
  25. icon_name: 'folder-open-inverse',
  26. classnames: '',
  27. },
  28. 1,
  29. ),
  30. new LinkMenuItemDefinition({
  31. name: 'images',
  32. label: 'Images',
  33. url: '/admin/images/',
  34. icon_name: 'image',
  35. classnames: '',
  36. }),
  37. new LinkMenuItemDefinition({
  38. name: 'documents',
  39. label: 'Documents',
  40. url: '/admin/documents/',
  41. icon_name: 'doc-full-inverse',
  42. classnames: '',
  43. }),
  44. new LinkMenuItemDefinition({
  45. name: 'snippets',
  46. label: 'Snippets',
  47. url: '/admin/snippets/',
  48. icon_name: 'snippet',
  49. classnames: '',
  50. }),
  51. new LinkMenuItemDefinition({
  52. name: 'forms',
  53. label: 'Forms',
  54. url: '/admin/forms/',
  55. icon_name: 'form',
  56. classnames: '',
  57. }),
  58. new SubMenuItemDefinition(
  59. {
  60. name: 'reports',
  61. label: 'Reports',
  62. icon_name: 'site',
  63. classnames: '',
  64. },
  65. [
  66. new LinkMenuItemDefinition({
  67. name: 'locked-pages',
  68. label: 'Locked pages',
  69. url: '/admin/reports/locked/',
  70. icon_name: 'lock',
  71. classnames: '',
  72. }),
  73. new LinkMenuItemDefinition({
  74. name: 'workflows',
  75. label: 'Workflows',
  76. url: '/admin/reports/workflow/',
  77. icon_name: 'tasks',
  78. classnames: '',
  79. }),
  80. new LinkMenuItemDefinition({
  81. name: 'workflow-tasks',
  82. label: 'Workflow tasks',
  83. url: '/admin/reports/workflow_tasks/',
  84. icon_name: 'thumbtack',
  85. classnames: '',
  86. }),
  87. new LinkMenuItemDefinition({
  88. name: 'site-history',
  89. label: 'Site history',
  90. url: '/admin/reports/site-history/',
  91. icon_name: 'history',
  92. classnames: '',
  93. }),
  94. ],
  95. ),
  96. new SubMenuItemDefinition(
  97. {
  98. name: 'settings',
  99. label: 'Settings',
  100. icon_name: 'cogs',
  101. classnames: '',
  102. footer_text: 'Wagtail Version',
  103. },
  104. [
  105. new LinkMenuItemDefinition({
  106. name: 'workflows',
  107. label: 'Workflows',
  108. url: '/admin/workflows/list/',
  109. icon_name: 'tasks',
  110. classnames: '',
  111. }),
  112. new LinkMenuItemDefinition({
  113. name: 'workflow-tasks',
  114. label: 'Workflow tasks',
  115. url: '/admin/workflows/tasks/index/',
  116. icon_name: 'thumbtack',
  117. classnames: '',
  118. }),
  119. new LinkMenuItemDefinition({
  120. name: 'users',
  121. label: 'Users',
  122. url: '/admin/users/',
  123. icon_name: 'user',
  124. classnames: '',
  125. }),
  126. new LinkMenuItemDefinition({
  127. name: 'groups',
  128. label: 'Groups',
  129. url: '/admin/groups/',
  130. icon_name: 'group',
  131. classnames: '',
  132. }),
  133. new LinkMenuItemDefinition({
  134. name: 'sites',
  135. label: 'Sites',
  136. url: '/admin/sites/',
  137. icon_name: 'site',
  138. classnames: '',
  139. }),
  140. new LinkMenuItemDefinition({
  141. name: 'collections',
  142. label: 'Collections',
  143. url: '/admin/collections/',
  144. icon_name: 'folder-open-1',
  145. classnames: '',
  146. }),
  147. new LinkMenuItemDefinition({
  148. name: 'redirects',
  149. label: 'Redirects',
  150. url: '/admin/redirects/',
  151. icon_name: 'redirect',
  152. classnames: '',
  153. }),
  154. ],
  155. ),
  156. ],
  157. [
  158. new LinkMenuItemDefinition({
  159. name: 'account',
  160. label: 'Account',
  161. url: '/admin/account/',
  162. icon_name: 'user',
  163. classnames: '',
  164. }),
  165. new LinkMenuItemDefinition({
  166. name: 'logout',
  167. label: 'Log out',
  168. url: '/admin/logout/',
  169. icon_name: 'logout',
  170. classnames: '',
  171. }),
  172. ],
  173. {
  174. name: 'Admin',
  175. avatarUrl:
  176. 'https://gravatar.com/avatar/e31ec811942afbf7b9ce0ac5affe426f?s=200&d=robohash&r=x',
  177. },
  178. );
  179. }
  180. interface RenderSidebarStoryOptions {
  181. rtl?: boolean;
  182. }
  183. function renderSidebarStory(
  184. modules: ModuleDefinition[],
  185. { rtl = false }: RenderSidebarStoryOptions = {},
  186. ) {
  187. // Add branding to all sidebar stories by default
  188. const wagtailBrandingModule = new WagtailBrandingModuleDefinition('');
  189. modules.unshift(wagtailBrandingModule);
  190. // Simulate navigation
  191. const [currentPath, setCurrentPath] = React.useState('/admin/');
  192. const navigate = (url: string) => {
  193. setCurrentPath(url);
  194. // Return resolved promise to close menu immediately
  195. return Promise.resolve();
  196. };
  197. const onExpandCollapse = (collapsed: boolean) => {
  198. if (collapsed) {
  199. document.body.classList.add('sidebar-collapsed');
  200. } else {
  201. document.body.classList.remove('sidebar-collapsed');
  202. }
  203. };
  204. if (rtl) {
  205. document.documentElement.setAttribute('dir', 'rtl');
  206. } else {
  207. document.documentElement.setAttribute('dir', 'ltr');
  208. }
  209. return (
  210. <div className="wrapper">
  211. <Sidebar
  212. collapsedOnLoad={false}
  213. modules={modules}
  214. currentPath={currentPath}
  215. navigate={navigate}
  216. onExpandCollapse={onExpandCollapse}
  217. />
  218. <main id="main" className="content-wrapper">
  219. <div className="content">
  220. <b>Current path:</b> {currentPath}
  221. </div>
  222. </main>
  223. </div>
  224. );
  225. }
  226. export function standard() {
  227. return renderSidebarStory([searchModule(), bogStandardMenuModule()]);
  228. }
  229. export function withNestedSubmenu() {
  230. const menuModule = bogStandardMenuModule();
  231. menuModule.menuItems.push(
  232. new SubMenuItemDefinition(
  233. {
  234. name: 'nested-menu',
  235. label: 'Nested menu',
  236. icon_name: 'cogs',
  237. classnames: '',
  238. },
  239. [
  240. new LinkMenuItemDefinition({
  241. name: 'item',
  242. label: 'Item',
  243. url: '/admin/item/',
  244. icon_name: 'user',
  245. classnames: '',
  246. }),
  247. new SubMenuItemDefinition(
  248. {
  249. name: 'nested-menu',
  250. label: 'Nested menu',
  251. icon_name: 'folder-open-1',
  252. classnames: '',
  253. },
  254. [
  255. new LinkMenuItemDefinition({
  256. name: 'item',
  257. label: 'Item',
  258. url: '/admin/item/item/',
  259. icon_name: 'user',
  260. classnames: '',
  261. }),
  262. new SubMenuItemDefinition(
  263. {
  264. name: 'deeply-nested-menu',
  265. label: 'Deeply nested menu',
  266. icon_name: 'side',
  267. classnames: '',
  268. },
  269. [
  270. new LinkMenuItemDefinition({
  271. name: 'item',
  272. label: 'Item',
  273. url: '/admin/item/item/item/',
  274. icon_name: 'user',
  275. classnames: '',
  276. }),
  277. ],
  278. ),
  279. new SubMenuItemDefinition(
  280. {
  281. name: 'another-deeply-nested-menu',
  282. label: 'Another deeply nested menu',
  283. icon_name: 'user',
  284. classnames: '',
  285. },
  286. [
  287. new LinkMenuItemDefinition({
  288. name: 'item',
  289. label: 'Item',
  290. url: '/admin/item/item/item2/',
  291. icon_name: 'user',
  292. classnames: '',
  293. }),
  294. ],
  295. ),
  296. ],
  297. ),
  298. ],
  299. ),
  300. );
  301. return renderSidebarStory([searchModule(), menuModule]);
  302. }
  303. export function withLargeSubmenu() {
  304. const menuModule = bogStandardMenuModule();
  305. const menuItems = [];
  306. range(0, 100).forEach((i) => {
  307. menuItems.push(
  308. new LinkMenuItemDefinition({
  309. name: `item-${i}`,
  310. label: `Item ${i}`,
  311. url: `/admin/item-${i}/`,
  312. icon_name: 'snippet',
  313. classnames: '',
  314. }),
  315. );
  316. });
  317. menuModule.menuItems.push(
  318. new SubMenuItemDefinition(
  319. {
  320. name: 'large-menu',
  321. label: 'Large menu',
  322. icon_name: 'cogs',
  323. classnames: '',
  324. footer_text: 'Footer text',
  325. },
  326. menuItems,
  327. ),
  328. );
  329. return renderSidebarStory([searchModule(), menuModule]);
  330. }
  331. export function withoutSearch() {
  332. return renderSidebarStory([bogStandardMenuModule()]);
  333. }
  334. function arabicMenuModule(): MainMenuModuleDefinition {
  335. return new MainMenuModuleDefinition(
  336. [
  337. new PageExplorerMenuItemDefinition({
  338. name: 'explorer',
  339. label: 'صفحات',
  340. url: '/admin/pages',
  341. start_page_id: 1,
  342. icon_name: 'folder-open-inverse',
  343. classnames: '',
  344. }),
  345. new LinkMenuItemDefinition({
  346. name: 'images',
  347. label: 'صور',
  348. url: '/admin/images/',
  349. icon_name: 'image',
  350. classnames: '',
  351. }),
  352. new LinkMenuItemDefinition({
  353. name: 'documents',
  354. label: 'وثائق',
  355. url: '/admin/documents/',
  356. icon_name: 'doc-full-inverse',
  357. classnames: '',
  358. }),
  359. new LinkMenuItemDefinition({
  360. name: 'snippets',
  361. label: 'قصاصات',
  362. url: '/admin/snippets/',
  363. icon_name: 'snippet',
  364. classnames: '',
  365. }),
  366. new LinkMenuItemDefinition({
  367. name: 'forms',
  368. label: 'نماذج',
  369. url: '/admin/forms/',
  370. icon_name: 'form',
  371. classnames: '',
  372. }),
  373. new SubMenuItemDefinition(
  374. {
  375. name: 'reports',
  376. label: 'التقارير',
  377. icon_name: 'site',
  378. classnames: '',
  379. },
  380. [
  381. new LinkMenuItemDefinition({
  382. name: 'locked-pages',
  383. label: 'Locked pages',
  384. url: '/admin/reports/locked/',
  385. icon_name: 'lock',
  386. classnames: '',
  387. }),
  388. new LinkMenuItemDefinition({
  389. name: 'workflows',
  390. label: 'Workflows',
  391. url: '/admin/reports/workflow/',
  392. icon_name: 'tasks',
  393. classnames: '',
  394. }),
  395. new LinkMenuItemDefinition({
  396. name: 'workflow-tasks',
  397. label: 'Workflow tasks',
  398. url: '/admin/reports/workflow_tasks/',
  399. icon_name: 'thumbtack',
  400. classnames: '',
  401. }),
  402. new LinkMenuItemDefinition({
  403. name: 'site-history',
  404. label: 'Site history',
  405. url: '/admin/reports/site-history/',
  406. icon_name: 'history',
  407. classnames: '',
  408. }),
  409. ],
  410. ),
  411. new SubMenuItemDefinition(
  412. {
  413. name: 'settings',
  414. label: 'إعدادات',
  415. icon_name: 'cogs',
  416. classnames: '',
  417. },
  418. [
  419. new LinkMenuItemDefinition({
  420. name: 'workflows',
  421. label: 'Workflows',
  422. url: '/admin/workflows/list/',
  423. icon_name: 'tasks',
  424. classnames: '',
  425. }),
  426. new LinkMenuItemDefinition({
  427. name: 'workflow-tasks',
  428. label: 'Workflow tasks',
  429. url: '/admin/workflows/tasks/index/',
  430. icon_name: 'thumbtack',
  431. classnames: '',
  432. }),
  433. new LinkMenuItemDefinition({
  434. name: 'users',
  435. label: 'مستخدمين',
  436. url: '/admin/users/',
  437. icon_name: 'user',
  438. classnames: '',
  439. }),
  440. new LinkMenuItemDefinition({
  441. name: 'groups',
  442. label: 'مجموعات',
  443. url: '/admin/groups/',
  444. icon_name: 'group',
  445. classnames: '',
  446. }),
  447. new LinkMenuItemDefinition({
  448. name: 'sites',
  449. label: 'مواقع',
  450. url: '/admin/sites/',
  451. icon_name: 'site',
  452. classnames: '',
  453. }),
  454. new LinkMenuItemDefinition({
  455. name: 'collections',
  456. label: 'مجموعات',
  457. url: '/admin/collections/',
  458. icon_name: 'folder-open-1',
  459. classnames: '',
  460. }),
  461. new LinkMenuItemDefinition({
  462. name: 'redirects',
  463. label: 'اعادة التوجيهات',
  464. url: '/admin/redirects/',
  465. icon_name: 'redirect',
  466. classnames: '',
  467. }),
  468. ],
  469. ),
  470. ],
  471. [
  472. new LinkMenuItemDefinition({
  473. name: 'account',
  474. label: 'حساب',
  475. url: '/admin/account/',
  476. icon_name: 'user',
  477. classnames: '',
  478. }),
  479. new LinkMenuItemDefinition({
  480. name: 'logout',
  481. label: 'تسجيل الخروج',
  482. url: '/admin/logout/',
  483. icon_name: 'logout',
  484. classnames: '',
  485. }),
  486. ],
  487. {
  488. name: 'Admin',
  489. avatarUrl:
  490. 'https://gravatar.com/avatar/e31ec811942afbf7b9ce0ac5affe426f?s=200&d=robohash&r=x',
  491. },
  492. );
  493. }
  494. export function rightToLeft() {
  495. return renderSidebarStory([searchModule(), arabicMenuModule()], {
  496. rtl: true,
  497. });
  498. }