| 1 | <html> |
| 2 | |
| 3 | <head> |
| 4 | <script type="module"> |
| 5 | import { store as sidebarStore } from "/components/sidebar/sidebar-store.js"; |
| 6 | </script> |
| 7 | <!-- Wrapper composes existing sidebar components --> |
| 8 | </head> |
| 9 | |
| 10 | <body> |
| 11 | <div x-data> |
| 12 | <template x-if="$store.sidebar"> |
| 13 | <div class="sidebar-shell" |
| 14 | @click.window="$store.sidebar.rowMenuClick($event, $refs.rowActionsMenu)" |
| 15 | @keydown.escape.window="$store.sidebar.rowMenuClose()"> |
| 16 | <x-component path="sidebar/top-section/header-icons.html"></x-component> |
| 17 | <div id="left-panel" class="panel" x-data :class="{'hidden': !$store.sidebar.isOpen}"> |
| 18 | <x-extension id="sidebar-start"></x-extension> |
| 19 | <!--Sidebar upper elements--> |
| 20 | <div class="left-panel-top no-scrollbar"> |
| 21 | <!-- Top Section: Quick Actions --> |
| 22 | <x-component path="sidebar/top-section/sidebar-top.html"></x-component> |
| 23 | <!-- Chats List --> |
| 24 | <div class="config-section" id="chats-section"> |
| 25 | <x-component path="sidebar/chats/chats-list.html"></x-component> |
| 26 | </div> |
| 27 | |
| 28 | <!-- Tasks List --> |
| 29 | <div class="config-section" id="tasks-section"> |
| 30 | <x-component path="sidebar/tasks/tasks-list.html"></x-component> |
| 31 | </div> |
| 32 | </div> |
| 33 | <!--Sidebar lower elements--> |
| 34 | <div class="left-panel-bottom"> |
| 35 | <x-component path="sidebar/bottom/sidebar-bottom.html"></x-component> |
| 36 | </div> |
| 37 | <x-extension id="sidebar-end"></x-extension> |
| 38 | </div> |
| 39 | <div x-ref="rowActionsMenu" class="dropdown-menu sidebar-row-actions-menu" role="menu" |
| 40 | x-show="$store.sidebar.rowMenuOpenId" x-transition :style="$store.sidebar.rowMenuStyle" |
| 41 | style="display: none;" @click.stop> |
| 42 | <x-extension id="sidebar-row-actions-menu"></x-extension> |
| 43 | </div> |
| 44 | </div> |
| 45 | </template> |
| 46 | </div> |
| 47 | |
| 48 | <style> |
| 49 | /* Left Panel styles from index.css */ |
| 50 | #left-panel { |
| 51 | background-color: var(--color-panel); |
| 52 | border-right: 1px solid var(--color-border); |
| 53 | box-sizing: border-box; |
| 54 | display: flex; |
| 55 | flex-direction: column; |
| 56 | justify-content: space-between; |
| 57 | transition: all var(--transition-speed) ease-in-out; |
| 58 | width: 250px; |
| 59 | min-width: 250px; |
| 60 | color: var(--color-text); |
| 61 | box-shadow: 1px 0 5px rgba(0, 0, 0, 0.3); |
| 62 | user-select: none; |
| 63 | -webkit-user-select: none; |
| 64 | /* Safari compatibility */ |
| 65 | height: 100vh; |
| 66 | /* Ensure full height */ |
| 67 | overflow: hidden; |
| 68 | /* Prevent overall panel overflow */ |
| 69 | } |
| 70 | |
| 71 | /* Ensure component host behaves like the original direct children for flex layout */ |
| 72 | #left-panel>.left-panel-top, |
| 73 | #left-panel>.left-panel-bottom { |
| 74 | display: flex; |
| 75 | flex-direction: column; |
| 76 | } |
| 77 | |
| 78 | #left-panel>.left-panel-top { |
| 79 | flex: 1; |
| 80 | min-height: 0; |
| 81 | /* allow inner flex children to shrink properly */ |
| 82 | } |
| 83 | |
| 84 | #left-panel.hidden { |
| 85 | margin-left: -250px; |
| 86 | } |
| 87 | |
| 88 | .left-panel-top { |
| 89 | flex: 1 1 auto; |
| 90 | /* Take available space */ |
| 91 | display: -webkit-flex; |
| 92 | display: flex; |
| 93 | flex-direction: column; |
| 94 | min-height: 0; |
| 95 | /* Critical for allowing flex children to shrink */ |
| 96 | overflow: hidden; |
| 97 | justify-content: space-between; |
| 98 | margin-top: 6.5rem; |
| 99 | padding: var(--spacing-md) var(--spacing-md) 0 var(--spacing-md); |
| 100 | } |
| 101 | |
| 102 | .left-panel-bottom { |
| 103 | position: relative; |
| 104 | flex-shrink: 0; |
| 105 | flex-grow: 0; |
| 106 | /* Prevent bottom from growing */ |
| 107 | } |
| 108 | |
| 109 | .sidebar-row-actions-menu { |
| 110 | position: fixed; |
| 111 | z-index: 9999; |
| 112 | margin: 0; |
| 113 | } |
| 114 | |
| 115 | .config-list li.sidebar-list-divider { |
| 116 | border-top: 1px solid color-mix(in srgb, var(--color-border) 55%, transparent); |
| 117 | margin-top: var(--spacing-xs); |
| 118 | padding-top: calc(0.28rem + var(--spacing-xs)); |
| 119 | } |
| 120 | |
| 121 | /* Chats section container inside sidebar */ |
| 122 | #chats-section { |
| 123 | display: -webkit-flex; |
| 124 | display: flex; |
| 125 | flex-direction: column; |
| 126 | min-height: 0; |
| 127 | flex: 1 1 auto; |
| 128 | /* Take all available space */ |
| 129 | max-height: 100%; |
| 130 | margin-inline-start: calc(0px - var(--spacing-sm)); |
| 131 | width: calc(100% + var(--spacing-sm)); |
| 132 | overflow: hidden; |
| 133 | } |
| 134 | |
| 135 | /* Tasks section container inside sidebar */ |
| 136 | #tasks-section { |
| 137 | display: -webkit-flex; |
| 138 | display: flex; |
| 139 | flex-direction: column; |
| 140 | min-height: 0; |
| 141 | flex: 0 0 auto; |
| 142 | /* Shrink to content, no reserved space */ |
| 143 | max-height: 40%; |
| 144 | /* Limit to 40% of viewport height when expanded */ |
| 145 | margin-top: 0; |
| 146 | margin-inline-start: calc(0px - var(--spacing-sm)); |
| 147 | width: calc(100% + var(--spacing-sm)); |
| 148 | padding-top: var(--spacing-md); |
| 149 | overflow: hidden; |
| 150 | } |
| 151 | |
| 152 | #chats-section .section-header-row, |
| 153 | #tasks-section .section-header { |
| 154 | margin-inline-start: var(--spacing-sm); |
| 155 | } |
| 156 | |
| 157 | /* Flatten wrapper elements to maintain flex chain for inner scroll containers */ |
| 158 | #chats-section>x-component, |
| 159 | #chats-section>x-component>div[x-data], |
| 160 | #tasks-section>x-component, |
| 161 | #tasks-section>x-component>div[x-data], |
| 162 | #tasks-section>x-component>div[x-data]>div[x-data] { |
| 163 | display: contents; |
| 164 | } |
| 165 | |
| 166 | /* Bootstrap collapse elements need proper display for animation to work */ |
| 167 | #tasks-section .collapse { |
| 168 | display: flex; |
| 169 | flex-direction: column; |
| 170 | flex: 1; |
| 171 | min-height: 0; |
| 172 | } |
| 173 | |
| 174 | /* During the collapsing transition, allow height animation to control size */ |
| 175 | #tasks-section .collapsing { |
| 176 | flex: 0 0 auto !important; |
| 177 | } |
| 178 | |
| 179 | /* Common section header styling (Chats, Tasks) - matching Preferences style */ |
| 180 | .section-header { |
| 181 | display: flex; |
| 182 | align-items: center; |
| 183 | justify-content: space-between; |
| 184 | gap: 6px; |
| 185 | margin: 0 0 0.5rem 0; |
| 186 | padding: 0; |
| 187 | -webkit-user-select: none; |
| 188 | /* Safari compatibility */ |
| 189 | user-select: none; |
| 190 | font-size: var(--font-size-normal); |
| 191 | } |
| 192 | |
| 193 | /* Collapsible section headers (Tasks) */ |
| 194 | .section-header-collapsible { |
| 195 | cursor: pointer; |
| 196 | } |
| 197 | |
| 198 | .light-mode #left-panel { |
| 199 | box-shadow: 1px 0 10px rgba(0, 0, 0, 0.1); |
| 200 | } |
| 201 | |
| 202 | @media (max-width: 768px) { |
| 203 | #left-panel { |
| 204 | position: fixed; |
| 205 | left: 0; |
| 206 | top: 0; |
| 207 | bottom: 0; |
| 208 | width: 250px !important; |
| 209 | /* Force width */ |
| 210 | min-width: 250px; |
| 211 | z-index: 1003; |
| 212 | transition: all var(--transition-speed) ease-in-out; |
| 213 | } |
| 214 | |
| 215 | #left-panel.hidden { |
| 216 | margin-left: -250px; |
| 217 | } |
| 218 | } |
| 219 | |
| 220 | @media (max-height: 600px) { |
| 221 | #chats-section { |
| 222 | min-height: 100%; |
| 223 | } |
| 224 | |
| 225 | .left-panel-top { |
| 226 | overflow-y: auto; |
| 227 | -webkit-scroll-behavior: smooth; |
| 228 | scroll-behavior: smooth; |
| 229 | } |
| 230 | } |
| 231 | </style> |
| 232 | </body> |
| 233 | |
| 234 | </html> |