1/* 2 * Copyright (C) 2022 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16import { BaseElement, element } from '../BaseElement'; 17import './LitMainMenuItem'; 18import './LitMainMenuGroup'; 19import { LitMainMenuGroup } from './LitMainMenuGroup'; 20import { LitMainMenuItem } from './LitMainMenuItem'; 21 22const initHtmlStyle: string = ` 23 <style> 24 :host{ 25 width: 248px; 26 height: 100vh; 27 display: flex; 28 flex-direction: column; 29 background-color: #fff; 30 } 31 .menu-body ::-webkit-scrollbar-thumb 32 { 33 background-color: var(--dark-background,#FFFFFF); 34 border-radius:10px; 35 36 } 37 .menu-body ::-webkit-scrollbar-track 38 { 39 border-radius:10px; 40 background-color:#F5F5F5; 41 42 } 43 .header{ 44 display: grid; 45 width: 100%; 46 height: 56px; 47 padding-left: 24px; 48 gap: 0 14px; 49 box-sizing: border-box; 50 grid-template-columns: min-content 1fr min-content; 51 grid-template-rows: auto; 52 color: #47A7E0; 53 background-color: var(--dark-background1); 54 border-bottom: 1px solid var(--dark-background1,#EFEFEF); 55 align-self: center; 56 } 57 .logo-img{ 58 width: 32px; 59 height: 32px; 60 vertical-align: middle; 61 } 62 .logo-text{ 63 font-family: 鸿蒙; 64 font-size: 20px; 65 color: #1E4EEA; 66 } 67 .bottom{ 68 width: 100%; 69 display: flex; 70 justify-content: space-between; 71 } 72 .header *{ 73 user-select: none; 74 align-self: center; 75 } 76 .version{ 77 width: 15rem; 78 padding: 20px 0; 79 text-align: center; 80 color: #94979d; 81 font-size: 0.6rem; 82 } 83 .color, .customColor{ 84 cursor: pointer; 85 font-size: 0.6rem; 86 padding: 20px 0px 20px 20px; 87 } 88 *{ 89 box-sizing: border-box; 90 } 91 .menu-button{ 92 display: flex; 93 align-content: center; 94 justify-content: center; 95 cursor: pointer; 96 height: 47px; 97 width: 48px; 98 color: #1E4EEA; 99 } 100 </style> 101 `; 102 103@element('lit-main-menu') 104export class LitMainMenu extends BaseElement { 105 private slotElements: Element[] | undefined; 106 private _menus: Array<MenuGroup> | undefined; 107 108 static get observedAttributes(): string[] { 109 return []; 110 } 111 112 get menus(): Array<MenuGroup> | undefined { 113 return this._menus; 114 } 115 116 set menus(value: Array<MenuGroup> | undefined) { 117 this._menus = value; 118 this.shadowRoot?.querySelectorAll('lit-main-menu-group').forEach((a) => a.remove()); 119 let menuBody = this.shadowRoot?.querySelector('.menu-body'); 120 if (this.getAttribute('main_menu') === '1' && window.localStorage.getItem('Theme') === 'dark') { 121 this.style.backgroundColor = '#262f3c'; 122 } else { 123 this.style.backgroundColor = '#fff'; 124 } 125 value?.forEach((it) => { 126 let group: LitMainMenuGroup = new LitMainMenuGroup(); 127 group.setAttribute('title', it.title || ''); 128 if (it.describe !== '') { 129 group.setAttribute('describe', it.describe || ''); 130 } else { 131 group.removeAttribute('describe'); 132 } 133 group.setAttribute('icon', it.icon || ''); 134 if (it.collapsed) { 135 group.setAttribute('collapsed', ''); 136 } else { 137 group.removeAttribute('collapsed'); 138 } 139 let groupName: LitMainMenuGroup = group!.shadowRoot!.querySelector('.group-name') as LitMainMenuGroup; 140 let groupDescribe: LitMainMenuGroup = group!.shadowRoot!.querySelector('.group-describe') as LitMainMenuGroup; 141 menuBody?.appendChild(group); // @ts-ignore 142 it.children?.forEach((item: unknown) => { 143 // @ts-ignore 144 if (item.fileModel !== undefined && item.fileModel === 'db') { 145 return; 146 } // @ts-ignore 147 if (item.children && item.children.length > 0) { 148 let secondGroup: LitMainMenuGroup = new LitMainMenuGroup(); // @ts-ignore 149 secondGroup.setAttribute('title', item.title || ''); // @ts-ignore 150 if (item.describe !== '') { 151 // @ts-ignore 152 secondGroup.setAttribute('describe', item.describe || ''); 153 } else { 154 secondGroup.removeAttribute('describe'); 155 } 156 this.setChildren(item, group, groupName, groupDescribe, secondGroup); 157 } else { 158 this.notChildren(item, group, groupName, groupDescribe); 159 } 160 }); 161 }); 162 } 163 164 setChildren( 165 item: unknown, 166 group: LitMainMenuGroup, 167 groupName: LitMainMenuGroup, 168 groupDescribe: LitMainMenuGroup, 169 secondGroup: LitMainMenuGroup 170 ): void { 171 // @ts-ignore 172 secondGroup.setAttribute('icon', item.icon || ''); // @ts-ignore 173 if (item.second) { 174 secondGroup.setAttribute('second', ''); 175 } else { 176 secondGroup.removeAttribute('second'); 177 } // @ts-ignore 178 if (item.collapsed) { 179 secondGroup.setAttribute('collapsed', ''); 180 } else { 181 secondGroup.removeAttribute('collapsed'); 182 } 183 group?.appendChild(secondGroup); // @ts-ignore 184 item.children?.forEach((v: unknown) => { 185 let th = new LitMainMenuItem(); // @ts-ignore 186 th.setAttribute('icon', v.icon || ''); // @ts-ignore 187 th.setAttribute('title', v.title || ''); 188 if (this.getAttribute('main_menu') === '1' && window.localStorage.getItem('Theme') === 'dark') { 189 groupName.style.color = 'white'; 190 groupDescribe.style.color = 'white'; 191 th!.style.color = 'white'; 192 } else { 193 groupName.style.color = 'black'; 194 groupDescribe.style.color = 'black'; 195 th!.style.color = 'black'; 196 } // @ts-ignore 197 if (v.fileChoose) { 198 th.setAttribute('file', ''); 199 th.addEventListener('file-change', (e): void => { 200 // @ts-ignore 201 if (v.fileHandler && !th.disabled) { // @ts-ignore 202 v.fileHandler(e); 203 } 204 }); 205 } else { 206 th.removeAttribute('file'); 207 th.addEventListener('click', (e): void => { 208 // @ts-ignore 209 if (v.clickHandler && !th.disabled) { // @ts-ignore 210 v.clickHandler(v); 211 } 212 }); 213 } // @ts-ignore 214 if (v.disabled !== undefined) { // @ts-ignore 215 th.disabled = v.disabled; 216 } 217 secondGroup.appendChild(th); 218 }); 219 } 220 221 notChildren( 222 item: unknown, 223 group: LitMainMenuGroup, 224 groupName: LitMainMenuGroup, 225 groupDescribe: LitMainMenuGroup 226 ): void { 227 let th = new LitMainMenuItem(); // @ts-ignore 228 th.setAttribute('icon', item.icon || ''); // @ts-ignore 229 th.setAttribute('title', item.title || ''); 230 if (this.getAttribute('main_menu') === '1' && window.localStorage.getItem('Theme') === 'dark') { 231 groupName.style.color = 'white'; 232 groupDescribe.style.color = 'white'; 233 th!.style.color = 'white'; 234 } else { 235 groupName.style.color = 'black'; 236 groupDescribe.style.color = 'black'; 237 th!.style.color = 'black'; 238 } // @ts-ignore 239 if (item.fileChoose) { 240 th.setAttribute('file', ''); 241 th.addEventListener('file-change', (e) => { 242 // @ts-ignore 243 if (item.fileHandler && !th.disabled) { 244 // @ts-ignore 245 item.fileHandler(e); 246 } 247 }); 248 } else { 249 th.removeAttribute('file'); 250 th.addEventListener('click', (e) => { 251 // @ts-ignore 252 if (item.clickHandler && !th.disabled) { 253 // @ts-ignore 254 item.clickHandler(item); 255 } 256 }); 257 } 258 // @ts-ignore 259 if (item.multi) { 260 th.multi = true; 261 } 262 // @ts-ignore 263 if (item.disabled !== undefined) { 264 // @ts-ignore 265 th.disabled = item.disabled; 266 } 267 group?.appendChild(th); 268 } 269 270 initElements(): void { 271 let st: HTMLSlotElement | null | undefined = this.shadowRoot?.querySelector('#st'); 272 st?.addEventListener('slotchange', (e) => { 273 this.slotElements = st?.assignedElements(); 274 this.slotElements?.forEach((it) => { 275 it.querySelectorAll('lit-main-menu-item').forEach((cell) => {}); 276 }); 277 }); 278 let versionDiv: HTMLElement | null | undefined = this.shadowRoot?.querySelector<HTMLElement>('.version'); 279 //@ts-ignore 280 versionDiv!.innerText = window.version || ''; 281 } 282 283 initHtml(): string { 284 return ` 285 ${initHtmlStyle} 286 <div class="header" name="header"> 287 <img class="logo-img" src="img/logo.png"/> 288 <span class="logo-text"> 289 HiSmartPerf 290 </span> 291 <div class="menu-button"> 292 <lit-icon name="menu" size="20" color="var(blue,#4D4D4D)"></lit-icon> 293 </div> 294 </div> 295 <div class="menu-body" style="overflow: auto;overflow-x:hidden;height: 100%"> 296 <slot id="st" ></slot> 297 </div> 298 <div class="bottom"> 299 <div class="customColor"> 300 <lit-icon name="bg-colors" size="20" color="grey"></lit-icon> 301 </div> 302 <div class="version" style=""> 303 </div> 304 </div>`; 305 } 306} 307 308export interface MenuGroup { 309 title: string; 310 describe: string; 311 second: boolean; 312 collapsed: boolean; 313 children: MenuItem[]; 314 icon: string; 315} 316 317export interface MenuItem { 318 icon: string; 319 title: string; 320 fileModel?: string; 321 multi?: boolean; 322 disabled?: boolean; 323 fileChoose?: boolean; 324 clickHandler?: Function; 325 fileHandler?: Function; 326} 327