@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.
- package/dist/src/TtNavbar.d.ts +1 -0
- package/dist/src/TtNavbar.js +9 -2
- package/dist/src/TtNavbar.js.map +1 -1
- package/dist/stories/{index.stories.d.ts → tt-navbar.stories.d.ts} +4 -0
- package/dist/stories/{index.stories.js → tt-navbar.stories.js} +10 -4
- package/dist/stories/tt-navbar.stories.js.map +1 -0
- package/dist/test/tt-navbar.test.js +33 -10
- package/dist/test/tt-navbar.test.js.map +1 -1
- package/dist/web/Routes.js +1 -1
- package/dist/web/TtNavbar.js +10 -3
- package/dist/web/TtNavbar.js.map +2 -2
- package/dist/web/index.js +10 -3
- package/dist/web/index.js.map +2 -2
- package/dist/web/styles.js +1 -1
- package/dist/web/triptease-logo.js +1 -1
- package/dist/web/tt-navbar.js +10 -3
- package/dist/web/tt-navbar.js.map +2 -2
- package/dist/web/urlMappings.js +1 -1
- package/package.json +1 -1
- package/src/TtNavbar.ts +11 -2
- package/stories/{index.stories.ts → tt-navbar.stories.ts} +12 -3
- package/test/tt-navbar.test.ts +58 -31
- package/dist/stories/index.stories.js.map +0 -1
package/dist/web/urlMappings.js
CHANGED
package/package.json
CHANGED
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
|
-
|
|
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({});
|
package/test/tt-navbar.test.ts
CHANGED
|
@@ -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
|
-
|
|
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"]}
|