@triptease/tt-navbar 0.0.96 → 0.1.1

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.
Files changed (77) hide show
  1. package/CHANGELOG.md +20 -0
  2. package/dist/cjs/package.json +3 -0
  3. package/dist/cjs/src/Config.js +10 -0
  4. package/dist/cjs/src/Config.js.map +1 -0
  5. package/dist/cjs/src/Routes.js +8 -0
  6. package/dist/cjs/src/Routes.js.map +1 -0
  7. package/dist/cjs/src/TtNavbar.js +426 -0
  8. package/dist/cjs/src/TtNavbar.js.map +1 -0
  9. package/dist/cjs/src/getInitialNavbarState.js +21 -0
  10. package/dist/cjs/src/getInitialNavbarState.js.map +1 -0
  11. package/dist/cjs/src/index.js +12 -0
  12. package/dist/cjs/src/index.js.map +1 -0
  13. package/dist/cjs/src/styles.js +331 -0
  14. package/dist/cjs/src/styles.js.map +1 -0
  15. package/dist/cjs/src/triptease-logo.js +13 -0
  16. package/dist/cjs/src/triptease-logo.js.map +1 -0
  17. package/dist/cjs/src/tt-navbar.js +9 -0
  18. package/dist/cjs/src/tt-navbar.js.map +1 -0
  19. package/dist/cjs/src/urlMappings.js +36 -0
  20. package/dist/cjs/src/urlMappings.js.map +1 -0
  21. package/dist/esm/src/Config.js.map +1 -0
  22. package/dist/esm/src/Routes.js.map +1 -0
  23. package/dist/esm/src/TtNavbar.js.map +1 -0
  24. package/dist/esm/src/getInitialNavbarState.js.map +1 -0
  25. package/dist/esm/src/index.js.map +1 -0
  26. package/dist/esm/src/styles.js.map +1 -0
  27. package/dist/esm/src/triptease-logo.js.map +1 -0
  28. package/dist/esm/src/tt-navbar.js.map +1 -0
  29. package/dist/esm/src/urlMappings.js.map +1 -0
  30. package/dist/esm/test/tt-navbar.test.js.map +1 -0
  31. package/dist/web/Config.js +1 -1
  32. package/dist/web/Routes.js +1 -1
  33. package/dist/web/TtNavbar.js +19 -19
  34. package/dist/web/getInitialNavbarState.js +1 -1
  35. package/dist/web/global.d.js +1 -1
  36. package/dist/web/index.js +19 -19
  37. package/dist/web/styles.js +1 -1
  38. package/dist/web/triptease-logo.js +1 -1
  39. package/dist/web/tt-navbar.js +19 -19
  40. package/dist/web/urlMappings.js +1 -1
  41. package/package.json +19 -9
  42. package/tsconfig.cjs.json +9 -0
  43. package/tsconfig.json +3 -3
  44. package/web-test-runner.config.js +1 -1
  45. package/dist/src/Config.js.map +0 -1
  46. package/dist/src/Routes.js.map +0 -1
  47. package/dist/src/TtNavbar.js.map +0 -1
  48. package/dist/src/getInitialNavbarState.js.map +0 -1
  49. package/dist/src/index.js.map +0 -1
  50. package/dist/src/styles.js.map +0 -1
  51. package/dist/src/triptease-logo.js.map +0 -1
  52. package/dist/src/tt-navbar.js.map +0 -1
  53. package/dist/src/urlMappings.js.map +0 -1
  54. package/dist/stories/tt-navbar.stories.d.ts +0 -39
  55. package/dist/stories/tt-navbar.stories.js +0 -56
  56. package/dist/stories/tt-navbar.stories.js.map +0 -1
  57. package/dist/test/tt-navbar.test.js.map +0 -1
  58. /package/dist/{src → esm/src}/Config.d.ts +0 -0
  59. /package/dist/{src → esm/src}/Config.js +0 -0
  60. /package/dist/{src → esm/src}/Routes.d.ts +0 -0
  61. /package/dist/{src → esm/src}/Routes.js +0 -0
  62. /package/dist/{src → esm/src}/TtNavbar.d.ts +0 -0
  63. /package/dist/{src → esm/src}/TtNavbar.js +0 -0
  64. /package/dist/{src → esm/src}/getInitialNavbarState.d.ts +0 -0
  65. /package/dist/{src → esm/src}/getInitialNavbarState.js +0 -0
  66. /package/dist/{src → esm/src}/index.d.ts +0 -0
  67. /package/dist/{src → esm/src}/index.js +0 -0
  68. /package/dist/{src → esm/src}/styles.d.ts +0 -0
  69. /package/dist/{src → esm/src}/styles.js +0 -0
  70. /package/dist/{src → esm/src}/triptease-logo.d.ts +0 -0
  71. /package/dist/{src → esm/src}/triptease-logo.js +0 -0
  72. /package/dist/{src → esm/src}/tt-navbar.d.ts +0 -0
  73. /package/dist/{src → esm/src}/tt-navbar.js +0 -0
  74. /package/dist/{src → esm/src}/urlMappings.d.ts +0 -0
  75. /package/dist/{src → esm/src}/urlMappings.js +0 -0
  76. /package/dist/{test → esm/test}/tt-navbar.test.d.ts +0 -0
  77. /package/dist/{test → esm/test}/tt-navbar.test.js +0 -0
package/CHANGELOG.md CHANGED
@@ -1,5 +1,25 @@
1
1
  # @triptease/tt-navbar
2
2
 
3
+ ## 0.1.1
4
+
5
+ ### Patch Changes
6
+
7
+ - Updating the prepublish command to use yarn build:node instead of tsc so that it compiles the imports down to use required for common js
8
+ - Updated dependencies
9
+ - @triptease/tt-combobox@5.7.1
10
+
11
+ ## 0.1.0
12
+
13
+ ### Minor Changes
14
+
15
+ - Add dual ESM/CJS output
16
+
17
+ ### Patch Changes
18
+
19
+ - Updated dependencies
20
+ - @triptease/tt-combobox@5.7.0
21
+ - @triptease/icons@1.4.0
22
+
3
23
  ## 0.0.96
4
24
 
5
25
  ### Patch Changes
