@kodaris/krubble-app-components 1.0.36 → 1.0.38

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.
@@ -58,971 +58,15 @@
58
58
 
59
59
  /**
60
60
  * @license
61
- * Copyright 2018 Google LLC
61
+ * Copyright 2017 Google LLC
62
62
  * SPDX-License-Identifier: BSD-3-Clause
63
- */const e$1=e$2(class extends i{constructor(t$1){if(super(t$1),t$1.type!==t.ATTRIBUTE||"class"!==t$1.name||t$1.strings?.length>2)throw Error("`classMap()` can only be used in the `class` attribute and must be the only part in the attribute.")}render(t){return " "+Object.keys(t).filter(s=>t[s]).join(" ")+" "}update(s,[i]){if(void 0===this.st){this.st=new Set,void 0!==s.strings&&(this.nt=new Set(s.strings.join(" ").split(/\s/).filter(t=>""!==t)));for(const t in i)i[t]&&!this.nt?.has(t)&&this.st.add(t);return this.render(i)}const r=s.element.classList;for(const t of this.st)t in i||(r.remove(t),this.st.delete(t));for(const t in i){const s=!!i[t];s===this.st.has(t)||this.nt?.has(t)||(s?(r.add(t),this.st.add(t)):(r.remove(t),this.st.delete(t)));}return E}});
63
+ */let e$1 = class e extends i{constructor(i){if(super(i),this.it=A,i.type!==t.CHILD)throw Error(this.constructor.directiveName+"() can only be used in child bindings")}render(r){if(r===A||null==r)return this._t=void 0,this.it=r;if(r===E)return r;if("string"!=typeof r)throw Error(this.constructor.directiveName+"() called with a non-string value");if(r===this.it)return this._t;this.it=r;const s=[r];return s.raw=s,this._t={_$litType$:this.constructor.resultType,strings:s,values:[]}}};e$1.directiveName="unsafeHTML",e$1.resultType=1;const o=e$2(e$1);
64
64
 
