Skip to content

Commit 27a5833

Browse files
luizhf42otavio
authored andcommitted
feat(ui): add pending devices count badge to DevicesDropdown
1 parent 9ef3f03 commit 27a5833

File tree

4 files changed

+44
-10
lines changed

4 files changed

+44
-10
lines changed

ui/src/components/AppBar/DevicesDropdown.vue

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,22 @@
11
<template>
2-
<v-icon
3-
color="primary"
4-
aria-label="Open devices menu"
5-
icon="mdi-developer-board"
6-
data-test="devices-icon"
7-
@click="toggleDrawer"
8-
/>
2+
<v-badge
3+
:model-value="pendingDevicesCount > 0"
4+
:content="pendingDevicesCount"
5+
offset-y="-5"
6+
location="top right"
7+
color="success"
8+
size="x-small"
9+
data-test="device-dropdown-badge"
10+
:class="{ 'mr-1': pendingDevicesCount > 0 }"
11+
>
12+
<v-icon
13+
color="primary"
14+
aria-label="Open devices menu"
15+
icon="mdi-developer-board"
16+
data-test="devices-icon"
17+
@click="toggleDrawer"
18+
/>
19+
</v-badge>
920

1021
<Teleport to="body">
1122
<v-navigation-drawer
@@ -140,7 +151,7 @@
140151
class="overflow-y-auto border"
141152
>
142153
<v-list
143-
v-if="pendingDevicesList.length > 0"
154+
v-if="pendingDevicesCount > 0"
144155
density="compact"
145156
class="bg-v-theme-surface pa-0"
146157
>
@@ -327,6 +338,7 @@ const snackbar = useSnackbar();
327338
const isDrawerOpen = ref(false);
328339
const activeTab = ref<"pending" | "recent">("pending");
329340
const pendingDevicesList = ref<IDevice[]>([]);
341+
const pendingDevicesCount = computed(() => pendingDevicesList.value.length);
330342
const recentDevicesList = ref<IDevice[]>([]);
331343
const stats = computed(() => statsStore.stats);
332344
const offlineDevices = computed(

ui/tests/components/AppBar/DevicesDropdown.spec.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import useDevicesStore from "@/store/modules/devices";
1515
import { IDevice } from "@/interfaces/IDevice";
1616
import { IStats } from "@/interfaces/IStats";
1717
import useAuthStore from "@/store/modules/auth";
18+
import { nextTick } from "vue";
1819

1920
const Component = {
2021
template: "<v-layout><DevicesDropdown /></v-layout>",
@@ -284,6 +285,17 @@ describe("Device Management Dropdown", () => {
284285
expect(fetchDevicesSpy).toHaveBeenCalledWith({ status: "pending", perPage: 100 });
285286
});
286287

288+
it("Shows correct pending devices count in badge", async () => {
289+
const badge = wrapper.find('[data-test="device-dropdown-badge"]');
290+
drawer.vm.pendingDevicesList = mockPendingDevices;
291+
await nextTick();
292+
expect(badge.text()).toBe("2");
293+
294+
drawer.vm.pendingDevicesList = [];
295+
await nextTick();
296+
expect(badge.text()).toBe("0");
297+
});
298+
287299
it("Shows error snackbar when accept fails", async () => {
288300
mockDevicesApi
289301
.onPatch(`http://localhost:3000/api/devices/${mockPendingDevices[0].uid}/accept`)

ui/tests/components/AppBar/__snapshots__/AppBar.spec.ts.snap

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,12 @@ exports[`AppBar Component > Renders the component 1`] = `
4040
<!---->
4141
</button>
4242
<!--teleport start-->
43-
<!--teleport end--><i class="mdi-developer-board mdi v-icon notranslate v-theme--light v-icon--size-default text-primary v-icon--clickable" role="button" aria-hidden="false" tabindex="0" aria-label="Open devices menu" data-test="devices-icon"></i>
43+
<!--teleport end-->
44+
<div class="v-badge" size="x-small" data-test="device-dropdown-badge">
45+
<div class="v-badge__wrapper"><i class="mdi-developer-board mdi v-icon notranslate v-theme--light v-icon--size-default text-primary v-icon--clickable" role="button" aria-hidden="false" tabindex="0" aria-label="Open devices menu" data-test="devices-icon"></i>
46+
<transition-stub name="scale-rotate-transition" appear="false" persisted="false" css="true"><span class="v-badge__badge v-theme--light bg-success" style="bottom: calc(100% - 7px); left: calc(100% - 12px); display: none;" aria-atomic="true" aria-label="Badge" aria-live="polite" role="status">0</span></transition-stub>
47+
</div>
48+
</div>
4449
<!--teleport start-->
4550
<!--teleport end--><button type="button" class="v-btn v-btn--icon v-theme--light text-primary v-btn--density-default v-btn--variant-text" aria-haspopup="menu" aria-expanded="false" aria-controls="v-menu-v-14" aria-owns="v-menu-v-14" data-test="user-menu-btn"><span class="v-btn__overlay"></span><span class="v-btn__underlay"></span>
4651
<!----><span class="v-btn__content" data-no-activator=""><div data-v-09753bb1="" class="v-avatar v-theme--light bg-primary v-avatar--density-default v-avatar--variant-flat border" style="width: 1.5rem; height: 1.5rem;" email="[email protected]" data-test="user-icon"><div data-v-09753bb1="" class="v-responsive v-img v-img--booting" data-test="gravatar-image"><div class="v-responsive__sizer"></div><!----><transition-stub name="fade-transition" appear="false" persisted="false" css="true"><!----></transition-stub><!----><!----><!----><!----></div><!----><span class="v-avatar__underlay"></span>

ui/tests/layouts/__snapshots__/AppLayout.spec.ts.snap

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -312,7 +312,12 @@ exports[`App Layout Component > Renders the component 1`] = `
312312
<!---->
313313
</button>
314314
<!--teleport start-->
315-
<!--teleport end--><i class="mdi-developer-board mdi v-icon notranslate v-theme--light v-icon--size-default text-primary v-icon--clickable" role="button" aria-hidden="false" tabindex="0" aria-label="Open devices menu" data-test="devices-icon"></i>
315+
<!--teleport end-->
316+
<div class="v-badge" size="x-small" data-test="device-dropdown-badge">
317+
<div class="v-badge__wrapper"><i class="mdi-developer-board mdi v-icon notranslate v-theme--light v-icon--size-default text-primary v-icon--clickable" role="button" aria-hidden="false" tabindex="0" aria-label="Open devices menu" data-test="devices-icon"></i>
318+
<transition-stub name="scale-rotate-transition" appear="false" persisted="false" css="true"><span class="v-badge__badge v-theme--light bg-success" style="bottom: calc(100% - 7px); left: calc(100% - 12px); display: none;" aria-atomic="true" aria-label="Badge" aria-live="polite" role="status">0</span></transition-stub>
319+
</div>
320+
</div>
316321
<!--teleport start-->
317322
<!--teleport end--><button type="button" class="v-btn v-btn--icon v-theme--light text-primary v-btn--density-default v-btn--variant-text" aria-haspopup="menu" aria-expanded="false" aria-controls="v-menu-v-21" aria-owns="v-menu-v-21" data-test="user-menu-btn"><span class="v-btn__overlay"></span><span class="v-btn__underlay"></span>
318323
<!----><span class="v-btn__content" data-no-activator=""><div data-v-09753bb1="" class="v-avatar v-theme--light bg-primary v-avatar--density-default v-avatar--variant-flat border" style="width: 1.5rem; height: 1.5rem;" email="" data-test="user-icon"><i data-v-09753bb1="" class="mdi-account mdi v-icon notranslate v-theme--light v-icon--size-default text-surface" aria-hidden="true" data-test="gravatar-placeholder"></i><!----><span class="v-avatar__underlay"></span>

0 commit comments

Comments
 (0)