Вы не можете выбрать более 25 тем Темы должны начинаться с буквы или цифры, могут содержать дефисы(-) и должны содержать не более 35 символов.

panel-shift-dropdown.blade.php 7.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. @php
  2. $items = filament()->getUserMenuItems();
  3. $logoutItem = $items['logout'] ?? null;
  4. $currentTenant = filament()->getTenant();
  5. $currentTenantName = $currentTenant ? filament()->getTenantName($currentTenant) : null;
  6. $navigation = $component->getNavigation();
  7. $hasDisplayAndAccessibility = $component->hasDisplayAndAccessibility();
  8. $hasCompanySettings = $component->hasCompanySettings();
  9. $hasLogoutItem = $component->hasLogoutItem();
  10. $panels = $component->getNavigationAsHierarchyArray();
  11. @endphp
  12. <div x-data="panelShiftDropdown">
  13. <div x-on:click="toggleDropdown()" class="flex cursor-pointer">
  14. <button
  15. type="button"
  16. class="fi-tenant-menu-trigger group flex w-full items-center justify-center gap-x-3 rounded-lg p-2 text-sm font-medium outline-none transition duration-75 hover:bg-gray-100 focus-visible:bg-gray-100 dark:hover:bg-white/5 dark:focus-visible:bg-white/5"
  17. >
  18. <x-filament-panels::avatar.tenant
  19. :tenant="$currentTenant"
  20. class="shrink-0"
  21. />
  22. <span class="grid justify-items-start text-start">
  23. @if ($currentTenant instanceof \Filament\Models\Contracts\HasCurrentTenantLabel)
  24. <span class="text-xs text-gray-500 dark:text-gray-400">
  25. {{ $currentTenant->getCurrentTenantLabel() }}
  26. </span>
  27. @endif
  28. <span class="text-gray-950 dark:text-white">
  29. {{ $currentTenantName }}
  30. </span>
  31. </span>
  32. <x-filament::icon
  33. icon="heroicon-m-chevron-down"
  34. class="h-5 w-5 transition duration-75 text-gray-400 group-hover:text-gray-500 group-focus-visible:text-gray-500 dark:text-gray-500 dark:group-hover:text-gray-400 dark:group-focus-visible:text-gray-400"
  35. x-bind:class="{ 'rotate-180': open }"
  36. />
  37. </button>
  38. </div>
  39. <div x-show="open" class="flex flex-col transition duration-200 ease-in-out grow shrink mt-4 absolute z-10 w-screen max-w-[360px] end-8 rounded-lg bg-white shadow-lg ring-1 ring-gray-950/5 dark:bg-gray-900 dark:ring-white/10 overflow-hidden">
  40. @foreach($panels as $panelId => $panel)
  41. <x-panel-shift-dropdown.panel :panel-id="$panelId">
  42. @if($panelId !== 'main' && isset($panel['label']))
  43. <x-panel-shift-dropdown.subpanel-header :label="$panel['label']" :panel-id="$panelId" />
  44. @endif
  45. @if($panel['renderItems'])
  46. @foreach($panel['items'] as $item)
  47. <x-panel-shift-dropdown.content-handler :item="$item" />
  48. @endforeach
  49. @endif
  50. @if($panelId === 'company-settings')
  51. <x-panel-shift-dropdown.company-settings :current-tenant="$currentTenant" icon="heroicon-m-building-office-2" />
  52. @endif
  53. @if($panelId === 'company-switcher')
  54. <x-panel-shift-dropdown.company-switcher :current-tenant="$currentTenant" icon="heroicon-m-adjustments-horizontal" />
  55. @endif
  56. @if($panelId === 'display-and-accessibility')
  57. <x-panel-shift-dropdown.display-accessibility icon="heroicon-s-moon"/>
  58. @endif
  59. @if($panelId === 'main' && $hasLogoutItem)
  60. <x-panel-shift-dropdown.item
  61. tag="form"
  62. method="post"
  63. :action="$logoutItem?->getUrl() ?? filament()->getLogoutUrl()"
  64. :label="$logoutItem?->getLabel() ?? __('filament-panels::layout.actions.logout.label')"
  65. :icon="$logoutItem?->getIcon() ?? \Filament\Support\Facades\FilamentIcon::resolve('panels::user-menu.logout-button') ?? 'heroicon-m-arrow-left-on-rectangle'"
  66. />
  67. @endif
  68. </x-panel-shift-dropdown.panel>
  69. @endforeach
  70. </div>
  71. </div>
  72. <script>
  73. document.addEventListener('alpine:init', () => {
  74. Alpine.data('panelShiftDropdown', () => ({
  75. open: false,
  76. navigationStack: ['main'],
  77. theme: localStorage.getItem('theme') || '{{ filament()->getDefaultThemeMode()->value }}',
  78. themeLabels: {
  79. light: 'Off',
  80. dark: 'On',
  81. system: 'System',
  82. },
  83. toggleDropdown() {
  84. this.open = !this.open;
  85. },
  86. setActiveMenu(menu) {
  87. this.transitionPanel(menu, 'forward');
  88. },
  89. focusMenuItem(menuItemRef) {
  90. this.$nextTick(() => {
  91. setTimeout(() => {
  92. this.$refs[menuItemRef]?.focus();
  93. }, 200);
  94. });
  95. },
  96. focusBackButton(backButtonRef) {
  97. this.$nextTick(() => {
  98. setTimeout(() => {
  99. this.$refs[backButtonRef]?.focus();
  100. }, 200);
  101. });
  102. },
  103. goBack() {
  104. if (this.open && this.navigationStack.length > 1) {
  105. this.transitionPanel(this.navigationStack.at(-2), 'back');
  106. }
  107. },
  108. currentActiveMenu() {
  109. return this.navigationStack.at(-1);
  110. },
  111. transitionPanel(target, direction) {
  112. const currentPanel = this.$refs[this.currentActiveMenu()];
  113. const targetPanel = this.$refs[target];
  114. const translateX = direction === 'forward' ? '-100%' : '100%';
  115. currentPanel.style.transform = `translateX(${translateX})`;
  116. setTimeout(() => {
  117. currentPanel.classList.add('hide');
  118. targetPanel.classList.remove('hide');
  119. targetPanel.style.transform = 'translateX(0)';
  120. if (direction === 'forward') {
  121. this.navigationStack.push(target);
  122. } else {
  123. this.navigationStack.pop();
  124. }
  125. }, 200);
  126. },
  127. setTheme(newTheme) {
  128. this.theme = newTheme;
  129. },
  130. init() {
  131. this.$watch('theme', (value) => {
  132. this.$dispatch('theme-changed', value);
  133. });
  134. this.$watch('open', (value) => {
  135. if (value) {
  136. if (this.navigationStack.length === 1) {
  137. const mainPanel = this.$refs.main;
  138. mainPanel.classList.remove('hide');
  139. mainPanel.style.transform = 'translateX(0)';
  140. }
  141. } else {
  142. if (this.currentActiveMenu() !== 'main') {
  143. this.setActiveMenu('main');
  144. }
  145. }
  146. });
  147. },
  148. getThemeLabel(value) {
  149. return this.themeLabels[value] || value;
  150. },
  151. }));
  152. });
  153. </script>