65
65
  /**
66
66
  * @license
67
- * Copyright 2017 Google LLC
67
+ * Copyright 2018 Google LLC
68
68
  * SPDX-License-Identifier: BSD-3-Clause
69
- */class e extends i{constructor(i){if(super(i),this.it=A,i.type!==t.CHILD)throw Error(this.constructor.directiveName+"() can only be used in child bindings")}render(r){if(r===A||null==r)return this._t=void 0,this.it=r;if(r===E)return r;if("string"!=typeof r)throw Error(this.constructor.directiveName+"() called with a non-string value");if(r===this.it)return this._t;this.it=r;const s=[r];return s.raw=s,this._t={_$litType$:this.constructor.resultType,strings:s,values:[]}}}e.directiveName="unsafeHTML",e.resultType=1;const o=e$2(e);
70
-
71
- var __decorate$5 = (undefined && undefined.__decorate) || function (decorators, target, key, desc) {
72
- var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
73
- if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
74
- else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
75
- return c > 3 && r && Object.defineProperty(target, key, r), r;
76
- };
77
- /**
78
- * Global shell component with app bar for app switching.
79
- *
80
- * The shell provides a horizontal app bar across the top of the viewport containing:
81
- * - Logo/home link on the left
82
- * - App switcher icons in the middle
83
- * - User avatar/menu on the right
84
- *
85
- * This allows individual apps (using kr-scaffold) to utilize the full width
86
- * of the browser window while maintaining consistent global navigation.
87
- *
88
- * @slot - The main content (typically kr-scaffold with the app)
89
- *
90
- * @property {string} logo - URL for the logo image
91
- * @property {KRApp[]} apps - Available applications for the switcher
92
- * @property {string} activeAppId - ID of the currently active app
93
- * @property {KRShellUser} user - User profile data
94
- * @property {KRShellMenuItem[]} menuItems - Custom menu items for user menu
95
- *
96
- * @fires app-click - When an app icon is clicked. Detail: { app: KRApp }
97
- * @fires menu-item-click - When a menu item is clicked. Detail: { item: KRShellMenuItem }
98
- * @fires logout - When logout is clicked
99
- */
100
- exports.Shell = class KRShell extends i$1 {
101
- constructor() {
102
- super(...arguments);
103
- this.logo = 'https://s3.amazonaws.com/kodariscom/kodariscom/content/website/kodaris-logo-icon-light-53.png';
104
- this.apps = [];
105
- this.activeAppId = '';
106
- this.user = null;
107
- this.menuItems = [];
108
- this.isUserMenuOpen = false;
109
- this.isAppsMenuOpen = false;
110
- this.pendingRequests = 0;
111
- this.originalFetch = null;
112
- this.originalXhrOpen = null;
113
- // Default icons
114
- this.defaultLogoutIcon = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"><path d="M17 7l-1.41 1.41L18.17 11H8v2h10.17l-2.58 2.58L17 17l5-5zM4 5h8V3H4c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h8v-2H4V5z"/></svg>';
115
- this.appsGridIcon = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"><path d="M4 8h4V4H4v4zm6 12h4v-4h-4v4zm-6 0h4v-4H4v4zm0-6h4v-4H4v4zm6 0h4v-4h-4v4zm6-10v4h4V4h-4zm-6 4h4V4h-4v4zm6 6h4v-4h-4v4zm0 6h4v-4h-4v4z"/></svg>';
116
- this.closeIcon = '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"><path d="M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"/></svg>';
117
- }
118
- connectedCallback() {
119
- super.connectedCallback();
120
- this.installFetchInterceptor();
121
- // Hide the default Chatlio close button (we use our own custom button)
122
- if (!document.getElementById('chatlio-widget-styles')) {
123
- const style = document.createElement('style');
124
- style.id = 'chatlio-widget-styles';
125
- style.textContent = `
126
- .chatlio-title-bar {
127
- display: none !important;
128
- }
129
-
130
- .chatlio-widget-body {
131
- bottom: 36px !important;
132
- }
133
- `;
134
- document.head.appendChild(style);
135
- }
136
- }
137
- disconnectedCallback() {
138
- super.disconnectedCallback();
139
- this.uninstallFetchInterceptor();
140
- }
141
- /**
142
- * Installs global interceptors for fetch and XMLHttpRequest to track pending HTTP requests.
143
- * Updates `pendingRequests` state when requests start/complete.
144
- */
145
- installFetchInterceptor() {
146
- if (this.originalFetch)
147
- return;
148
- const shell = this;
149
- // Intercept fetch
150
- this.originalFetch = window.fetch.bind(window);
151
- const originalFetch = this.originalFetch;
152
- window.fetch = function (...args) {
153
- shell.pendingRequests++;
154
- return originalFetch(...args).finally(() => {
155
- shell.pendingRequests--;
156
- });
157
- };
158
- // Intercept XMLHttpRequest
159
- this.originalXhrOpen = XMLHttpRequest.prototype.open;
160
- const originalXhrOpen = this.originalXhrOpen;
161
- XMLHttpRequest.prototype.open = function (method, url, async = true, username, password) {
162
- shell.pendingRequests++;
163
- this.addEventListener('loadend', () => {
164
- shell.pendingRequests--;
165
- }, { once: true });
166
- return originalXhrOpen.call(this, method, url, async, username, password);
167
- };
168
- }
169
- /**
170
- * Restores the original fetch and XMLHttpRequest functions.
171
- */
172
- uninstallFetchInterceptor() {
173
- if (this.originalFetch) {
174
- window.fetch = this.originalFetch;
175
- this.originalFetch = null;
176
- }
177
- if (this.originalXhrOpen) {
178
- XMLHttpRequest.prototype.open = this.originalXhrOpen;
179
- this.originalXhrOpen = null;
180
- }
181
- }
182
- handleLogoClick() {
183
- this.dispatchEvent(new CustomEvent('logo-click', {
184
- bubbles: true,
185
- composed: true,
186
- }));
187
- }
188
- toggleUserMenu() {
189
- this.isUserMenuOpen = !this.isUserMenuOpen;
190
- this.isAppsMenuOpen = false;
191
- }
192
- closeUserMenu() {
193
- this.isUserMenuOpen = false;
194
- }
195
- toggleAppsMenu() {
196
- this.isAppsMenuOpen = !this.isAppsMenuOpen;
197
- this.isUserMenuOpen = false;
198
- }
199
- closeAppsMenu() {
200
- this.isAppsMenuOpen = false;
201
- }
202
- handleMenuItemClick(item) {
203
- this.closeUserMenu();
204
- this.dispatchEvent(new CustomEvent('menu-item-click', {
205
- detail: { item },
206
- bubbles: true,
207
- composed: true,
208
- }));
209
- }
210
- handleLogout() {
211
- this.closeUserMenu();
212
- this.dispatchEvent(new CustomEvent('logout', {
213
- bubbles: true,
214
- composed: true,
215
- }));
216
- }
217
- handleChatClick() {
218
- // Toggle Chatlio widget
219
- if (typeof window._chatlio !== 'undefined') {
220
- window._chatlio.showOrHide();
221
- }
222
- }
223
- renderAppsMenu() {
224
- return b `
225
- <div class="appbar-apps">
226
- ${this.isAppsMenuOpen ? b `
227
- <div class="menu-backdrop" @click=${this.closeAppsMenu}></div>
228
- ` : A}
229
-
230
- <button
231
- class=${e$1({
232
- 'appbar-apps-btn': true,
233
- 'appbar-apps-btn--open': this.isAppsMenuOpen,
234
- })}
235
- @click=${this.toggleAppsMenu}
236
- >
237
- <span class="appbar-apps-btn__icon">${o(this.appsGridIcon)}</span>
238
- </button>
239
-
240
- <div class=${e$1({
241
- 'appbar-apps-menu': true,
242
- 'appbar-apps-menu--open': this.isAppsMenuOpen,
243
- })}>
244
- <div class="appbar-apps-menu__header">
245
- <h2 class="appbar-apps-menu__title">Applications</h2>
246
- <button class="appbar-apps-menu__close" @click=${this.closeAppsMenu}>
247
- ${o(this.closeIcon)}
248
- </button>
249
- </div>
250
- <div class="appbar-apps-menu__content">
251
- <div class="appbar-apps-menu__list">
252
- ${this.apps.map((app) => b `
253
- <a
254
- class="appbar-apps-menu__item"
255
- href=${app.url}
256
- @click=${(e) => {
257
- this.closeAppsMenu();
258
- const event = new CustomEvent('app-click', {
259
- detail: { app },
260
- bubbles: true,
261
- composed: true,
262
- cancelable: true,
263
- });
264
- this.dispatchEvent(event);
265
- if (event.defaultPrevented) {
266
- e.preventDefault();
267
- }
268
- }}
269
- >
270
- ${app.name}
271
- </a>
272
- `)}
273
- </div>
274
- </div>
275
- </div>
276
- </div>
277
- `;
278
- }
279
- renderUserMenu() {
280
- if (!this.user)
281
- return A;
282
- const initials = this.user.name
283
- .split(' ')
284
- .map((part) => part[0])
285
- .join('')
286
- .toUpperCase()
287
- .slice(0, 2);
288
- return b `
289
- <div class="appbar-user">
290
- ${this.isUserMenuOpen ? b `
291
- <div class="menu-backdrop" @click=${this.closeUserMenu}></div>
292
- ` : A}
293
-
294
- <div
295
- class="appbar-user__avatar"
296
- @click=${this.toggleUserMenu}
297
- >
298
- ${this.user.avatar
299
- ? b `<img src=${this.user.avatar} alt=${this.user.name} />`
300
- : initials}
301
- </div>
302
-
303
- <div class=${e$1({
304
- 'appbar-user__menu': true,
305
- 'appbar-user__menu--open': this.isUserMenuOpen,
306
- })}>
307
- <div class="appbar-user__header">
308
- <p class="appbar-user__name">${this.user.name}</p>
309
- ${this.user.email ? b `
310
- <p class="appbar-user__email">${this.user.email}</p>
311
- ` : A}
312
- </div>
313
-
314
- ${this.menuItems.map((item) => item.divider
315
- ? b `<div class="appbar-user__menu-divider"></div>`
316
- : b `
317
- <button
318
- class="appbar-user__menu-item"
319
- @click=${() => this.handleMenuItemClick(item)}
320
- >
321
- ${item.icon ? b `
322
- <span class="appbar-user__menu-item__icon">${o(item.icon)}</span>
323
- ` : A}
324
- ${item.label}
325
- </button>
326
- `)}
327
-
328
- ${this.menuItems.length > 0 ? b `
329
- <div class="appbar-user__menu-divider"></div>
330
- ` : A}
331
-
332
- <button
333
- class="appbar-user__menu-item appbar-user__menu-item--danger"
334
- @click=${this.handleLogout}
335
- >
336
- <span class="appbar-user__menu-item__icon">${o(this.defaultLogoutIcon)}</span>
337
- Sign Out
338
- </button>
339
- </div>
340
- </div>
341
- `;
342
- }
343
- render() {
344
- return b `
345
- <div class=${e$1({
346
- 'progress': true,
347
- 'progress--loading': this.pendingRequests > 0,
348
- })}>
349
- <div class="progress__track"></div>
350
- <div class="progress__bar progress__bar--primary">
351
- <span class="progress__bar-inner"></span>
352
- </div>
353
- <div class="progress__bar progress__bar--secondary">
354
- <span class="progress__bar-inner"></span>
355
- </div>
356
- </div>
357
-
358
- <header class="appbar">
359
- <!-- Logo -->
360
- ${this.logo ? b `
361
- <div class="appbar-logo" @click=${this.handleLogoClick}>
362
- <img src=${this.logo} alt="Home" />
363
- </div>
364
- <div class="appbar-divider"></div>
365
- ` : A}
366
-
367
- <!-- App Switcher -->
368
- ${this.renderAppsMenu()}
369
-
370
- <div class="appbar-spacer"></div>
371
-
372
- <!-- User -->
373
- ${this.renderUserMenu()}
374
- </header>
375
-
376
- <!-- <div class="subbar">-->
377
- <!-- <nav class="breadcrumbs">-->
378
- <!-- <a href="#">Home</a>-->
379
- <!-- <span class="breadcrumbs__separator">/</span>-->
380
- <!-- <a href="#">Companies</a>-->
381
- <!-- <span class="breadcrumbs__separator">/</span>-->
382
- <!-- <span>Acme Corp</span>-->
383
- <!-- </nav>-->
384
- <!-- </div>-->
385
-
386
- <main class="main">
387
- <slot></slot>
388
- </main>
389
-
390
- <footer class="footer">
391
- <div class="footer-content">
392
- <div class="footer-info">
393
- <span>© ${new Date().getFullYear()} Kodaris. All Rights Reserved.</span>
394
- </div>
395
- <a class="footer-link" target="_blank" href="https://www.kodaris.com/content/privacy-policy">Privacy</a>
396
- <a class="footer-link" target="_blank" href="https://www.kodaris.com/content/terms-use">Terms</a>
397
- <button class="footer-chat" data-chatlio-widget-button @click=${this.handleChatClick}>
398
- <span class="footer-chat__icon">
399
- <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="lucide lucide-messages-square-icon lucide-messages-square">
400
- <path d="M16 10a2 2 0 0 1-2 2H6.828a2 2 0 0 0-1.414.586l-2.202 2.202A.71.71 0 0 1 2 14.286V4a2 2 0 0 1 2-2h10a2 2 0 0 1 2 2z"/><path d="M20 9a2 2 0 0 1 2 2v10.286a.71.71 0 0 1-1.212.502l-2.202-2.202A2 2 0 0 0 17.172 19H10a2 2 0 0 1-2-2v-1"/>
401
- </svg>
402
- </span>
403
- Chat with us
404
- </button>
405
- </div>
406
- </footer>
407
- `;
408
- }
409
- };
410
- exports.Shell.styles = i$4 `
411
- :host {
412
- display: flex;
413
- flex-direction: column;
414
- height: 100vh;
415
- width: 100vw;
416
- --kr-shell-bar-height: 48px;
417
- --kr-shell-bar-bg: #10172a; /* matches scaffold nav-bg */
418
- /* --kr-shell-bar-bg: #0a0f1a; */ /* original darker bg */
419
- --kr-shell-bar-border: rgba(255, 255, 255, 0.08);
420
- --kr-shell-icon-size: 36px;
421
- --kr-shell-icon-color: rgba(255, 255, 255, 0.7);
422
- --kr-shell-icon-color-hover: rgba(255, 255, 255, 1);
423
- --kr-shell-icon-color-active: #beea4e;
424
- --kr-shell-icon-bg-hover: rgba(255, 255, 255, 0.08);
425
- --kr-shell-icon-bg-active: rgba(190, 234, 78, 0.15);
426
- --kr-shell-tooltip-bg: #1a2332;
427
- --kr-shell-tooltip-color: #ffffff;
428
- --kr-shell-menu-bg: #1a2332;
429
- --kr-shell-menu-border: rgba(255, 255, 255, 0.1);
430
- --kr-shell-menu-hover: rgba(255, 255, 255, 0.08);
431
- }
432
-
433
- *,
434
- *::before,
435
- *::after {
436
- box-sizing: border-box;
437
- }
438
-
439
- /* App Bar */
440
- .appbar {
441
- height: var(--kr-shell-bar-height);
442
- background: var(--kr-shell-bar-bg);
443
- border-bottom: 1px solid var(--kr-shell-bar-border);
444
- display: flex;
445
- align-items: center;
446
- padding: 0 16px;
447
- flex-shrink: 0;
448
- z-index: 100;
449
- }
450
-
451
- /* Logo */
452
- .appbar-logo {
453
- cursor: pointer;
454
- margin-right: 8px;
455
- }
456
-
457
- .appbar-logo img {
458
- display: block;
459
- max-width: 24px;
460
- max-height: 24px;
461
- object-fit: contain;
462
- }
463
-
464
- /* Divider */
465
- .appbar-divider {
466
- width: 1px;
467
- height: 24px;
468
- background: #ffffff4f;
469
- margin: 0 10px;
470
- }
471
-
472
- /* Apps Button */
473
- .appbar-apps {
474
- position: relative;
475
- }
476
-
477
- .appbar-apps-btn {
478
- width: var(--kr-shell-icon-size);
479
- height: var(--kr-shell-icon-size);
480
- display: flex;
481
- align-items: center;
482
- justify-content: center;
483
- border-radius: 6px;
484
- cursor: pointer;
485
- color: var(--kr-shell-icon-color);
486
- background: transparent;
487
- border: none;
488
- padding: 0;
489
- transition: all 0.15s ease;
490
- }
491
-
492
- .appbar-apps-btn:hover {
493
- color: var(--kr-shell-icon-color-hover);
494
- background: var(--kr-shell-icon-bg-hover);
495
- }
496
-
497
- .appbar-apps-btn--open {
498
- color: var(--kr-shell-icon-color-hover);
499
- background: var(--kr-shell-icon-bg-hover);
500
- }
501
-
502
- .appbar-apps-btn__icon {
503
- width: 24px;
504
- height: 24px;
505
- display: flex;
506
- align-items: center;
507
- justify-content: center;
508
- color: #ffffff;
509
- }
510
-
511
- .appbar-apps-btn__icon svg {
512
- width: 100%;
513
- height: 100%;
514
- fill: currentColor;
515
- }
516
-
517
- /* Apps Megamenu */
518
- .appbar-apps-menu {
519
- position: absolute;
520
- left: 0;
521
- top: 100%;
522
- margin-top: 6px;
523
- min-width: 320px;
524
- min-height: 90vh;
525
- max-height: calc(100vh - var(--kr-shell-bar-height));
526
- background: #10172a;
527
- border: 1px solid var(--kr-shell-menu-border);
528
- border-top: none;
529
- border-radius: 0 0 8px 8px;
530
- box-shadow: 0 8px 24px rgba(0, 0, 0, 0.4);
531
- z-index: 1000;
532
- opacity: 0;
533
- visibility: hidden;
534
- transform: translateY(-10px);
535
- transition: all 0.15s ease;
536
- overflow-y: auto;
537
- }
538
-
539
- .appbar-apps-menu--open {
540
- opacity: 1;
541
- visibility: visible;
542
- transform: translateY(0);
543
- }
544
-
545
- .appbar-apps-menu__header {
546
- display: flex;
547
- align-items: center;
548
- justify-content: space-between;
549
- padding: 16px 16px 16px 24px;
550
- border-bottom: 1px solid var(--kr-shell-menu-border);
551
- }
552
-
553
- .appbar-apps-menu__title {
554
- font-size: 16px;
555
- font-weight: 500;
556
- color: #ffffff;
557
- margin: 0;
558
- }
559
-
560
- .appbar-apps-menu__close {
561
- width: 32px;
562
- height: 32px;
563
- display: flex;
564
- align-items: center;
565
- justify-content: center;
566
- background: none;
567
- border: none;
568
- color: rgba(255, 255, 255, 0.6);
569
- cursor: pointer;
570
- border-radius: 6px;
571
- transition: all 0.15s ease;
572
- }
573
-
574
- .appbar-apps-menu__close:hover {
575
- background: var(--kr-shell-menu-hover);
576
- color: #ffffff;
577
- }
578
-
579
- .appbar-apps-menu__close svg {
580
- width: 24px;
581
- height: 24px;
582
- fill: #ffffff;
583
- }
584
-
585
- .appbar-apps-menu__content {
586
- padding: 16px 8px;
587
- }
588
-
589
- .appbar-apps-menu__list {
590
- display: flex;
591
- flex-direction: column;
592
- gap: 2px;
593
- max-width: 320px;
594
- }
595
-
596
- .appbar-apps-menu__item {
597
- display: block;
598
- width: 100%;
599
- padding: 12px 16px;
600
- background: none;
601
- border: none;
602
- color: #ffffff;
603
- font-size: 14px;
604
- font-family: inherit;
605
- text-align: left;
606
- text-decoration: none;
607
- cursor: pointer;
608
- border-radius: 6px;
609
- transition: all 0.15s ease;
610
- }
611
-
612
- .appbar-apps-menu__item:hover {
613
- background: var(--kr-shell-menu-hover);
614
- }
615
-
616
- .appbar-apps-menu__item--active,
617
- .appbar-apps-menu__item--active:hover {
618
- color: var(--kr-shell-icon-color-active);
619
- }
620
-
621
- /* Spacer to push user to the right */
622
- .appbar-spacer {
623
- flex: 1;
624
- }
625
-
626
- /* User Section */
627
- .appbar-user {
628
- position: relative;
629
- margin-left: 8px;
630
- }
631
-
632
- .appbar-user__avatar {
633
- width: 32px;
634
- height: 32px;
635
- border-radius: 50%;
636
- background: #beea4e;
637
- color: #0a0f1a;
638
- display: flex;
639
- align-items: center;
640
- justify-content: center;
641
- font-size: 12px;
642
- font-weight: 600;
643
- cursor: pointer;
644
- overflow: hidden;
645
- border: 2px solid transparent;
646
- transition: border-color 0.15s ease;
647
- }
648
-
649
- .appbar-user__avatar:hover {
650
- border-color: rgba(255, 255, 255, 0.3);
651
- }
652
-
653
- .appbar-user__avatar img {
654
- width: 100%;
655
- height: 100%;
656
- object-fit: cover;
657
- }
658
-
659
- /* User Menu */
660
- .appbar-user__menu {
661
- position: absolute;
662
- right: 0;
663
- top: calc(100% + 8px);
664
- min-width: 200px;
665
- background: var(--kr-shell-menu-bg);
666
- border: 1px solid var(--kr-shell-menu-border);
667
- border-radius: 8px;
668
- padding: 8px;
669
- box-shadow: 0 8px 24px rgba(0, 0, 0, 0.4);
670
- z-index: 1000;
671
- opacity: 0;
672
- visibility: hidden;
673
- transform: translateY(-8px);
674
- transition: all 0.15s ease;
675
- }
676
-
677
- .appbar-user__menu--open {
678
- opacity: 1;
679
- visibility: visible;
680
- transform: translateY(0);
681
- }
682
-
683
- .appbar-user__header {
684
- padding: 8px 12px 12px;
685
- border-bottom: 1px solid var(--kr-shell-menu-border);
686
- margin-bottom: 8px;
687
- }
688
-
689
- .appbar-user__name {
690
- font-size: 14px;
691
- font-weight: 600;
692
- color: #ffffff;
693
- margin: 0 0 2px;
694
- }
695
-
696
- .appbar-user__email {
697
- font-size: 12px;
698
- color: rgba(255, 255, 255, 0.6);
699
- margin: 0;
700
- }
701
-
702
- .appbar-user__menu-item {
703
- display: flex;
704
- align-items: center;
705
- gap: 10px;
706
- width: 100%;
707
- padding: 10px 12px;
708
- background: none;
709
- border: none;
710
- color: rgba(255, 255, 255, 0.8);
711
- font-size: 13px;
712
- font-family: inherit;
713
- text-align: left;
714
- cursor: pointer;
715
- border-radius: 6px;
716
- transition: all 0.15s ease;
717
- }
718
-
719
- .appbar-user__menu-item:hover {
720
- background: var(--kr-shell-menu-hover);
721
- color: #ffffff;
722
- }
723
-
724
- .appbar-user__menu-item--danger {
725
- color: #f87171;
726
- }
727
-
728
- .appbar-user__menu-item--danger:hover {
729
- background: rgba(248, 113, 113, 0.1);
730
- color: #f87171;
731
- }
732
-
733
- .appbar-user__menu-item__icon {
734
- width: 16px;
735
- height: 16px;
736
- display: flex;
737
- align-items: center;
738
- justify-content: center;
739
- flex-shrink: 0;
740
- }
741
-
742
- .appbar-user__menu-item__icon svg {
743
- width: 100%;
744
- height: 100%;
745
- fill: currentColor;
746
- }
747
-
748
- .appbar-user__menu-divider {
749
- height: 1px;
750
- background: var(--kr-shell-menu-border);
751
- margin: 8px 0;
752
- }
753
-
754
- /* Secondary App Bar */
755
- .subbar {
756
- height: 30px;
757
- background: #364365;
758
- border-bottom: 1px solid rgba(255, 255, 255, 0.08);
759
- display: flex;
760
- align-items: center;
761
- padding: 0 16px;
762
- flex-shrink: 0;
763
- }
764
-
765
- .breadcrumbs {
766
- display: flex;
767
- align-items: center;
768
- gap: 8px;
769
- font-size: 12px;
770
- color: #ffffff;
771
- }
772
-
773
- .breadcrumbs a {
774
- color: #ffffff;
775
- text-decoration: none;
776
- }
777
-
778
- .breadcrumbs a:hover {
779
- text-decoration: underline;
780
- }
781
-
782
- .breadcrumbs__separator {
783
- color: #ffffff;
784
- }
785
-
786
- /* Main Content */
787
- .main {
788
- flex: 1;
789
- min-height: 0;
790
- display: flex;
791
- flex-direction: column;
792
- overflow: hidden;
793
- position: relative;
794
- }
795
-
796
- /* Click outside overlay */
797
- .menu-backdrop {
798
- position: fixed;
799
- inset: 0;
800
- z-index: 999;
801
- }
802
-
803
- /* Progress bar */
804
- .progress {
805
- position: fixed;
806
- top: 0;
807
- left: 0;
808
- right: 0;
809
- height: 4px;
810
- overflow-x: hidden;
811
- z-index: 1000;
812
- display: none;
813
- }
814
-
815
- .progress--loading {
816
- display: block;
817
- }
818
-
819
- .progress__track {
820
- position: absolute;
821
- top: 0;
822
- bottom: 0;
823
- width: 100%;
824
- background: rgb(190 234 78 / 50%); // rgba(190, 234, 78, 0.3);
825
- }
826
-
827
- .progress__bar {
828
- position: absolute;
829
- top: 0;
830
- bottom: 0;
831
- width: 100%;
832
- transform-origin: left center;
833
- }
834
-
835
- .progress__bar-inner {
836
- display: inline-block;
837
- position: absolute;
838
- width: 100%;
839
- height: 100%;
840
- background: #beea4e;
841
- }
842
-
843
- .progress__bar--primary {
844
- left: -145.166611%;
845
- }
846
-
847
- .progress--loading .progress__bar--primary {
848
- animation: progress-primary-translate 2s infinite linear;
849
- }
850
-
851
- .progress--loading .progress__bar--primary .progress__bar-inner {
852
- animation: progress-primary-scale 2s infinite linear;
853
- }
854
-
855
- .progress__bar--secondary {
856
- left: -54.888891%;
857
- }
858
-
859
- .progress--loading .progress__bar--secondary {
860
- animation: progress-secondary-translate 2s infinite linear;
861
- }
862
-
863
- .progress--loading .progress__bar--secondary .progress__bar-inner {
864
- animation: progress-secondary-scale 2s infinite linear;
865
- }
866
-
867
- @keyframes progress-primary-translate {
868
- 0% {
869
- transform: translateX(0);
870
- }
871
- 20% {
872
- animation-timing-function: cubic-bezier(0.5, 0, 0.701732, 0.495819);
873
- transform: translateX(0);
874
- }
875
- 59.15% {
876
- animation-timing-function: cubic-bezier(0.302435, 0.381352, 0.55, 0.956352);
877
- transform: translateX(83.67142%);
878
- }
879
- 100% {
880
- transform: translateX(200.611057%);
881
- }
882
- }
883
-
884
- @keyframes progress-primary-scale {
885
- 0% {
886
- transform: scaleX(0.08);
887
- }
888
- 36.65% {
889
- animation-timing-function: cubic-bezier(0.334731, 0.12482, 0.785844, 1);
890
- transform: scaleX(0.08);
891
- }
892
- 69.15% {
893
- animation-timing-function: cubic-bezier(0.06, 0.11, 0.6, 1);
894
- transform: scaleX(0.661479);
895
- }
896
- 100% {
897
- transform: scaleX(0.08);
898
- }
899
- }
900
-
901
- @keyframes progress-secondary-translate {
902
- 0% {
903
- animation-timing-function: cubic-bezier(0.15, 0, 0.515058, 0.409685);
904
- transform: translateX(0);
905
- }
906
- 25% {
907
- animation-timing-function: cubic-bezier(0.31033, 0.284058, 0.8, 0.733712);
908
- transform: translateX(37.651913%);
909
- }
910
- 48.35% {
911
- animation-timing-function: cubic-bezier(0.4, 0.627035, 0.6, 0.902026);
912
- transform: translateX(84.386165%);
913
- }
914
- 100% {
915
- transform: translateX(160.277782%);
916
- }
917
- }
918
-
919
- @keyframes progress-secondary-scale {
920
- 0% {
921
- animation-timing-function: cubic-bezier(0.205028, 0.057051, 0.57661, 0.453971);
922
- transform: scaleX(0.08);
923
- }
924
- 19.15% {
925
- animation-timing-function: cubic-bezier(0.152313, 0.196432, 0.648374, 1.004315);
926
- transform: scaleX(0.457104);
927
- }
928
- 44.15% {
929
- animation-timing-function: cubic-bezier(0.257759, -0.003163, 0.211762, 1.38179);
930
- transform: scaleX(0.72796);
931
- }
932
- 100% {
933
- transform: scaleX(0.08);
934
- }
935
- }
936
-
937
- .footer {
938
- background: var(--kr-shell-bar-bg);
939
- border-top: 1px solid var(--kr-shell-bar-border);
940
- padding: 8px 16px;
941
- flex-shrink: 0;
942
- }
943
-
944
- .footer-content {
945
- display: flex;
946
- justify-content: flex-end;
947
- align-items: center;
948
- gap: 36px;
949
- }
950
-
951
- .footer-info {
952
- font-size: 12px;
953
- color: rgba(255, 255, 255, 0.7);
954
- }
955
-
956
- .footer-link {
957
- color: rgba(255, 255, 255, 0.7);
958
- text-decoration: none;
959
- font-size: 12px;
960
- }
961
-
962
- .footer-link:hover {
963
- color: #ffffff;
964
- text-decoration: underline;
965
- }
966
-
967
- .footer-chat {
968
- display: flex;
969
- align-items: center;
970
- gap: 6px;
971
- font-size: 14px;
972
- color: #beea4e;
973
- cursor: pointer;
974
- background: none;
975
- border: none;
976
- border-radius: 4px;
977
- font-family: inherit;
978
- transition: background 0.15s ease;
979
- }
980
-
981
- .footer-chat:hover {
982
- background: rgba(255, 255, 255, 0.08);
983
- }
984
-
985
- .footer-chat__icon {
986
- width: 16px;
987
- height: 16px;
988
- display: flex;
989
- align-items: center;
990
- justify-content: center;
991
- }
992
-
993
- .footer-chat__icon svg {
994
- width: 100%;
995
- height: 100%;
996
- stroke: currentColor;
997
- }
998
- `;
999
- __decorate$5([
1000
- n({ type: String })
1001
- ], exports.Shell.prototype, "logo", void 0);
1002
- __decorate$5([
1003
- n({ type: Array })
1004
- ], exports.Shell.prototype, "apps", void 0);
1005
- __decorate$5([
1006
- n({ type: String, attribute: 'active-app-id' })
1007
- ], exports.Shell.prototype, "activeAppId", void 0);
1008
- __decorate$5([
1009
- n({ type: Object })
1010
- ], exports.Shell.prototype, "user", void 0);
1011
- __decorate$5([
1012
- n({ type: Array, attribute: 'menu-items' })
1013
- ], exports.Shell.prototype, "menuItems", void 0);
1014
- __decorate$5([
1015
- r()
1016
- ], exports.Shell.prototype, "isUserMenuOpen", void 0);
1017
- __decorate$5([
1018
- r()
1019
- ], exports.Shell.prototype, "isAppsMenuOpen", void 0);
1020
- __decorate$5([
1021
- r()
1022
- ], exports.Shell.prototype, "pendingRequests", void 0);
1023
- exports.Shell = __decorate$5([
1024
- t$1('kr-shell')
1025
- ], exports.Shell);
69
+ */const e=e$2(class extends i{constructor(t$1){if(super(t$1),t$1.type!==t.ATTRIBUTE||"class"!==t$1.name||t$1.strings?.length>2)throw Error("`classMap()` can only be used in the `class` attribute and must be the only part in the attribute.")}render(t){return " "+Object.keys(t).filter(s=>t[s]).join(" ")+" "}update(s,[i]){if(void 0===this.st){this.st=new Set,void 0!==s.strings&&(this.nt=new Set(s.strings.join(" ").split(/\s/).filter(t=>""!==t)));for(const t in i)i[t]&&!this.nt?.has(t)&&this.st.add(t);return this.render(i)}const r=s.element.classList;for(const t of this.st)t in i||(r.remove(t),this.st.delete(t));for(const t in i){const s=!!i[t];s===this.st.has(t)||this.nt?.has(t)||(s?(r.add(t),this.st.add(t)):(r.remove(t),this.st.delete(t)));}return E}});
1026
70
 
