@triptease/tt-navbar 0.0.19 → 0.0.21

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.
@@ -0,0 +1,18 @@
1
+ /**
2
+ * @triptease/tt-navbar v0.0.21
3
+ */
4
+
5
+ // src/urlMappings.ts
6
+ var urlMappings = {
7
+ "/paidsearch/$CLIENT_KEY/performance": "/channels",
8
+ "/meta/$CLIENT_KEY/performance": "/channels",
9
+ "/retargeting/$CLIENT_KEY/performance": "/channels",
10
+ "/messages/$CLIENT_KEY/messages": "/channels",
11
+ "/$CLIENT_KEY/email": "/channels",
12
+ "/pricematch/$CLIENT_KEY/performance": "/channels",
13
+ "/chat/insights/$CLIENT_KEY": "/channels"
14
+ };
15
+ export {
16
+ urlMappings
17
+ };
18
+ //# sourceMappingURL=urlMappings.js.map
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../../src/urlMappings.ts"],
4
+ "sourcesContent": ["type UrlMapping = Record<string, string>;\n\nconst urlMappings: UrlMapping = {\n '/paidsearch/$CLIENT_KEY/performance': '/channels',\n '/meta/$CLIENT_KEY/performance': '/channels',\n '/retargeting/$CLIENT_KEY/performance': '/channels',\n '/messages/$CLIENT_KEY/messages': '/channels',\n '/$CLIENT_KEY/email': '/channels',\n '/pricematch/$CLIENT_KEY/performance': '/channels',\n '/chat/insights/$CLIENT_KEY': '/channels',\n};\n\nexport { urlMappings };\n"],
5
+ "mappings": ";;;;;AAEA,IAAM,cAA0B;AAAA,EAC9B,uCAAuC;AAAA,EACvC,iCAAiC;AAAA,EACjC,wCAAwC;AAAA,EACxC,kCAAkC;AAAA,EAClC,sBAAsB;AAAA,EACtB,uCAAuC;AAAA,EACvC,8BAA8B;AAChC;",
6
+ "names": []
7
+ }
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "description": "Webcomponent tt-navbar following open-wc recommendations",
4
4
  "license": "MIT",
5
5
  "author": "tt-navbar",
6
- "version": "0.0.19",
6
+ "version": "0.0.21",
7
7
  "type": "module",
8
8
  "main": "dist/src/index.js",
9
9
  "module": "dist/src/index.js",
package/src/Routes.ts ADDED
@@ -0,0 +1,5 @@
1
+ const Routes = {
2
+ CampaignManager: 'CampaignManager',
3
+ };
4
+
5
+ export { Routes };
package/src/TtNavbar.ts CHANGED
@@ -16,6 +16,8 @@ import {
16
16
  } from '@triptease/icons';
17
17
  import { styles } from './styles.js';
18
18
  import { tripteaseLogo } from './triptease-logo.js';
19
+ import { urlMappings } from './urlMappings.js';
20
+ import { Routes } from './Routes.js';
19
21
 
