@triptease/tt-navbar 0.0.23 → 0.0.25

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.
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @triptease/tt-navbar v0.0.23
2
+ * @triptease/tt-navbar v0.0.25
3
3
  */
4
4
 
5
5
  // src/urlMappings.ts
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.23",
6
+ "version": "0.0.25",
7
7
  "type": "module",
8
8
  "main": "dist/src/index.js",
9
9
  "module": "dist/src/index.js",
package/src/TtNavbar.ts CHANGED
@@ -178,6 +178,15 @@ export class TtNavbar extends LitElement {
178
178
  }
179
179
  };
180
180
 
181
+ private handleClientChange = (e: Event) => {
182
+ const combobox = e.target as any;
183
+ const selectedClientKey = combobox.value?.[0];
184
+
185
+ if (selectedClientKey && this.onClientChange) {
186
+ this.onClientChange(selectedClientKey);
187
+ }
188
+ };
189
+
181
190
  render() {
182
191
  return html`
183
192
  <nav id=${this.id} class="${this.sidebarOpen ? '' : 'sidebar-closed'}">
@@ -221,7 +230,7 @@ export class TtNavbar extends LitElement {
221
230
  class="sub-nav-item"
222
231
  href=${this.buildUrl('/parity/$CLIENT_KEY')}
223
232
  @click=${this.onAnchorClick}
224
- >Parity</a
233
+ >Parity monitoring</a
225
234
  >
226
235
  <a
227
236
  class="sub-nav-item"
@@ -345,7 +354,7 @@ export class TtNavbar extends LitElement {
345
354
  <tt-combobox
346
355
  .openUpward=${true}
347
356
  .value=${this.clientKey ? [this.clientKey] : []}
348
- .onChange=${this.onClientChange}
357
+ @change=${this.handleClientChange}
349
358
  >
350
359
  ${this.clients.map((client) => html`
351
360
  <option slot="option" value=${client.clientKey}>
@@ -7,7 +7,8 @@ const meta = {
7
7
  argTypes: {
8
8
  clientKey: { control: 'text' },
9
9
  clients: { control: 'object' },
10
- campaignManagerUrl: { control: 'text' }
10
+ campaignManagerUrl: { control: 'text' },
11
+ onClientChange: { action: 'clientChanged' }
11
12
  }
12
13
  };
13
14
 
@@ -29,30 +30,38 @@ interface ArgTypes {
29
30
  clientKey?: string;
30
31
  clients?: Client[];
31
32
  campaignManagerUrl?: string;
33
+ onClientChange: (clientKey: string) => void;
32
34
  }
33
35
 
34
36
  const Template: Story<ArgTypes> = ({
35
37
  clientKey = 'zxd47KQGAP',
36
38
  clients = [],
37
- campaignManagerUrl = 'https://app.campaign-manager.triptease.io'
39
+ campaignManagerUrl = 'https://app.campaign-manager.triptease.io',
40
+ onClientChange
38
41
  }: ArgTypes) => html`
39
42
  <div>
40
43
  <tt-navbar
41
44
  client-key=${clientKey}
42
45
  campaign-manager-url=${campaignManagerUrl}
43
46
  clients=${JSON.stringify(clients)}
47
+ .onClientChange=${onClientChange}
44
48
  >
45
49
  </tt-navbar>
46
50
  </div>
47
51
  `;
48
52
 
53
+ const clientChangeHandler = (clientKey: string) => {
54
+ console.log('Client changed to:', clientKey);
55
+ }
56
+
49
57
  export const MultipleClients = Template.bind({});
50
58
  MultipleClients.args = {
51
59
  clientKey: 'zxd47KQGAP',
52
60
  clients: [
53
61
  { clientKey: 'zxd47KQGAP', displayName: 'Demo Client' },
54
62
  { clientKey: 'a1b2c3d4e5', displayName: 'Another Client' }
55
- ]
63
+ ],
64
+ onClientChange: clientChangeHandler
56
65
  };
