Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/assets/main.css
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@
}

@utility text-tertiary-neutral {
@apply text-gray-600 dark:text-gray-300;
@apply text-gray-600 dark:text-gray-400;
}

@utility text-enabled {
Expand Down
145 changes: 90 additions & 55 deletions src/components/standalone/dns_dhcp/DhcpCard.vue
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
<!--
Copyright (C) 2026 Nethesis S.r.l.
SPDX-License-Identifier: GPL-3.0-or-later
-->

<script lang="ts" setup>
import type { DhcpInterface } from '@/components/standalone/dns_dhcp/DhcpManager.vue'
import {
Expand All @@ -8,14 +13,8 @@ import {
} from '@/lib/standalone/network.ts'
import { FontAwesomeIcon } from '@fortawesome/vue-fontawesome'
import { computed } from 'vue'
import {
faCheck,
faCircleCheck,
faCircleXmark,
faPenToSquare,
faXmark
} from '@fortawesome/free-solid-svg-icons'
import { NeBadge, NeButton, NeLink, NeTooltip } from '@nethesis/vue-components'
import { faCircleCheck, faCircleXmark, faPenToSquare } from '@fortawesome/free-solid-svg-icons'
import { NeButton, NeLink, NeTooltip } from '@nethesis/vue-components'
import { useI18n } from 'vue-i18n'
import { useFirewallStore } from '@/stores/standalone/firewall.ts'

Expand All @@ -35,11 +34,11 @@ const borderColor = computed((): string => {
return getZoneBorderColorClasses(zoneName)
})

const range = computed((): string | undefined => {
if (dhcpInterface.first != undefined && dhcpInterface.last != undefined) {
return `${dhcpInterface.first} - ${dhcpInterface.last}`
const allRanges = computed((): Array<string> => {
if (dhcpInterface.ranges && dhcpInterface.ranges.length > 0) {
return dhcpInterface.ranges.map(({ first, last }) => `${first} - ${last}`)
}
return undefined
return []
})

const dhcpOptions = computed(() => {
Expand Down Expand Up @@ -75,9 +74,14 @@ const visibleOptions = computed(() => {
class="h-4 w-4"
/>
</div>
<span class="text-base leading-6 font-medium">
{{ interfaceName }}<br />{{ dhcpInterface.device }}
</span>
<div class="flex flex-col">
<span class="text-base leading-6 font-medium text-primary-neutral">
{{ interfaceName }}
</span>
<span class="text-sm text-tertiary-neutral">
{{ dhcpInterface.device }}
</span>
</div>
</div>
<div>
<NeButton kind="tertiary" size="sm" @click="$emit('edit', dhcpInterface)">
Expand All @@ -88,10 +92,15 @@ const visibleOptions = computed(() => {
</NeButton>
</div>
</div>
<div class="space-y-2 text-tertiary-neutral">
<p class="flex items-center gap-3">
<span>{{ t('standalone.dns_dhcp.mac_binding') }}:</span>
<span class="space-x-1">

<!-- MAC binding section -->
<div class="space-y-2">
<p class="text-sm font-medium text-primary-neutral">
{{ t('standalone.dns_dhcp.mac_binding') }}
</p>
<div class="flex items-center justify-between text-sm text-tertiary-neutral">
<span>{{ t('common.status') }}</span>
<span class="flex items-center gap-1.5">
<template v-if="dhcpInterface.ns_binding != undefined && dhcpInterface.ns_binding == 0">
<FontAwesomeIcon :icon="faCircleXmark" class="text-offline" />
<span>{{ t('common.disabled') }}</span>
Expand All @@ -109,39 +118,61 @@ const visibleOptions = computed(() => {
</span>
</template>
</span>
</p>
<hr />
</div>
</div>
<div class="space-y-1 text-sm">
<p class="flex items-center">
{{ t('standalone.dns_dhcp.dhcp') }}
<NeBadge
v-if="dhcpInterface.active"
:icon="faCheck"
:text="t('common.enabled')"
class="ml-auto"
kind="success"
size="xs"
/>
<NeBadge
v-else
:icon="faXmark"
:text="t('common.disabled')"
class="ml-auto"
kind="secondary"
size="xs"
/>
</p>
<div v-if="dhcpInterface.active" class="space-y-1 font-normal">
<p v-if="range != undefined">{{ t('standalone.dns_dhcp.ip_range') }}: {{ range }}</p>
<p v-if="leaseTime != undefined">
{{ t('standalone.dns_dhcp.lease_time') }}: {{ leaseTime }}
</p>

<!-- DHCP section -->
<div class="mt-6 space-y-2">
<p class="text-sm font-medium text-primary-neutral">{{ t('standalone.dns_dhcp.dhcp') }}</p>

<!-- status -->
<div class="flex items-center justify-between text-sm text-tertiary-neutral">
<span>{{ t('common.status') }}</span>
<span class="flex items-center gap-1.5">
<FontAwesomeIcon
:icon="dhcpInterface.active ? faCircleCheck : faCircleXmark"
:class="dhcpInterface.active ? 'text-online' : 'text-offline'"
/>
<span>{{ dhcpInterface.active ? t('common.enabled') : t('common.disabled') }}</span>
</span>
</div>

<template v-if="dhcpInterface.active">
<hr />
<!-- IP ranges -->
<div
v-if="allRanges.length > 0"
class="flex justify-between gap-4 text-sm text-tertiary-neutral"
>
<span class="shrink-0">
{{ t('standalone.dns_dhcp.ip_range', allRanges.length) }}
</span>
<div class="flex flex-col items-end gap-0.5">
<span v-for="(range, index) in allRanges" :key="index">{{ range }}</span>
</div>
</div>
<hr />
<!-- lease time -->
<div
v-if="leaseTime != undefined"
class="flex items-center justify-between text-sm text-tertiary-neutral"
>
<span>
{{ t('standalone.dns_dhcp.lease_time') }}
</span>
<span>{{ leaseTime }}</span>
</div>

<!-- DHCP options -->
<template v-if="visibleOptions.length > 3">
<p v-for="dhcpOption in visibleOptions.slice(0, 2)" :key="dhcpOption.key">
{{ dhcpOption.key }}: {{ dhcpOption.value }}
</p>
<p v-if="visibleOptions.length > 2">
<template v-for="dhcpOption in visibleOptions.slice(0, 2)" :key="dhcpOption.key">
<hr />
<div class="flex items-center justify-between text-sm text-tertiary-neutral">
<span>{{ dhcpOption.key }}</span>
<span>{{ dhcpOption.value }}</span>
</div>
</template>
<div v-if="visibleOptions.length > 2" class="flex justify-end">
<NeTooltip>
<template #trigger>
<NeLink>
Expand All @@ -154,14 +185,18 @@ const visibleOptions = computed(() => {
</p>
</template>
</NeTooltip>
</p>
</div>
</template>
<template v-else>
<p v-for="dhcpOption in visibleOptions" :key="dhcpOption.key">
{{ dhcpOption.key }}: {{ dhcpOption.value }}
</p>
<template v-for="dhcpOption in visibleOptions" :key="dhcpOption.key">
<hr />
<div class="flex items-center justify-between text-sm text-tertiary-neutral">
<span>{{ dhcpOption.key }}</span>
<span>{{ dhcpOption.value }}</span>
</div>
</template>
</template>
</div>
</template>
</div>
</div>
</template>
10 changes: 5 additions & 5 deletions src/components/standalone/dns_dhcp/DhcpManager.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<!--
Copyright (C) 2024 Nethesis S.r.l.
Copyright (C) 2026 Nethesis S.r.l.
SPDX-License-Identifier: GPL-3.0-or-later
-->

Expand All @@ -24,13 +24,13 @@ type BindingType = 0 | 1 | 2

export type DhcpInterface = {
device: string
start: string
end: string
active: boolean
options: Record<string, string>
zone: string
first?: string
last?: string
ranges: Array<{
first: string
last: string
}>
ns_binding?: BindingType
}

Expand Down
Loading
Loading