1027
71
  var __decorate$4 = (undefined && undefined.__decorate) || function (decorators, target, key, desc) {
1028
72
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
@@ -2218,7 +1262,7 @@
2218
1262
  const children = this.getNavItemChildren(item.id);
2219
1263
  return b `
2220
1264
  <button
2221
- class=${e$1({
1265
+ class=${e({
2222
1266
  'nav-item': true,
2223
1267
  'nav-item--expanded': this.navItemsExpanded.has(item.id),
2224
1268
  'nav-item--hidden': this.isEditing && item.active === false,
@@ -2243,7 +1287,7 @@
2243
1287
  <path d="M6 9l6 6 6-6" stroke-linecap="round" stroke-linejoin="round" />
2244
1288
  </svg>
2245
1289
  </button>
2246
- <div class=${e$1({
1290
+ <div class=${e({
2247
1291
  'nav-group': true,
2248
1292
  'nav-group--expanded': this.navItemsExpanded.has(item.id),
2249
1293
  })}>
@@ -2253,7 +1297,7 @@
2253
1297
  }
2254
1298
  return b `
2255
1299
  <a
2256
- class=${e$1({
1300
+ class=${e({
2257
1301
  'nav-item': true,
2258
1302
  'nav-item--active': this.activeNavItemId === item.id,
2259
1303
  'nav-item--hidden': this.isEditing && item.active === false,
@@ -2278,7 +1322,7 @@
2278
1322
  // Use unfiltered count to determine if search should show (so it doesn't disappear while typing)
2279
1323
  const totalTopLevelItems = this.getComputedNav().filter(item => item.parentId === null).length;
2280
1324
  return b `
2281
- <div class=${e$1({
1325
+ <div class=${e({
2282
1326
  'progress': true,
2283
1327
  'progress--loading': this.pendingRequests > 0,
2284
1328
  })}>
@@ -2298,7 +1342,7 @@
2298
1342
  ` : A}
2299
1343
 
2300
1344
  <div class="wrapper">
2301
- <nav class=${e$1({
1345
+ <nav class=${e({
2302
1346
  'nav': true,
2303
1347
  'nav--scrolled': this.isNavScrolled,
2304
1348
  'nav--opened': !this.subbar || this.isNavOpened,
@@ -3565,7 +2609,7 @@
3565
2609
  return b `
3566
2610
  ${index > 0 ? b `<span class="breadcrumb-separator">/</span>` : ''}
3567
2611
  <a
3568
- class=${e$1({ 'breadcrumb': true, 'breadcrumb--current': isCurrent })}
2612
+ class=${e({ 'breadcrumb': true, 'breadcrumb--current': isCurrent })}
3569
2613
  href=${this.resolveUrl(crumb)}
3570
2614
  @click=${(e) => this._handleBreadcrumbClick(e, crumb, isCurrent)}
3571
2615
  >${crumb.label}</a>