57
66
 
58
67
  export const SingleClient = Template.bind({});
@@ -1,11 +1,5 @@
1
1
  import '../src/tt-navbar.js';
2
- import {
3
- elementUpdated,
4
- expect,
5
- fixture,
6
- nextFrame,
7
- waitUntil,
8
- } from '@open-wc/testing';
2
+ import { elementUpdated, expect, fixture, nextFrame, waitUntil } from '@open-wc/testing';
9
3
  import { TtNavbar } from '../src/index.js';
10
4
  import { Routes } from '../src/Routes.js';
11
5
 
@@ -20,10 +14,20 @@ const getLinkByHref = (links: NodeListOf<HTMLAnchorElement>, href: string) => {
20
14
  return undefined;
21
15
  };
22
16
 
17
+ const selectComboboxOption = async (combobox: Element, value: string) => {
18
+ const input = combobox.shadowRoot!.querySelector('[role="combobox"]') as HTMLInputElement;
19
+ input.click();
20
+
21
+ await elementUpdated(combobox);
22
+
23
+ const option = combobox.shadowRoot!.querySelector(`[role="option"][data-value="${value}"]`) as HTMLLIElement;
24
+ option.click();
25
+ };
26
+
23
27
  const isVisuallyHidden = (element: Element) => {
24
28
  const style = getComputedStyle(element);
25
29
 
26
- const result =
30
+ return Boolean(
27
31
  style.position === 'absolute' &&
28
32
  style.width === '1px' &&
29
33
  style.height === '1px' &&
@@ -33,9 +37,8 @@ const isVisuallyHidden = (element: Element) => {
33
37
  style.overflow === 'hidden' &&
34
38
  style.clip === 'rect(0px, 0px, 0px, 0px)' &&
35
39
  style.clipPath === 'inset(50%)' &&
36
- style.whiteSpace === 'nowrap';
37
-
38
- return result;
40
+ style.whiteSpace === 'nowrap'
41
+ );
39
42
  };
40
43
 
41
44
  const CLIENT_KEY = 'zxd47KQGAP';
@@ -50,7 +53,7 @@ describe('TtNavbar', () => {
50
53
  });
51
54
  it('should render with the default links', async () => {
52
55
  const navbar = await fixture<TtNavbar>(
53
- `<tt-navbar client-key=${CLIENT_KEY}></tt-navbar>`,
56
+ `<tt-navbar client-key=${CLIENT_KEY}></tt-navbar>`
54
57
  );
55
58
  const links = navbar.shadowRoot?.querySelectorAll('a');
56
59
 
@@ -77,7 +80,7 @@ describe('TtNavbar', () => {
77
80
  it('should render platform URLs against the base URL when it is defined', async () => {
78
81
  const platformUrl = 'https://app.triptease.io';
79
82
  const navbar = await fixture<TtNavbar>(
80
- `<tt-navbar client-key=${CLIENT_KEY} platform-url="${platformUrl}"></tt-navbar>`,
83
+ `<tt-navbar client-key=${CLIENT_KEY} platform-url="${platformUrl}"></tt-navbar>`
81
84
  );
82
85
  const links = navbar.shadowRoot?.querySelectorAll('a');
83
86
 
@@ -98,7 +101,7 @@ describe('TtNavbar', () => {
98
101
  };
99
102
 
100
103
  const navbar = await fixture<TtNavbar>(
101
- `<tt-navbar client-key=${CLIENT_KEY}></tt-navbar>`,
104
+ `<tt-navbar client-key=${CLIENT_KEY}></tt-navbar>`
102
105
  );
103
106
  navbar.navigate = onNavigate;
104
107
  await navbar.updateComplete;
@@ -108,17 +111,17 @@ describe('TtNavbar', () => {
108
111
 
109
112
  await waitUntil(
110
113
  () => expect(navigateEventCount).to.equal(13),
111
- 'navigate event did not fire',
114
+ 'navigate event did not fire'
112
115
  );
113
116
  });
114
117
 
115
118
  it('should render a combobox when multiple clients are provided', async () => {
116
119
  const navbar = await fixture<TtNavbar>(
117
- `<tt-navbar client-key=${CLIENT_KEY}></tt-navbar>`,
120
+ `<tt-navbar client-key=${CLIENT_KEY}></tt-navbar>`
118
121
  );
119
122
  navbar.clients = [
120
123
  { clientKey: CLIENT_KEY, displayName: 'Client One' },
121
- { clientKey: 'abc123', displayName: 'Client Two' },
124
+ { clientKey: 'abc123', displayName: 'Client Two' }
122
125
  ];
123
126
  await navbar.updateComplete;
124
127
 
@@ -132,10 +135,10 @@ describe('TtNavbar', () => {
132
135
 
133
136
  it('should render the client name when only one client is provided', async () => {
134
137
  const navbar = await fixture<TtNavbar>(
135
- `<tt-navbar client-key=${CLIENT_KEY}></tt-navbar>`,
138
+ `<tt-navbar client-key=${CLIENT_KEY}></tt-navbar>`
136
139
  );
137
140
  navbar.clients = [
138
- { clientKey: CLIENT_KEY, displayName: 'Single Client' },
141
+ { clientKey: CLIENT_KEY, displayName: 'Single Client' }
139
142
  ];
140
143
  await navbar.updateComplete;
141
144
 
@@ -149,7 +152,7 @@ describe('TtNavbar', () => {
149
152
 
150
153
  it('should render the logout link', async () => {
151
154
  const navbar = await fixture<TtNavbar>(
152
- `<tt-navbar client-key=${CLIENT_KEY}></tt-navbar>`,
155
+ `<tt-navbar client-key=${CLIENT_KEY}></tt-navbar>`
153
156
  );
154
157
 
155
158
  const links = navbar.shadowRoot?.querySelectorAll('a');
@@ -160,7 +163,7 @@ describe('TtNavbar', () => {
160
163
 
161
164
  it('should close other details when one is being opened', async () => {
162
165
  const navbar = await fixture<TtNavbar>(
163
- `<tt-navbar client-key=${CLIENT_KEY}></tt-navbar>`,
166
+ `<tt-navbar client-key=${CLIENT_KEY}></tt-navbar>`
164
167
  );
165
168
 
166
169
  const allDetails = navbar.shadowRoot!.querySelectorAll('summary');
@@ -186,11 +189,11 @@ describe('TtNavbar', () => {
186
189
 
187
190
  it('should collapse the navbar when toggle clicked', async () => {
188
191
  const navbar = await fixture<TtNavbar>(
189
- `<tt-navbar client-key=${CLIENT_KEY}></tt-navbar>`,
192
+ `<tt-navbar client-key=${CLIENT_KEY}></tt-navbar>`
190
193
  );
191
194
 
192
195
  const navbarToggleBtn = navbar.shadowRoot!.querySelector(
193
- '#navbar-toggle-btn',
196
+ '#navbar-toggle-btn'
194
197
  ) as HTMLButtonElement;
195
198
 
196
199
  navbarToggleBtn.click();
@@ -220,7 +223,7 @@ describe('TtNavbar', () => {
220
223
  for (const element of [
221
224
  ...rootLinksHiddenElements,
222
225
  ...summaryHiddenElements,
223
- logoutLink!,
226
+ logoutLink!
224
227
  ]) {
225
228
  expect(isVisuallyHidden(element)).to.be.true;
226
229
  }
@@ -230,16 +233,16 @@ describe('TtNavbar', () => {
230
233
  'market-insights',
231
234
  'settings',
232
235
  'account',
233
- 'billing-routes',
236
+ 'billing-routes'
234
237
  ];
235
238
  collapsibleIds.forEach(id => {
236
239
  it(`should open the nav bar when the ${id} collapsible is clicked`, async () => {
237
240
  const navbar = await fixture<TtNavbar>(
238
- `<tt-navbar client-key=${CLIENT_KEY}></tt-navbar>`,
241
+ `<tt-navbar client-key=${CLIENT_KEY}></tt-navbar>`
239
242
  );
240
243
 
241
244
  const navbarToggleBtn = navbar.shadowRoot!.querySelector(
242
- '#navbar-toggle-btn',
245
+ '#navbar-toggle-btn'
243
246
  ) as HTMLButtonElement;
244
247
 
245
248
  navbarToggleBtn.click();
@@ -256,7 +259,7 @@ describe('TtNavbar', () => {
256
259
  element!.click();
257
260
 
258
261
  await waitUntil(() => logo?.checkVisibility(), 'navbar should be open', {
259
- timeout: 500,
262
+ timeout: 500
260
263
  });
261
264
  });
262
265
  });
@@ -269,7 +272,7 @@ describe('TtNavbar', () => {
269
272
  [`/parity/${CLIENT_KEY}/foo`, 'Parity'],
270
273
  [`/meta/${CLIENT_KEY}/performance`, 'Channels'],
271
274
  [`/chat/insights/${CLIENT_KEY}`, 'Channels'],
272
- [`/${CLIENT_KEY}/email`, 'Channels'],
275
+ [`/${CLIENT_KEY}/email`, 'Channels']
273
276
  ];
274
277
 
275
278
  URLs.forEach(([route, text]) => {
@@ -278,7 +281,7 @@ describe('TtNavbar', () => {
278
281
  history.pushState({}, '', route); // 👈 mock URL
279
282
 
280
283
  const navbar = await fixture<TtNavbar>(
281
- `<tt-navbar client-key=${CLIENT_KEY}></tt-navbar>`,
284
+ `<tt-navbar client-key=${CLIENT_KEY}></tt-navbar>`
282
285
  );
283
286
 
284
287
  const anchor = navbar.shadowRoot!.querySelector('a[aria-current="page"]');
@@ -293,10 +296,34 @@ describe('TtNavbar', () => {
293
296
  const campaignManagerUrl = 'http://localhost:8000';
294
297
 
295
298
  const navbar = await fixture<TtNavbar>(
296
- `<tt-navbar client-key=${CLIENT_KEY} platform-url=${platformUrl} campaign-manager-url=${campaignManagerUrl} active-route="${Routes.CampaignManager}"></tt-navbar>`,
299
+ `<tt-navbar client-key=${CLIENT_KEY} platform-url=${platformUrl} campaign-manager-url=${campaignManagerUrl} active-route="${Routes.CampaignManager}"></tt-navbar>`
297
300
  );
298
301
  const anchor = navbar.shadowRoot!.querySelector('a[aria-current="page"]');
299
302
  expect(anchor).to.exist;
300
303
  expect(anchor!.textContent).to.include('Campaigns');
301
304
  });
305
+
306
+ it('should fire an event when the client is changed', async () => {
307
+ let selectedClientKey: string | undefined;
308
+ const onClientChange = (clientKey: string) => {
309
+ selectedClientKey = clientKey;
310
+ };
311
+
312
+ const navbar = await fixture<TtNavbar>(
313
+ `<tt-navbar client-key=${CLIENT_KEY}></tt-navbar>`
314
+ );
315
+ navbar.clients = [
316
+ { clientKey: CLIENT_KEY, displayName: 'Client One' },
317
+ { clientKey: 'abc123', displayName: 'Client Two' }
318
+ ];
319
+ navbar.onClientChange = onClientChange;
320
+ await navbar.updateComplete;
321
+
322
+ const combobox = navbar.shadowRoot?.querySelector('tt-combobox');
323
+ expect(combobox).to.exist;
324
+
325
+ await selectComboboxOption(combobox!, 'abc123');
326
+
327
+ expect(selectedClientKey).to.equal('abc123');
328
+ });
302
329
  });
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.stories.js","sourceRoot":"","sources":["../../stories/index.stories.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAkB,MAAM,KAAK,CAAC;AAC3C,OAAO,qBAAqB,CAAC;AAE7B,MAAM,IAAI,GAAG;IACX,KAAK,EAAE,UAAU;IACjB,SAAS,EAAE,WAAW;IACtB,QAAQ,EAAE;QACR,SAAS,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE;QAC9B,OAAO,EAAE,EAAE,OAAO,EAAE,QAAQ,EAAE;QAC9B,kBAAkB,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE;KACxC;CACF,CAAC;AAEF,eAAe,IAAI,CAAC;AAoBpB,MAAM,QAAQ,GAAoB,CAAC,EACE,SAAS,GAAG,YAAY,EACxB,OAAO,GAAG,EAAE,EACZ,kBAAkB,GAAG,2CAA2C,EACvD,EAAE,EAAE,CAAC,IAAI,CAAA;;;mBAGpC,SAAS;6BACC,kBAAkB;gBAC/B,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC;;;;CAItC,CAAC;AAEF,MAAM,CAAC,MAAM,eAAe,GAAG,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;AACjD,eAAe,CAAC,IAAI,GAAG;IACrB,SAAS,EAAE,YAAY;IACvB,OAAO,EAAE;QACP,EAAE,SAAS,EAAE,YAAY,EAAE,WAAW,EAAE,aAAa,EAAE;QACvD,EAAE,SAAS,EAAE,YAAY,EAAE,WAAW,EAAE,gBAAgB,EAAE;KAC3D;CACF,CAAC;AAEF,MAAM,CAAC,MAAM,YAAY,GAAG,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;AAC9C,YAAY,CAAC,IAAI,GAAG;IAClB,SAAS,EAAE,YAAY;IACvB,OAAO,EAAE;QACP,EAAE,SAAS,EAAE,YAAY,EAAE,WAAW,EAAE,aAAa,EAAE;KACxD;CACF,CAAC","sourcesContent":["import { html, TemplateResult } from 'lit';\nimport '../src/tt-navbar.js';\n\nconst meta = {\n title: 'TtNavbar',\n component: 'tt-navbar',\n argTypes: {\n clientKey: { control: 'text' },\n clients: { control: 'object' },\n campaignManagerUrl: { control: 'text' }\n }\n};\n\nexport default meta;\n\ninterface Story<T> {\n (args: T): TemplateResult;\n\n args?: Partial<T>;\n argTypes?: Record<string, unknown>;\n}\n\ninterface Client {\n clientKey: string;\n displayName: string;\n}\n\ninterface ArgTypes {\n clientKey?: string;\n clients?: Client[];\n campaignManagerUrl?: string;\n}\n\nconst Template: Story<ArgTypes> = ({\n clientKey = 'zxd47KQGAP',\n clients = [],\n campaignManagerUrl = 'https://app.campaign-manager.triptease.io'\n }: ArgTypes) => html`\n <div>\n <tt-navbar\n client-key=${clientKey}\n campaign-manager-url=${campaignManagerUrl}\n clients=${JSON.stringify(clients)}\n >\n </tt-navbar>\n </div>\n`;\n\nexport const MultipleClients = Template.bind({});\nMultipleClients.args = {\n clientKey: 'zxd47KQGAP',\n clients: [\n { clientKey: 'zxd47KQGAP', displayName: 'Demo Client' },\n { clientKey: 'a1b2c3d4e5', displayName: 'Another Client' }\n ]\n};\n\nexport const SingleClient = Template.bind({});\nSingleClient.args = {\n clientKey: 'zxd47KQGAP',\n clients: [\n { clientKey: 'zxd47KQGAP', displayName: 'Demo Client' }\n ]\n};\n"]}