20
22
  export class TtNavbar extends LitElement {
21
23
  static styles = styles;
@@ -23,12 +25,18 @@ export class TtNavbar extends LitElement {
23
25
  @property({ type: Function })
24
26
  navigate: ((e: MouseEvent) => void) | undefined;
25
27
 
26
- @property({ type: String, attribute: 'base-url' })
27
- baseUrl?: string;
28
+ @property({ type: String, attribute: 'campaign-manager-url' })
29
+ campaignManagerUrl: string = 'https://app.campaign-manager.triptease.io';
30
+
31
+ @property({ type: String, attribute: 'platform-url' })
32
+ platformUrl?: string;
28
33
 
29
34
  @property({ type: String, attribute: 'client-key' })
30
35
  clientKey?: string;
31
36
 
37
+ @property({ type: String, attribute: 'active-route' })
38
+ activeRoute?: keyof typeof Routes;
39
+
32
40
  @queryAll('details')
33
41
  protected allDetailsElements!: Array<HTMLDetailsElement>;
34
42
 
@@ -68,18 +76,36 @@ export class TtNavbar extends LitElement {
68
76
  let bestMatch: HTMLAnchorElement | undefined;
69
77
  let bestMatchLength = 0;
70
78
 
71
- for (const link of this.allNavLinks) {
72
- link.classList.remove('current-page');
73
- if (link.hasAttribute('aria-current')) {
74
- link.attributes.removeNamedItem('aria-current');
79
+ // Check special cases first, as everything will always match on / and return Dashboard
80
+ if (this.activeRoute === Routes.CampaignManager) {
81
+ const links = Object.values(this.allNavLinks);
82
+ bestMatch = links.find(link => link.id === Routes.CampaignManager);
83
+ }
84
+
85
+ if (!bestMatch && this.clientKey) {
86
+ const parsedPath = currentPath.replace(this.clientKey, '$CLIENT_KEY');
87
+ const mappedUrl = urlMappings[parsedPath];
88
+
89
+ if (mappedUrl) {
90
+ const links = Object.values(this.allNavLinks);
91
+ bestMatch = links.find(link => link.href.includes(mappedUrl));
75
92
  }
93
+ }
94
+
95
+ if (!bestMatch) {
96
+ for (const link of this.allNavLinks) {
97
+ link.classList.remove('current-page');
98
+ if (link.hasAttribute('aria-current')) {
99
+ link.attributes.removeNamedItem('aria-current');
100
+ }
76
101
 
77
- const linkPath = new URL(link.href).pathname;
102
+ const linkPath = new URL(link.href).pathname;
78
103
 
79
- if (currentPath.startsWith(linkPath)) {
80
- if (linkPath.length > bestMatchLength) {
81
- bestMatch = link;
82
- bestMatchLength = linkPath.length;
104
+ if (currentPath.startsWith(linkPath)) {
105
+ if (linkPath.length > bestMatchLength) {
106
+ bestMatch = link;
107
+ bestMatchLength = linkPath.length;
108
+ }
83
109
  }
84
110
  }
85
111
  }
@@ -87,6 +113,8 @@ export class TtNavbar extends LitElement {
87
113
  if (bestMatch) {
88
114
  bestMatch.classList.add('current-page');
89
115
  bestMatch.setAttribute('aria-current', 'page');
116
+ } else {
117
+ console.error(`No matching nav link found for path: ${currentPath}`);
90
118
  }
91
119
  };
92
120
 
@@ -122,9 +150,9 @@ export class TtNavbar extends LitElement {
122
150
  if (!this.clientKey) throw new Error('clientKey is required');
123
151
 
124
152
  const formattedPath = path.replace('$CLIENT_KEY', this.clientKey);
125
- if (!this.baseUrl) return formattedPath;
153
+ if (!this.platformUrl) return formattedPath;
126
154
 
127
- return new URL(formattedPath, this.baseUrl).toString();
155
+ return new URL(formattedPath, this.platformUrl).toString();
128
156
  };
129
157
 
130
158
  private onAnchorClick = (e: MouseEvent) => {
@@ -157,7 +185,7 @@ export class TtNavbar extends LitElement {
157
185
  @click=${this.onAnchorClick}
158
186
  >${unsafeSVG(home)}<span>Dashboard</span></a
159
187
  >
160
- <a class="nav-item" href="https://app.campaign-manager.triptease.io"
188
+ <a id="${Routes.CampaignManager}" class="nav-item" href=${this.campaignManagerUrl}
161
189
  >${unsafeSVG(campaigns)}<span>Campaigns</span></a
162
190
  >
163
191
  <a
package/src/index.ts CHANGED
@@ -1 +1,2 @@
1
1
  export { TtNavbar } from './TtNavbar.js';
2
+ export { Routes } from './Routes.js';
@@ -0,0 +1,13 @@
1
+ type UrlMapping = Record<string, string>;
2
+
3
+ const urlMappings: UrlMapping = {
4
+ '/paidsearch/$CLIENT_KEY/performance': '/channels',
5
+ '/meta/$CLIENT_KEY/performance': '/channels',
6
+ '/retargeting/$CLIENT_KEY/performance': '/channels',
7
+ '/messages/$CLIENT_KEY/messages': '/channels',
8
+ '/$CLIENT_KEY/email': '/channels',
9
+ '/pricematch/$CLIENT_KEY/performance': '/channels',
10
+ '/chat/insights/$CLIENT_KEY': '/channels',
11
+ };
12
+
13
+ export { urlMappings };
@@ -8,7 +8,10 @@ export default {
8
8
 
9
9
  const Template = () => html`
10
10
  <div>
11
- <tt-navbar client-key="zxd47KQGAP">
11
+ <tt-navbar
12
+ client-key="zxd47KQGAP"
13
+ campaign-manager-url="https://app.campaign-manager.triptease.io"
14
+ >
12
15
  <div slot="clientSelector">
13
16
  <p>My Cool Client Selector</p>
14
17
  </div>
@@ -7,6 +7,7 @@ import {
7
7
  waitUntil,
8
8
  } from '@open-wc/testing';
9
9
  import { TtNavbar } from '../src/index.js';
10
+ import { Routes } from '../src/Routes.js';
10
11
 
11
12
  // eslint-disable-next-line no-undef
12
13
  const getLinkByHref = (links: NodeListOf<HTMLAnchorElement>, href: string) => {
@@ -74,17 +75,17 @@ describe('TtNavbar', () => {
74
75
  });
75
76
 
76
77
  it('should render platform URLs against the base URL when it is defined', async () => {
77
- const baseUrl = 'https://app.triptease.io';
78
+ const platformUrl = 'https://app.triptease.io';
78
79
  const navbar = await fixture<TtNavbar>(
79
- `<tt-navbar client-key=${CLIENT_KEY} base-url="${baseUrl}"></tt-navbar>`,
80
+ `<tt-navbar client-key=${CLIENT_KEY} platform-url="${platformUrl}"></tt-navbar>`,
80
81
  );
81
82
  const links = navbar.shadowRoot?.querySelectorAll('a');
82
83
 
83
84
  if (links) {
84
- expect(getLinkByHref(links, `${baseUrl}/`)).to.exist;
85
+ expect(getLinkByHref(links, `${platformUrl}/`)).to.exist;
85
86
  expect(getLinkByHref(links, 'https://app.campaign-manager.triptease.io'))
86
87
  .to.exist; // This shouldn't change
87
- expect(getLinkByHref(links, `${baseUrl}/channels`)).to.exist;
88
+ expect(getLinkByHref(links, `${platformUrl}/channels`)).to.exist;
88
89
  }
89
90
  });
90
91
 
@@ -241,6 +242,9 @@ describe('TtNavbar', () => {
241
242
  [`/parity/${CLIENT_KEY}`, 'Parity'],
242
243
  [`/parity/${CLIENT_KEY}`, 'Parity'],
243
244
  [`/parity/${CLIENT_KEY}/foo`, 'Parity'],
245
+ [`/meta/${CLIENT_KEY}/performance`, 'Channels'],
246
+ [`/chat/insights/${CLIENT_KEY}`, 'Channels'],
247
+ [`/${CLIENT_KEY}/email`, 'Channels'],
244
248
  ];
245
249
 
246
250
  URLs.forEach(([route, text]) => {
@@ -258,4 +262,16 @@ describe('TtNavbar', () => {
258
262
  expect(anchor!.textContent).to.include(text);
259
263
  });
260
264
  });
265
+
266
+ it('should show the current page as campaign manager when on the given campaign manager url', async () => {
267
+ const platformUrl = 'https://app.triptease.io';
268
+ const campaignManagerUrl = 'http://localhost:8000';
269
+
270
+ const navbar = await fixture<TtNavbar>(
271
+ `<tt-navbar client-key=${CLIENT_KEY} platform-url=${platformUrl} campaign-manager-url=${campaignManagerUrl} active-route="${Routes.CampaignManager}"></tt-navbar>`,
272
+ );
273
+ const anchor = navbar.shadowRoot!.querySelector('a[aria-current="page"]');
274
+ expect(anchor).to.exist;
275
+ expect(anchor!.textContent).to.include('Campaigns');
276
+ });
261
277
  });