@@ -0,0 +1,3 @@
1
+ {
2
+ "type": "commonjs"
3
+ }
@@ -0,0 +1,10 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Config = void 0;
4
+ const Config = {
5
+ NavbarStateCookieName: 'tt-navbar-state',
6
+ NavbarStateCookieOpenValue: 'open',
7
+ NavbarStateCookieClosedValue: 'closed',
8
+ };
9
+ exports.Config = Config;
10
+ //# sourceMappingURL=Config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Config.js","sourceRoot":"","sources":["../../../src/Config.ts"],"names":[],"mappings":";;;AAAA,MAAM,MAAM,GAAG;IACb,qBAAqB,EAAE,iBAAiB;IACxC,0BAA0B,EAAE,MAAe;IAC3C,4BAA4B,EAAE,QAAiB;CAChD,CAAC;AAEO,wBAAM","sourcesContent":["const Config = {\n NavbarStateCookieName: 'tt-navbar-state',\n NavbarStateCookieOpenValue: 'open' as const,\n NavbarStateCookieClosedValue: 'closed' as const,\n};\n\nexport { Config };\n"]}
@@ -0,0 +1,8 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Routes = void 0;
4
+ const Routes = {
5
+ CampaignManager: 'CampaignManager',
6
+ };
7
+ exports.Routes = Routes;
8
+ //# sourceMappingURL=Routes.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Routes.js","sourceRoot":"","sources":["../../../src/Routes.ts"],"names":[],"mappings":";;;AAAA,MAAM,MAAM,GAAG;IACb,eAAe,EAAE,iBAAiB;CACnC,CAAC;AAEO,wBAAM","sourcesContent":["const Routes = {\n CampaignManager: 'CampaignManager',\n};\n\nexport { Routes };\n"]}
@@ -0,0 +1,426 @@
1
+ "use strict";
2
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
3
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
4
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
5
+ 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;
6
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
7
+ };
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.TtNavbar = void 0;
10
+ const lit_1 = require("lit");
11
+ const decorators_js_1 = require("lit/decorators.js");
12
+ const unsafe_svg_js_1 = require("lit/directives/unsafe-svg.js");
13
+ const icons_1 = require("@triptease/icons");
14
+ require("@triptease/tt-combobox");
15
+ const styles_js_1 = require("./styles.js");
16
+ const triptease_logo_js_1 = require("./triptease-logo.js");
17
+ const urlMappings_js_1 = require("./urlMappings.js");
18
+ const Routes_js_1 = require("./Routes.js");
19
+ const Config_js_1 = require("./Config.js");
20
+ const jsonArrayConverter = (value) => {
21
+ if (!value)
22
+ return [];
23
+ try {
24
+ return JSON.parse(value);
25
+ }
26
+ catch {
27
+ return [];
28
+ }
29
+ };
30
+ class TtNavbar extends lit_1.LitElement {
31
+ constructor() {
32
+ super(...arguments);
33
+ this.campaignManagerUrl = 'https://app.campaign-manager.triptease.io';
34
+ this.clients = [];
35
+ this.initialState = undefined;
36
+ this.isOpen = true;
37
+ /*
38
+ * Set the active state for the current page.
39
+ *
40
+ * This function iterates over all nav links and compares the current URL path with the href of each link.
41
+ * If the current URL path starts with the href of a link, the link is marked as active. If multiple links
42
+ * share the same prefix, the longest prefix is used as it is more specific.
43
+ *
44
+ * Example:
45
+ * - Current URL: /channels/123
46
+ * - Nav links:
47
+ * - /channels
48
+ * - /channels/123
49
+ * - /channels/456
50
+ *
51
+ * Loop 1: currentPath = /channels/123, linkPath = /channels, bestMatch = /channels
52
+ * Loop 2: currentPath = /channels/123, linkPath = /channels/123, bestMatch = /channels/123
53
+ * Loop 3: currentPath = /channels/123, linkPath = /channels/456, bestMatch = /channels/123
54
+ * Result: /channels/123 is marked as active
55
+ *
56
+ */
57
+ this.setActiveState = () => {
58
+ const currentPath = window.location.pathname;
59
+ let bestMatch;
60
+ let bestMatchLength = 0;
61
+ // Check special cases first, as everything will always match on / and return Dashboard
62
+ if (this.activeRoute === Routes_js_1.Routes.CampaignManager) {
63
+ bestMatch = this.campaignManagerLink;
64
+ }
65
+ if (!bestMatch && this.clientKey) {
66
+ const parsedPath = currentPath.replace(this.clientKey, '$CLIENT_KEY');
67
+ let mappedUrl = urlMappings_js_1.urlMappings[parsedPath];
68
+ const matchedPattern = this.mappedUrlPatterns.find((pattern) => pattern.test(currentPath, window.location.origin))?.pathname;
69
+ if (matchedPattern) {
70
+ mappedUrl = urlMappings_js_1.urlMappings[matchedPattern];
71
+ }
72
+ if (mappedUrl) {
73
+ const clientSpecificUrl = mappedUrl.replace('$CLIENT_KEY', this.clientKey);
74
+ const links = Object.values(this.allNavLinks);
75
+ bestMatch = links.find((link) => link.href.includes(clientSpecificUrl));
76
+ }
77
+ }
78
+ if (!bestMatch) {
79
+ for (const link of this.allNavLinks) {
80
+ const linkPath = new URL(link.href).pathname;
81
+ if (currentPath.startsWith(linkPath)) {
82
+ if (linkPath.length > bestMatchLength) {
83
+ bestMatch = link;
84
+ bestMatchLength = linkPath.length;
85
+ }
86
+ }
87
+ }
88
+ }
89
+ for (const link of this.allNavLinks) {
90
+ link.classList.remove('current-page');
91
+ if (link.hasAttribute('aria-current')) {
92
+ link.attributes.removeNamedItem('aria-current');
93
+ }
94
+ }
95
+ if (bestMatch) {
96
+ bestMatch.classList.add('current-page');
97
+ bestMatch.setAttribute('aria-current', 'page');
98
+ // Auto-expand parent details if the active link is within a collapsible section
99
+ const parentDetails = bestMatch.closest('details');
100
+ if (parentDetails) {
101
+ parentDetails.setAttribute('open', '');
102
+ }
103
+ }
104
+ else {
105
+ console.error(`No matching nav link found for path: ${currentPath}`);
106
+ }
107
+ };
108
+ this.closeAllDetails = (element) => {
109
+ this.allDetailsElements.forEach((detail) => {
110
+ if (element && !detail.contains(element)) {
111
+ detail.removeAttribute('open');
112
+ }
113
+ else if (!element) {
114
+ detail.removeAttribute('open');
115
+ }
116
+ });
117
+ };
118
+ this.toggleSidebar = () => {
119
+ this.closeAllDetails();
120
+ this.isOpen = !this.isOpen;
121
+ const { NavbarStateCookieName, NavbarStateCookieOpenValue, NavbarStateCookieClosedValue } = Config_js_1.Config;
122
+ const domain = window.location.hostname.endsWith('.triptease.io') ? 'domain=.triptease.io' : '';
123
+ document.cookie = `${NavbarStateCookieName}=${this.isOpen ? NavbarStateCookieOpenValue : NavbarStateCookieClosedValue}; path=/; max-age=31536000; ${domain}`;
124
+ };
125
+ this.handleDetailsToggle = (e) => {
126
+ const { newState } = e;
127
+ const target = e.currentTarget;
128
+ if (newState === 'open') {
129
+ if (!this.isOpen) {
130
+ this.toggleSidebar();
131
+ }
132
+ this.closeAllDetails(target);
133
+ }
134
+ };
135
+ this.buildUrl = (path) => {
136
+ if (!this.clientKey)
137
+ throw new Error('clientKey is required');
138
+ const formattedPath = path.replace('$CLIENT_KEY', this.clientKey);
139
+ if (!this.platformUrl)
140
+ return formattedPath;
141
+ return new URL(formattedPath, this.platformUrl).toString();
142
+ };
143
+ this.onAnchorClick = (e) => {
144
+ if (this.navigate) {
145
+ this.navigate(e);
146
+ this.setActiveState();
147
+ }
148
+ };
149
+ this.handleClientChange = (e) => {
150
+ const combobox = e.target;
151
+ const selectedClientKey = combobox.value?.[0];
152
+ if (selectedClientKey && this.onClientChange) {
153
+ this.onClientChange(selectedClientKey);
154
+ }
155
+ };
156
+ }
157
+ firstUpdated() {
158
+ this.setActiveState();
159
+ }
160
+ connectedCallback() {
161
+ // Listen for browser back/forward navigation
162
+ window.addEventListener('popstate', this.setActiveState);
163
+ // Listen for Tetris programmatic navigation
164
+ window.addEventListener('tetris:navigate', this.setActiveState);
165
+ super.connectedCallback();
166
+ if (this.initialState) {
167
+ this.isOpen = this.initialState === 'open';
168
+ }
169
+ }
170
+ disconnectedCallback() {
171
+ window.removeEventListener('popstate', this.setActiveState);
172
+ window.removeEventListener('tetris:navigate', this.setActiveState);
173
+ super.disconnectedCallback();
174
+ }
175
+ get mappedUrlPatterns() {
176
+ return Object.keys(urlMappings_js_1.urlMappings).map((pattern) => new URLPattern({ pathname: pattern, baseURL: window.location.origin }));
177
+ }
178
+ render() {
179
+ return (0, lit_1.html) `
180
+ <nav id=${this.id} class="${this.isOpen ? '' : 'sidebar-closed'}">
181
+ <div class="sidebar-header ${this.isOpen ? '' : 'sidebar-closed'}">
182
+ <div class="logo">
183
+ ${(0, unsafe_svg_js_1.unsafeSVG)(triptease_logo_js_1.tripteaseLogo)}
184
+ </div>
185
+ <button id="navbar-toggle-btn" class="nav-item nav-toggle-button" @click=${this.toggleSidebar}>
186
+ ${(0, unsafe_svg_js_1.unsafeSVG)(icons_1.sidebarCollapsed)}
187
+ <span class="tooltip nav-toggle-tooltip">
188
+ ${(0, unsafe_svg_js_1.unsafeSVG)(icons_1.sidebarCollapsed)}
189
+ <span>${this.isOpen ? (0, lit_1.html) `Collapse sidebar` : (0, lit_1.html) `Expand sidebar`}</span>
190
+ </span>
191
+ </button>
192
+ </div>
193
+
194
+ <div class="nav-items ${this.isOpen ? '' : 'sidebar-closed'}">
195
+ <a
196
+ class="nav-item"
197
+ href=${this.buildUrl('/')}
198
+ @click=${this.onAnchorClick}
199
+ data-intercom-target="dashboard"
200
+ >${(0, unsafe_svg_js_1.unsafeSVG)(icons_1.home)}<span>Dashboard</span></a
201
+ >
202
+ <a id="${Routes_js_1.Routes.CampaignManager}" class="nav-item" href=${this.campaignManagerUrl}
203
+ @click=${this.onAnchorClick}
204
+ data-intercom-target="campaigns"
205
+ >${(0, unsafe_svg_js_1.unsafeSVG)(icons_1.campaigns)}<span>Campaigns</span></a
206
+ >
207
+ <a
208
+ class="nav-item"
209
+ href=${this.buildUrl('/$CLIENT_KEY/channels')}
210
+ @click=${this.onAnchorClick}
211
+ data-intercom-target="channels"
212
+ >${(0, unsafe_svg_js_1.unsafeSVG)(icons_1.channels)}<span>Channels</span></a
213
+ >
214
+ <details id="market-insights" @toggle=${this.handleDetailsToggle} data-intercom-target="market-insights">
215
+ <summary>
216
+ ${(0, unsafe_svg_js_1.unsafeSVG)(icons_1.graph)}
217
+ <span>Market Insights</span>
218
+ <span class="icon chevron"> ${(0, unsafe_svg_js_1.unsafeSVG)(icons_1.chevronDown)}</span>
219
+ </summary>
220
+ <div class="dropdown-items">
221
+ <a
222
+ class="sub-nav-item"
223
+ href=${this.buildUrl('/parity/$CLIENT_KEY')}
224
+ @click=${this.onAnchorClick}
225
+ data-intercom-target="parity-monitoring"
226
+ >Parity monitoring</a
227
+ >
228
+ <a
229
+ class="sub-nav-item"
230
+ href=${this.buildUrl('/$CLIENT_KEY/guest-insights')}
231
+ @click=${this.onAnchorClick}
232
+ data-intercom-target="guest-insights"
233
+ >Guest insights</a
234
+ >
235
+ </div>
236
+ </details>
237
+ <details id="settings" @toggle=${this.handleDetailsToggle} data-intercom-target="settings">
238
+ <summary>
239
+ ${(0, unsafe_svg_js_1.unsafeSVG)(icons_1.gear)}
240
+ <span>Settings</span>
241
+ <span class="icon chevron"> ${(0, unsafe_svg_js_1.unsafeSVG)(icons_1.chevronDown)}</span>
242
+ </summary>
243
+ <div class="dropdown-items">
244
+ <a
245
+ class="sub-nav-item"
246
+ href=${this.buildUrl('/$CLIENT_KEY/guest-behavioural-data')}
247
+ @click=${this.onAnchorClick}
248
+ data-intercom-target="email-setup"
249
+ >Email setup</a
250
+ >
251
+ <a
252
+ class="sub-nav-item"
253
+ href=${this.buildUrl('/$CLIENT_KEY/crm-config')}
254
+ @click=${this.onAnchorClick}
255
+ data-intercom-target="crm-connectivity"
256
+ >CRM connectivity</a
257
+ >
258
+ <a
259
+ class="sub-nav-item"
260
+ href=${this.buildUrl('/$CLIENT_KEY/settings/guides')}
261
+ @click=${this.onAnchorClick}
262
+ data-intercom-target="group-settings"
263
+ >Group settings</a
264
+ >
265
+ <a
266
+ class="sub-nav-item"
267
+ href=${this.buildUrl('/$CLIENT_KEY/settings/hotels')}
268
+ @click=${this.onAnchorClick}
269
+ data-intercom-target="property-settings"
270
+ >Property settings</a
271
+ >
272
+ </div>
273
+ </details>
274
+ <hr />
275
+ <details id="account" @toggle=${this.handleDetailsToggle} data-intercom-target="account">
276
+ <summary>
277
+ ${(0, unsafe_svg_js_1.unsafeSVG)(icons_1.user)}
278
+ <span>Account</span>
279
+ <span class="icon chevron"> ${(0, unsafe_svg_js_1.unsafeSVG)(icons_1.chevronDown)}</span>
280
+ </summary>
281
+ <div class="dropdown-items">
282
+ <a
283
+ class="sub-nav-item"
284
+ href=${this.buildUrl('/account')}
285
+ @click=${this.onAnchorClick}
286
+ data-intercom-target="user-settings"
287
+ >User settings</a
288
+ >
289
+ <!-- TODO: Change to /$CLIENT_KEY/account/team when the change in Tetris is ready -->
290
+ <a
291
+ class="sub-nav-item"
292
+ href=${this.buildUrl('/account/team/$CLIENT_KEY')}
293
+ @click=${this.onAnchorClick}
294
+ data-intercom-target="team-permissions"
295
+ >Team and permissions</a
296
+ >
297
+ </div>
298
+ </details>
299
+ <details id="billing-routes" @toggle=${this.handleDetailsToggle} data-intercom-target="billing">
300
+ <summary>
301
+ ${(0, unsafe_svg_js_1.unsafeSVG)(icons_1.wallet)}
302
+ <span>Billing</span>
303
+ <span class="icon chevron"> ${(0, unsafe_svg_js_1.unsafeSVG)(icons_1.chevronDown)}</span>
304
+ </summary>
305
+ <div>
306
+ <!-- TODO: Change to /$CLIENT_KEY/account/billing-management when the change in Tetris is ready -->
307
+ <a
308
+ class="sub-nav-item"
309
+ href=${this.buildUrl('/account/billing-management/$CLIENT_KEY')}
310
+ @click=${this.onAnchorClick}
311
+ data-intercom-target="booking-reconciliation"
312
+ >Booking reconciliation</a
313
+ >
314
+ <!-- TODO: Change to /$CLIENT_KEY/subscriptions when the change in Tetris is ready -->
315
+ <a
316
+ class="sub-nav-item"
317
+ href=${this.buildUrl('/subscriptions/$CLIENT_KEY')}
318
+ @click=${this.onAnchorClick}
319
+ data-intercom-target="subscriptions"
320
+ >Subscriptions</a
321
+ >
322
+ </div>
323
+ </details>
324
+ </div>
325
+ <div class="tertiary-nav ${this.isOpen ? '' : 'sidebar-closed'}">
326
+ <div id="external-links" class="nav-items">
327
+ <a
328
+ class="nav-item external-link"
329
+ href='https://triptease.canny.io/feature-requests'
330
+ target="_blank"
331
+ rel="noreferrer"
332
+ >
333
+ Feature requests
334
+ ${(0, unsafe_svg_js_1.unsafeSVG)(icons_1.external)}
335
+ </a>
336
+ <a
337
+ class='nav-item external-link'
338
+ href='https://triptease.canny.io/changelog'
339
+ target="_blank"
340
+ rel="noreferrer"
341
+ >
342
+ Product updates
343
+ ${(0, unsafe_svg_js_1.unsafeSVG)(icons_1.external)}
344
+ </a>
345
+ <a
346
+ class='nav-item external-link'
347
+ href='https://help.triptease.com/'
348
+ target="_blank"
349
+ rel="noreferrer"
350
+ >
351
+ Help center
352
+ ${(0, unsafe_svg_js_1.unsafeSVG)(icons_1.external)}
353
+ </a>
354
+ <hr />
355
+ </div>
356
+ <div class='nav-items'>
357
+ <div id="client-selector">
358
+ ${this.clients.length > 1
359
+ ? (0, lit_1.html) `
360
+ <tt-combobox
361
+ .openUpward=${true}
362
+ .value=${this.clientKey ? [this.clientKey] : []}
363
+ @change=${this.handleClientChange}
364
+ >
365
+ ${this.clients.map((client) => (0, lit_1.html) `
366
+ <option slot="option" value=${client.clientKey}>${client.displayName}</option>
367
+ `)}
368
+ </tt-combobox>
369
+ `
370
+ : (0, lit_1.html) `
371
+ <div class="single-client-name">
372
+ ${this.clients.find((m) => m.clientKey === this.clientKey)?.displayName}
373
+ </div>
374
+ `}
375
+ </div>
376
+ <a
377
+ id="logout-link"
378
+ class="nav-item"
379
+ href=${this.buildUrl('/logout')}
380
+ @click=${this.onAnchorClick}
381
+ data-intercom-target="logout"
382
+ >${(0, unsafe_svg_js_1.unsafeSVG)(icons_1.logout)}<span>Logout</span></a>
383
+ </div>
384
+ </nav>
385
+ `;
386
+ }
387
+ }
388
+ exports.TtNavbar = TtNavbar;
389
+ TtNavbar.styles = styles_js_1.styles;
390
+ __decorate([
391
+ (0, decorators_js_1.property)({ type: Function })
392
+ ], TtNavbar.prototype, "navigate", void 0);
393
+ __decorate([
394
+ (0, decorators_js_1.property)({ type: String, attribute: 'campaign-manager-url' })
395
+ ], TtNavbar.prototype, "campaignManagerUrl", void 0);
396
+ __decorate([
397
+ (0, decorators_js_1.property)({ type: String, attribute: 'platform-url' })
398
+ ], TtNavbar.prototype, "platformUrl", void 0);
399
+ __decorate([
400
+ (0, decorators_js_1.property)({ type: String, attribute: 'client-key' })
401
+ ], TtNavbar.prototype, "clientKey", void 0);
402
+ __decorate([
403
+ (0, decorators_js_1.property)({ type: String, attribute: 'active-route' })
404
+ ], TtNavbar.prototype, "activeRoute", void 0);
405
+ __decorate([
406
+ (0, decorators_js_1.property)({ type: Array, converter: jsonArrayConverter })
407
+ ], TtNavbar.prototype, "clients", void 0);
408
+ __decorate([
409
+ (0, decorators_js_1.property)({ type: String, attribute: 'initial-state' })
410
+ ], TtNavbar.prototype, "initialState", void 0);
411
+ __decorate([
412
+ (0, decorators_js_1.state)()
413
+ ], TtNavbar.prototype, "isOpen", void 0);
414
+ __decorate([
415
+ (0, decorators_js_1.property)({ type: Object })
416
+ ], TtNavbar.prototype, "onClientChange", void 0);
417
+ __decorate([
418
+ (0, decorators_js_1.queryAll)('details')
419
+ ], TtNavbar.prototype, "allDetailsElements", void 0);
420
+ __decorate([
421
+ (0, decorators_js_1.queryAll)('a')
422
+ ], TtNavbar.prototype, "allNavLinks", void 0);
423
+ __decorate([
424
+ (0, decorators_js_1.query)(`a#${Routes_js_1.Routes.CampaignManager}`)
425
+ ], TtNavbar.prototype, "campaignManagerLink", void 0);
426
+ //# sourceMappingURL=TtNavbar.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TtNavbar.js","sourceRoot":"","sources":["../../../src/TtNavbar.ts"],"names":[],"mappings":";;;;;;;;;AAAA,6BAAuC;AACvC,qDAAqE;AACrE,gEAAyD;AACzD,4CAY0B;AAC1B,kCAAgC;AAChC,2CAAqC;AACrC,2DAAoD;AACpD,qDAA+C;AAC/C,2CAAqC;AACrC,2CAAqC;AAErC,MAAM,kBAAkB,GAAG,CAAC,KAAoB,EAAE,EAAE;IAClD,IAAI,CAAC,KAAK;QAAE,OAAO,EAAE,CAAC;IACtB,IAAI,CAAC;QACH,OAAO,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IAC3B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC,CAAC;AAEF,MAAa,QAAS,SAAQ,gBAAU;IAAxC;;QAOE,uBAAkB,GAAW,2CAA2C,CAAC;QAYzE,YAAO,GAAiD,EAAE,CAAC;QAG3D,iBAAY,GAAkC,SAAS,CAAC;QAGxD,WAAM,GAAY,IAAI,CAAC;QA6CvB;;;;;;;;;;;;;;;;;;;WAmBG;QACK,mBAAc,GAAG,GAAG,EAAE;YAC5B,MAAM,WAAW,GAAG,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAC;YAE7C,IAAI,SAAwC,CAAC;YAC7C,IAAI,eAAe,GAAG,CAAC,CAAC;YAExB,uFAAuF;YACvF,IAAI,IAAI,CAAC,WAAW,KAAK,kBAAM,CAAC,eAAe,EAAE,CAAC;gBAChD,SAAS,GAAG,IAAI,CAAC,mBAAmB,CAAC;YACvC,CAAC;YACD,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;gBACjC,MAAM,UAAU,GAAG,WAAW,CAAC,OAAO,CAAC,IAAI,CAAC,SAAS,EAAE,aAAa,CAAC,CAAC;gBACtE,IAAI,SAAS,GAAuB,4BAAW,CAAC,UAAU,CAAC,CAAC;gBAE5D,MAAM,cAAc,GAAG,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC,CAAC,OAAO,EAAE,EAAE,CAC7D,OAAO,CAAC,IAAI,CAAC,WAAW,EAAE,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,CAClD,EAAE,QAAQ,CAAC;gBAEZ,IAAI,cAAc,EAAE,CAAC;oBACnB,SAAS,GAAG,4BAAW,CAAC,cAAc,CAAC,CAAC;gBAC1C,CAAC;gBAED,IAAI,SAAS,EAAE,CAAC;oBACd,MAAM,iBAAiB,GAAG,SAAS,CAAC,OAAO,CAAC,aAAa,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;oBAC3E,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;oBAC9C,SAAS,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,iBAAiB,CAAC,CAAC,CAAC;gBAC1E,CAAC;YACH,CAAC;YAED,IAAI,CAAC,SAAS,EAAE,CAAC;gBACf,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;oBACpC,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC;oBAE7C,IAAI,WAAW,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;wBACrC,IAAI,QAAQ,CAAC,MAAM,GAAG,eAAe,EAAE,CAAC;4BACtC,SAAS,GAAG,IAAI,CAAC;4BACjB,eAAe,GAAG,QAAQ,CAAC,MAAM,CAAC;wBACpC,CAAC;oBACH,CAAC;gBACH,CAAC;YACH,CAAC;YAED,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,WAAW,EAAE,CAAC;gBACpC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,cAAc,CAAC,CAAC;gBACtC,IAAI,IAAI,CAAC,YAAY,CAAC,cAAc,CAAC,EAAE,CAAC;oBACtC,IAAI,CAAC,UAAU,CAAC,eAAe,CAAC,cAAc,CAAC,CAAC;gBAClD,CAAC;YACH,CAAC;YAED,IAAI,SAAS,EAAE,CAAC;gBACd,SAAS,CAAC,SAAS,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;gBACxC,SAAS,CAAC,YAAY,CAAC,cAAc,EAAE,MAAM,CAAC,CAAC;gBAE/C,gFAAgF;gBAChF,MAAM,aAAa,GAAG,SAAS,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;gBACnD,IAAI,aAAa,EAAE,CAAC;oBAClB,aAAa,CAAC,YAAY,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;gBACzC,CAAC;YACH,CAAC;iBAAM,CAAC;gBACN,OAAO,CAAC,KAAK,CAAC,wCAAwC,WAAW,EAAE,CAAC,CAAC;YACvE,CAAC;QACH,CAAC,CAAC;QAEM,oBAAe,GAAG,CAAC,OAA4B,EAAE,EAAE;YACzD,IAAI,CAAC,kBAAkB,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,EAAE;gBACzC,IAAI,OAAO,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;oBACzC,MAAM,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC;gBACjC,CAAC;qBAAM,IAAI,CAAC,OAAO,EAAE,CAAC;oBACpB,MAAM,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC;gBACjC,CAAC;YACH,CAAC,CAAC,CAAC;QACL,CAAC,CAAC;QAEM,kBAAa,GAAG,GAAG,EAAE;YAC3B,IAAI,CAAC,eAAe,EAAE,CAAC;YACvB,IAAI,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,MAAM,CAAC;YAE3B,MAAM,EAAE,qBAAqB,EAAE,0BAA0B,EAAE,4BAA4B,EAAE,GAAG,kBAAM,CAAC;YAEnG,MAAM,MAAM,GAAG,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAC,QAAQ,CAAC,eAAe,CAAC,CAAC,CAAC,CAAC,sBAAsB,CAAC,CAAC,CAAC,EAAE,CAAC;YAEhG,QAAQ,CAAC,MAAM,GAAG,GAAG,qBAAqB,IAAI,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,0BAA0B,CAAC,CAAC,CAAC,4BAA4B,+BAA+B,MAAM,EAAE,CAAC;QAC/J,CAAC,CAAC;QAEM,wBAAmB,GAAG,CAAC,CAAc,EAAE,EAAE;YAC/C,MAAM,EAAE,QAAQ,EAAE,GAAG,CAAC,CAAC;YACvB,MAAM,MAAM,GAAG,CAAC,CAAC,aAAmC,CAAC;YAErD,IAAI,QAAQ,KAAK,MAAM,EAAE,CAAC;gBACxB,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;oBACjB,IAAI,CAAC,aAAa,EAAE,CAAC;gBACvB,CAAC;gBAED,IAAI,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC;YAC/B,CAAC;QACH,CAAC,CAAC;QAEM,aAAQ,GAAG,CAAC,IAAY,EAAU,EAAE;YAC1C,IAAI,CAAC,IAAI,CAAC,SAAS;gBAAE,MAAM,IAAI,KAAK,CAAC,uBAAuB,CAAC,CAAC;YAE9D,MAAM,aAAa,GAAG,IAAI,CAAC,OAAO,CAAC,aAAa,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;YAClE,IAAI,CAAC,IAAI,CAAC,WAAW;gBAAE,OAAO,aAAa,CAAC;YAE5C,OAAO,IAAI,GAAG,CAAC,aAAa,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC,QAAQ,EAAE,CAAC;QAC7D,CAAC,CAAC;QAEM,kBAAa,GAAG,CAAC,CAAa,EAAE,EAAE;YACxC,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;gBAClB,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;gBACjB,IAAI,CAAC,cAAc,EAAE,CAAC;YACxB,CAAC;QACH,CAAC,CAAC;QAEM,uBAAkB,GAAG,CAAC,CAAQ,EAAE,EAAE;YACxC,MAAM,QAAQ,GAAG,CAAC,CAAC,MAA4C,CAAC;YAChE,MAAM,iBAAiB,GAAG,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC;YAE9C,IAAI,iBAAiB,IAAI,IAAI,CAAC,cAAc,EAAE,CAAC;gBAC7C,IAAI,CAAC,cAAc,CAAC,iBAAiB,CAAC,CAAC;YACzC,CAAC;QACH,CAAC,CAAC;IAuNJ,CAAC;IAlYW,YAAY;QACpB,IAAI,CAAC,cAAc,EAAE,CAAC;IACxB,CAAC;IAEM,iBAAiB;QACtB,6CAA6C;QAC7C,MAAM,CAAC,gBAAgB,CAAC,UAAU,EAAE,IAAI,CAAC,cAAc,CAAC,CAAC;QAEzD,4CAA4C;QAC5C,MAAM,CAAC,gBAAgB,CAAC,iBAAiB,EAAE,IAAI,CAAC,cAAc,CAAC,CAAC;QAEhE,KAAK,CAAC,iBAAiB,EAAE,CAAC;QAE1B,IAAI,IAAI,CAAC,YAAY,EAAE,CAAC;YACtB,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,YAAY,KAAK,MAAM,CAAC;QAC7C,CAAC;IACH,CAAC;IAEM,oBAAoB;QACzB,MAAM,CAAC,mBAAmB,CAAC,UAAU,EAAE,IAAI,CAAC,cAAc,CAAC,CAAC;QAC5D,MAAM,CAAC,mBAAmB,CAAC,iBAAiB,EAAE,IAAI,CAAC,cAAc,CAAC,CAAC;QAEnE,KAAK,CAAC,oBAAoB,EAAE,CAAC;IAC/B,CAAC;IAED,IAAY,iBAAiB;QAC3B,OAAO,MAAM,CAAC,IAAI,CAAC,4BAAW,CAAC,CAAC,GAAG,CACjC,CAAC,OAAO,EAAE,EAAE,CAAC,IAAI,UAAU,CAAC,EAAE,QAAQ,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC,CACpF,CAAC;IACJ,CAAC;IAgJD,MAAM;QACJ,OAAO,IAAA,UAAI,EAAA;gBACC,IAAI,CAAC,EAAE,WAAW,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,gBAAgB;qCAChC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,gBAAgB;;cAE1D,IAAA,yBAAS,EAAC,iCAAa,CAAC;;qFAE+C,IAAI,CAAC,aAAa;cACzF,IAAA,yBAAS,EAAC,wBAAgB,CAAC;;gBAEzB,IAAA,yBAAS,EAAC,wBAAgB,CAAC;sBACrB,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,IAAA,UAAI,EAAA,kBAAkB,CAAC,CAAC,CAAC,IAAA,UAAI,EAAA,gBAAgB;;;;;gCAKjD,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,gBAAgB;;;mBAGhD,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC;qBAChB,IAAI,CAAC,aAAa;;aAE1B,IAAA,yBAAS,EAAC,YAAI,CAAC;;mBAET,kBAAM,CAAC,eAAe,2BAA2B,IAAI,CAAC,kBAAkB;sBACrE,IAAI,CAAC,aAAa;;aAE3B,IAAA,yBAAS,EAAC,iBAAS,CAAC;;;;mBAId,IAAI,CAAC,QAAQ,CAAC,uBAAuB,CAAC;qBACpC,IAAI,CAAC,aAAa;;aAE1B,IAAA,yBAAS,EAAC,gBAAQ,CAAC;;kDAEkB,IAAI,CAAC,mBAAmB;;gBAE1D,IAAA,yBAAS,EAAC,aAAK,CAAC;;4CAEY,IAAA,yBAAS,EAAC,mBAAW,CAAC;;;;;uBAK3C,IAAI,CAAC,QAAQ,CAAC,qBAAqB,CAAC;yBAClC,IAAI,CAAC,aAAa;;;;;;uBAMpB,IAAI,CAAC,QAAQ,CAAC,6BAA6B,CAAC;yBAC1C,IAAI,CAAC,aAAa;;;;;;2CAMA,IAAI,CAAC,mBAAmB;;gBAEnD,IAAA,yBAAS,EAAC,YAAI,CAAC;;4CAEa,IAAA,yBAAS,EAAC,mBAAW,CAAC;;;;;uBAK3C,IAAI,CAAC,QAAQ,CAAC,qCAAqC,CAAC;yBAClD,IAAI,CAAC,aAAa;;;;;;uBAMpB,IAAI,CAAC,QAAQ,CAAC,yBAAyB,CAAC;yBACtC,IAAI,CAAC,aAAa;;;;;;uBAMpB,IAAI,CAAC,QAAQ,CAAC,8BAA8B,CAAC;yBAC3C,IAAI,CAAC,aAAa;;;;;;uBAMpB,IAAI,CAAC,QAAQ,CAAC,8BAA8B,CAAC;yBAC3C,IAAI,CAAC,aAAa;;;;;;;0CAOD,IAAI,CAAC,mBAAmB;;gBAElD,IAAA,yBAAS,EAAC,YAAI,CAAC;;4CAEa,IAAA,yBAAS,EAAC,mBAAW,CAAC;;;;;uBAK3C,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC;yBACvB,IAAI,CAAC,aAAa;;;;;;;uBAOpB,IAAI,CAAC,QAAQ,CAAC,2BAA2B,CAAC;yBACxC,IAAI,CAAC,aAAa;;;;;;iDAMM,IAAI,CAAC,mBAAmB;;gBAEzD,IAAA,yBAAS,EAAC,cAAM,CAAC;;4CAEW,IAAA,yBAAS,EAAC,mBAAW,CAAC;;;;;;uBAM3C,IAAI,CAAC,QAAQ,CAAC,yCAAyC,CAAC;yBACtD,IAAI,CAAC,aAAa;;;;;;;uBAOpB,IAAI,CAAC,QAAQ,CAAC,4BAA4B,CAAC;yBACzC,IAAI,CAAC,aAAa;;;;;;;mCAOR,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,gBAAgB;;;;;;;;;gBAStD,IAAA,yBAAS,EAAC,gBAAQ,CAAC;;;;;;;;;gBASnB,IAAA,yBAAS,EAAC,gBAAQ,CAAC;;;;;;;;;gBASnB,IAAA,yBAAS,EAAC,gBAAQ,CAAC;;;;;;gBAOnB,IAAI,CAAC,OAAO,CAAC,MAAM,GAAG,CAAC;YACrB,CAAC,CAAC,IAAA,UAAI,EAAA;;sCAEc,IAAI;iCACT,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,EAAE;kCACrC,IAAI,CAAC,kBAAkB;;0BAE/B,IAAI,CAAC,OAAO,CAAC,GAAG,CAChB,CAAC,MAAM,EAAE,EAAE,CAAC,IAAA,UAAI,EAAA;0DACgB,MAAM,CAAC,SAAS,IAAI,MAAM,CAAC,WAAW;2BACrE,CACF;;qBAEJ;YACH,CAAC,CAAC,IAAA,UAAI,EAAA;;0BAEE,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,KAAK,IAAI,CAAC,SAAS,CAAC,EAAE,WAAW;;qBAGjF;;;;;qBAKO,IAAI,CAAC,QAAQ,CAAC,SAAS,CAAC;uBACtB,IAAI,CAAC,aAAa;;eAE1B,IAAA,yBAAS,EAAC,cAAM,CAAC;;;KAG3B,CAAC;IACJ,CAAC;;AAxaH,4BAyaC;AAxaQ,eAAM,GAAG,kBAAM,AAAT,CAAU;AAGvB;IADC,IAAA,wBAAQ,EAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC;0CACmB;AAGhD;IADC,IAAA,wBAAQ,EAAC,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,sBAAsB,EAAE,CAAC;oDACW;AAGzE;IADC,IAAA,wBAAQ,EAAC,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,cAAc,EAAE,CAAC;6CACjC;AAGrB;IADC,IAAA,wBAAQ,EAAC,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,YAAY,EAAE,CAAC;2CACjC;AAGnB;IADC,IAAA,wBAAQ,EAAC,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,cAAc,EAAE,CAAC;6CACpB;AAGlC;IADC,IAAA,wBAAQ,EAAC,EAAE,IAAI,EAAE,KAAK,EAAE,SAAS,EAAE,kBAAkB,EAAE,CAAC;yCACE;AAG3D;IADC,IAAA,wBAAQ,EAAC,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,eAAe,EAAE,CAAC;8CACC;AAGxD;IADC,IAAA,qBAAK,GAAE;wCACe;AAGvB;IADC,IAAA,wBAAQ,EAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;gDACuC;AAGxD;IADT,IAAA,wBAAQ,EAAC,SAAS,CAAC;oDACqC;AAG/C;IADT,IAAA,wBAAQ,EAAC,GAAG,CAAC;6CACmC;AAGzC;IADP,IAAA,qBAAK,EAAC,KAAK,kBAAM,CAAC,eAAe,EAAE,CAAC;qDACW","sourcesContent":["import { html, LitElement } from 'lit';\nimport { property, query, queryAll, state } from 'lit/decorators.js';\nimport { unsafeSVG } from 'lit/directives/unsafe-svg.js';\nimport {\n campaigns,\n channels,\n chevronDown,\n external,\n gear,\n graph,\n home,\n logout,\n sidebarCollapsed,\n user,\n wallet,\n} from '@triptease/icons';\nimport '@triptease/tt-combobox';\nimport { styles } from './styles.js';\nimport { tripteaseLogo } from './triptease-logo.js';\nimport { urlMappings } from './urlMappings.js';\nimport { Routes } from './Routes.js';\nimport { Config } from './Config.js';\n\nconst jsonArrayConverter = (value: string | null) => {\n if (!value) return [];\n try {\n return JSON.parse(value);\n } catch {\n return [];\n }\n};\n\nexport class TtNavbar extends LitElement {\n static styles = styles;\n\n @property({ type: Function })\n navigate: ((e: MouseEvent) => void) | undefined;\n\n @property({ type: String, attribute: 'campaign-manager-url' })\n campaignManagerUrl: string = 'https://app.campaign-manager.triptease.io';\n\n @property({ type: String, attribute: 'platform-url' })\n platformUrl?: string;\n\n @property({ type: String, attribute: 'client-key' })\n clientKey?: string;\n\n @property({ type: String, attribute: 'active-route' })\n activeRoute?: keyof typeof Routes;\n\n @property({ type: Array, converter: jsonArrayConverter })\n clients: { clientKey: string; displayName: string }[] = [];\n\n @property({ type: String, attribute: 'initial-state' })\n initialState: 'open' | 'closed' | undefined = undefined;\n\n @state()\n isOpen: boolean = true;\n\n @property({ type: Object })\n onClientChange: ((clientKeySelected: string) => void) | undefined;\n\n @queryAll('details')\n protected allDetailsElements!: Array<HTMLDetailsElement>;\n\n @queryAll('a')\n protected allNavLinks!: Array<HTMLAnchorElement>;\n\n @query(`a#${Routes.CampaignManager}`)\n private campaignManagerLink!: HTMLAnchorElement;\n\n protected firstUpdated() {\n this.setActiveState();\n }\n\n public connectedCallback() {\n // Listen for browser back/forward navigation\n window.addEventListener('popstate', this.setActiveState);\n\n // Listen for Tetris programmatic navigation\n window.addEventListener('tetris:navigate', this.setActiveState);\n\n super.connectedCallback();\n\n if (this.initialState) {\n this.isOpen = this.initialState === 'open';\n }\n }\n\n public disconnectedCallback() {\n window.removeEventListener('popstate', this.setActiveState);\n window.removeEventListener('tetris:navigate', this.setActiveState);\n\n super.disconnectedCallback();\n }\n\n private get mappedUrlPatterns(): URLPattern[] {\n return Object.keys(urlMappings).map(\n (pattern) => new URLPattern({ pathname: pattern, baseURL: window.location.origin })\n );\n }\n\n /*\n * Set the active state for the current page.\n *\n * This function iterates over all nav links and compares the current URL path with the href of each link.\n * If the current URL path starts with the href of a link, the link is marked as active. If multiple links\n * share the same prefix, the longest prefix is used as it is more specific.\n *\n * Example:\n * - Current URL: /channels/123\n * - Nav links:\n * - /channels\n * - /channels/123\n * - /channels/456\n *\n * Loop 1: currentPath = /channels/123, linkPath = /channels, bestMatch = /channels\n * Loop 2: currentPath = /channels/123, linkPath = /channels/123, bestMatch = /channels/123\n * Loop 3: currentPath = /channels/123, linkPath = /channels/456, bestMatch = /channels/123\n * Result: /channels/123 is marked as active\n *\n */\n private setActiveState = () => {\n const currentPath = window.location.pathname;\n\n let bestMatch: HTMLAnchorElement | undefined;\n let bestMatchLength = 0;\n\n // Check special cases first, as everything will always match on / and return Dashboard\n if (this.activeRoute === Routes.CampaignManager) {\n bestMatch = this.campaignManagerLink;\n }\n if (!bestMatch && this.clientKey) {\n const parsedPath = currentPath.replace(this.clientKey, '$CLIENT_KEY');\n let mappedUrl: string | undefined = urlMappings[parsedPath];\n\n const matchedPattern = this.mappedUrlPatterns.find((pattern) =>\n pattern.test(currentPath, window.location.origin)\n )?.pathname;\n\n if (matchedPattern) {\n mappedUrl = urlMappings[matchedPattern];\n }\n\n if (mappedUrl) {\n const clientSpecificUrl = mappedUrl.replace('$CLIENT_KEY', this.clientKey);\n const links = Object.values(this.allNavLinks);\n bestMatch = links.find((link) => link.href.includes(clientSpecificUrl));\n }\n }\n\n if (!bestMatch) {\n for (const link of this.allNavLinks) {\n const linkPath = new URL(link.href).pathname;\n\n if (currentPath.startsWith(linkPath)) {\n if (linkPath.length > bestMatchLength) {\n bestMatch = link;\n bestMatchLength = linkPath.length;\n }\n }\n }\n }\n\n for (const link of this.allNavLinks) {\n link.classList.remove('current-page');\n if (link.hasAttribute('aria-current')) {\n link.attributes.removeNamedItem('aria-current');\n }\n }\n\n if (bestMatch) {\n bestMatch.classList.add('current-page');\n bestMatch.setAttribute('aria-current', 'page');\n\n // Auto-expand parent details if the active link is within a collapsible section\n const parentDetails = bestMatch.closest('details');\n if (parentDetails) {\n parentDetails.setAttribute('open', '');\n }\n } else {\n console.error(`No matching nav link found for path: ${currentPath}`);\n }\n };\n\n private closeAllDetails = (element?: HTMLDetailsElement) => {\n this.allDetailsElements.forEach((detail) => {\n if (element && !detail.contains(element)) {\n detail.removeAttribute('open');\n } else if (!element) {\n detail.removeAttribute('open');\n }\n });\n };\n\n private toggleSidebar = () => {\n this.closeAllDetails();\n this.isOpen = !this.isOpen;\n\n const { NavbarStateCookieName, NavbarStateCookieOpenValue, NavbarStateCookieClosedValue } = Config;\n\n const domain = window.location.hostname.endsWith('.triptease.io') ? 'domain=.triptease.io' : '';\n\n document.cookie = `${NavbarStateCookieName}=${this.isOpen ? NavbarStateCookieOpenValue : NavbarStateCookieClosedValue}; path=/; max-age=31536000; ${domain}`;\n };\n\n private handleDetailsToggle = (e: ToggleEvent) => {\n const { newState } = e;\n const target = e.currentTarget as HTMLDetailsElement;\n\n if (newState === 'open') {\n if (!this.isOpen) {\n this.toggleSidebar();\n }\n\n this.closeAllDetails(target);\n }\n };\n\n private buildUrl = (path: string): string => {\n if (!this.clientKey) throw new Error('clientKey is required');\n\n const formattedPath = path.replace('$CLIENT_KEY', this.clientKey);\n if (!this.platformUrl) return formattedPath;\n\n return new URL(formattedPath, this.platformUrl).toString();\n };\n\n private onAnchorClick = (e: MouseEvent) => {\n if (this.navigate) {\n this.navigate(e);\n this.setActiveState();\n }\n };\n\n private handleClientChange = (e: Event) => {\n const combobox = e.target as EventTarget & { value?: string[] };\n const selectedClientKey = combobox.value?.[0];\n\n if (selectedClientKey && this.onClientChange) {\n this.onClientChange(selectedClientKey);\n }\n };\n\n render() {\n return html`\n <nav id=${this.id} class=\"${this.isOpen ? '' : 'sidebar-closed'}\">\n <div class=\"sidebar-header ${this.isOpen ? '' : 'sidebar-closed'}\">\n <div class=\"logo\">\n ${unsafeSVG(tripteaseLogo)}\n </div>\n <button id=\"navbar-toggle-btn\" class=\"nav-item nav-toggle-button\" @click=${this.toggleSidebar}>\n ${unsafeSVG(sidebarCollapsed)}\n <span class=\"tooltip nav-toggle-tooltip\">\n ${unsafeSVG(sidebarCollapsed)}\n <span>${this.isOpen ? html`Collapse sidebar` : html`Expand sidebar`}</span>\n </span>\n </button>\n </div>\n\n <div class=\"nav-items ${this.isOpen ? '' : 'sidebar-closed'}\">\n <a\n class=\"nav-item\"\n href=${this.buildUrl('/')}\n @click=${this.onAnchorClick}\n data-intercom-target=\"dashboard\"\n >${unsafeSVG(home)}<span>Dashboard</span></a\n >\n <a id=\"${Routes.CampaignManager}\" class=\"nav-item\" href=${this.campaignManagerUrl}\n @click=${this.onAnchorClick}\n data-intercom-target=\"campaigns\"\n >${unsafeSVG(campaigns)}<span>Campaigns</span></a\n >\n <a\n class=\"nav-item\"\n href=${this.buildUrl('/$CLIENT_KEY/channels')}\n @click=${this.onAnchorClick}\n data-intercom-target=\"channels\"\n >${unsafeSVG(channels)}<span>Channels</span></a\n >\n <details id=\"market-insights\" @toggle=${this.handleDetailsToggle} data-intercom-target=\"market-insights\">\n <summary>\n ${unsafeSVG(graph)}\n <span>Market Insights</span>\n <span class=\"icon chevron\"> ${unsafeSVG(chevronDown)}</span>\n </summary>\n <div class=\"dropdown-items\">\n <a\n class=\"sub-nav-item\"\n href=${this.buildUrl('/parity/$CLIENT_KEY')}\n @click=${this.onAnchorClick}\n data-intercom-target=\"parity-monitoring\"\n >Parity monitoring</a\n >\n <a\n class=\"sub-nav-item\"\n href=${this.buildUrl('/$CLIENT_KEY/guest-insights')}\n @click=${this.onAnchorClick}\n data-intercom-target=\"guest-insights\"\n >Guest insights</a\n >\n </div>\n </details>\n <details id=\"settings\" @toggle=${this.handleDetailsToggle} data-intercom-target=\"settings\">\n <summary>\n ${unsafeSVG(gear)}\n <span>Settings</span>\n <span class=\"icon chevron\"> ${unsafeSVG(chevronDown)}</span>\n </summary>\n <div class=\"dropdown-items\">\n <a\n class=\"sub-nav-item\"\n href=${this.buildUrl('/$CLIENT_KEY/guest-behavioural-data')}\n @click=${this.onAnchorClick}\n data-intercom-target=\"email-setup\"\n >Email setup</a\n >\n <a\n class=\"sub-nav-item\"\n href=${this.buildUrl('/$CLIENT_KEY/crm-config')}\n @click=${this.onAnchorClick}\n data-intercom-target=\"crm-connectivity\"\n >CRM connectivity</a\n >\n <a\n class=\"sub-nav-item\"\n href=${this.buildUrl('/$CLIENT_KEY/settings/guides')}\n @click=${this.onAnchorClick}\n data-intercom-target=\"group-settings\"\n >Group settings</a\n >\n <a\n class=\"sub-nav-item\"\n href=${this.buildUrl('/$CLIENT_KEY/settings/hotels')}\n @click=${this.onAnchorClick}\n data-intercom-target=\"property-settings\"\n >Property settings</a\n >\n </div>\n </details>\n <hr />\n <details id=\"account\" @toggle=${this.handleDetailsToggle} data-intercom-target=\"account\">\n <summary>\n ${unsafeSVG(user)}\n <span>Account</span>\n <span class=\"icon chevron\"> ${unsafeSVG(chevronDown)}</span>\n </summary>\n <div class=\"dropdown-items\">\n <a\n class=\"sub-nav-item\"\n href=${this.buildUrl('/account')}\n @click=${this.onAnchorClick}\n data-intercom-target=\"user-settings\"\n >User settings</a\n >\n <!-- TODO: Change to /$CLIENT_KEY/account/team when the change in Tetris is ready -->\n <a\n class=\"sub-nav-item\"\n href=${this.buildUrl('/account/team/$CLIENT_KEY')}\n @click=${this.onAnchorClick}\n data-intercom-target=\"team-permissions\"\n >Team and permissions</a\n >\n </div>\n </details>\n <details id=\"billing-routes\" @toggle=${this.handleDetailsToggle} data-intercom-target=\"billing\">\n <summary>\n ${unsafeSVG(wallet)}\n <span>Billing</span>\n <span class=\"icon chevron\"> ${unsafeSVG(chevronDown)}</span>\n </summary>\n <div>\n <!-- TODO: Change to /$CLIENT_KEY/account/billing-management when the change in Tetris is ready -->\n <a\n class=\"sub-nav-item\"\n href=${this.buildUrl('/account/billing-management/$CLIENT_KEY')}\n @click=${this.onAnchorClick}\n data-intercom-target=\"booking-reconciliation\"\n >Booking reconciliation</a\n >\n <!-- TODO: Change to /$CLIENT_KEY/subscriptions when the change in Tetris is ready -->\n <a\n class=\"sub-nav-item\"\n href=${this.buildUrl('/subscriptions/$CLIENT_KEY')}\n @click=${this.onAnchorClick}\n data-intercom-target=\"subscriptions\"\n >Subscriptions</a\n >\n </div>\n </details>\n </div>\n <div class=\"tertiary-nav ${this.isOpen ? '' : 'sidebar-closed'}\">\n <div id=\"external-links\" class=\"nav-items\">\n <a\n class=\"nav-item external-link\"\n href='https://triptease.canny.io/feature-requests'\n target=\"_blank\"\n rel=\"noreferrer\"\n >\n Feature requests\n ${unsafeSVG(external)}\n </a>\n <a\n class='nav-item external-link'\n href='https://triptease.canny.io/changelog'\n target=\"_blank\"\n rel=\"noreferrer\"\n >\n Product updates\n ${unsafeSVG(external)}\n </a>\n <a\n class='nav-item external-link'\n href='https://help.triptease.com/'\n target=\"_blank\"\n rel=\"noreferrer\"\n >\n Help center\n ${unsafeSVG(external)}\n </a>\n <hr />\n </div>\n <div class='nav-items'>\n <div id=\"client-selector\">\n ${\n this.clients.length > 1\n ? html`\n <tt-combobox\n .openUpward=${true}\n .value=${this.clientKey ? [this.clientKey] : []}\n @change=${this.handleClientChange}\n >\n ${this.clients.map(\n (client) => html`\n <option slot=\"option\" value=${client.clientKey}>${client.displayName}</option>\n `\n )}\n </tt-combobox>\n `\n : html`\n <div class=\"single-client-name\">\n ${this.clients.find((m) => m.clientKey === this.clientKey)?.displayName}\n </div>\n `\n }\n </div>\n <a\n id=\"logout-link\"\n class=\"nav-item\"\n href=${this.buildUrl('/logout')}\n @click=${this.onAnchorClick}\n data-intercom-target=\"logout\"\n >${unsafeSVG(logout)}<span>Logout</span></a>\n </div>\n </nav>\n `;\n }\n}\n"]}
@@ -0,0 +1,21 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getInitialNavbarState = void 0;
4
+ const Config_js_1 = require("./Config.js");
5
+ const getInitialNavbarState = (cookieString) => {
6
+ const cookies = cookieString || document.cookie;
7
+ if (!cookies) {
8
+ return undefined;
9
+ }
10
+ const stateCookie = cookies.split(';').find((c) => c.trim().startsWith(`${Config_js_1.Config.NavbarStateCookieName}`));
11
+ if (!stateCookie) {
12
+ return undefined;
13
+ }
14
+ const value = stateCookie.split('=')[1];
15
+ if (value !== Config_js_1.Config.NavbarStateCookieOpenValue && value !== Config_js_1.Config.NavbarStateCookieClosedValue) {
16
+ return undefined;
17
+ }
18
+ return value;
19
+ };
20
+ exports.getInitialNavbarState = getInitialNavbarState;
21
+ //# sourceMappingURL=getInitialNavbarState.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"getInitialNavbarState.js","sourceRoot":"","sources":["../../../src/getInitialNavbarState.ts"],"names":[],"mappings":";;;AAAA,2CAAqC;AAErC,MAAM,qBAAqB,GAAG,CAAC,YAAqB,EAAE,EAAE;IACtD,MAAM,OAAO,GAAG,YAAY,IAAI,QAAQ,CAAC,MAAM,CAAC;IAEhD,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,MAAM,WAAW,GAAG,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,UAAU,CAAC,GAAG,kBAAM,CAAC,qBAAqB,EAAE,CAAC,CAAC,CAAC;IAE3G,IAAI,CAAC,WAAW,EAAE,CAAC;QACjB,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,MAAM,KAAK,GAAG,WAAW,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IAExC,IAAI,KAAK,KAAK,kBAAM,CAAC,0BAA0B,IAAI,KAAK,KAAK,kBAAM,CAAC,4BAA4B,EAAE,CAAC;QACjG,OAAO,SAAS,CAAC;IACnB,CAAC;IAED,OAAO,KAAK,CAAC;AACf,CAAC,CAAC;AAEO,sDAAqB","sourcesContent":["import { Config } from './Config.js';\n\nconst getInitialNavbarState = (cookieString?: string) => {\n const cookies = cookieString || document.cookie;\n\n if (!cookies) {\n return undefined;\n }\n\n const stateCookie = cookies.split(';').find((c) => c.trim().startsWith(`${Config.NavbarStateCookieName}`));\n\n if (!stateCookie) {\n return undefined;\n }\n\n const value = stateCookie.split('=')[1];\n\n if (value !== Config.NavbarStateCookieOpenValue && value !== Config.NavbarStateCookieClosedValue) {\n return undefined;\n }\n\n return value;\n};\n\nexport { getInitialNavbarState };\n"]}
@@ -0,0 +1,12 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getInitialNavbarState = exports.Config = exports.Routes = exports.TtNavbar = void 0;
4
+ var TtNavbar_js_1 = require("./TtNavbar.js");
5
+ Object.defineProperty(exports, "TtNavbar", { enumerable: true, get: function () { return TtNavbar_js_1.TtNavbar; } });
6
+ var Routes_js_1 = require("./Routes.js");
7
+ Object.defineProperty(exports, "Routes", { enumerable: true, get: function () { return Routes_js_1.Routes; } });
8
+ var Config_js_1 = require("./Config.js");
9
+ Object.defineProperty(exports, "Config", { enumerable: true, get: function () { return Config_js_1.Config; } });
10
+ var getInitialNavbarState_js_1 = require("./getInitialNavbarState.js");
11
+ Object.defineProperty(exports, "getInitialNavbarState", { enumerable: true, get: function () { return getInitialNavbarState_js_1.getInitialNavbarState; } });
12
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/index.ts"],"names":[],"mappings":";;;AAAA,6CAAyC;AAAhC,uGAAA,QAAQ,OAAA;AACjB,yCAAqC;AAA5B,mGAAA,MAAM,OAAA;AACf,yCAAqC;AAA5B,mGAAA,MAAM,OAAA;AACf,uEAAmE;AAA1D,iIAAA,qBAAqB,OAAA","sourcesContent":["export { TtNavbar } from './TtNavbar.js';\nexport { Routes } from './Routes.js';\nexport { Config } from './Config.js';\nexport { getInitialNavbarState } from './getInitialNavbarState.js';\n"]}