Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: routes page #59

Merged
merged 3 commits into from
Oct 12, 2023
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
8 changes: 4 additions & 4 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
"@headlessui/vue": "^1.7.13",
"@nethesis/nethesis-light-svg-icons": "github:nethesis/Font-Awesome#ns-light",
"@nethesis/nethesis-solid-svg-icons": "github:nethesis/Font-Awesome#ns-solid",
"@nethserver/vue-tailwind-lib": "^0.0.77",
"@nethserver/vue-tailwind-lib": "^0.0.79",
"@types/lodash": "^4.14.195",
"axios": "^1.4.0",
"chart.js": "^4.4.0",
Expand Down
9 changes: 5 additions & 4 deletions public/i18n/en/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -57,11 +57,11 @@
"cannot_retrieve_wan_traffic": "Cannot retrieve WAN traffic",
"register_unit_error": "Cannot register unit",
"cancel_registration_error": "Cannot cancel registration",
"cannot_load_routes": "Cannot retrive routes",
"cannot_load_routes": "Cannot retrieve routes",
"cannot_create_route": "Cannot create route",
"cannot_edit_route": "Cannot edit route",
"cannot_retrive_interfaces": "Cannot retrieve interfaces",
"cannot_retrive_route_types": "Cannot retrieve route types",
"cannot_retrieve_interfaces": "Cannot retrieve interfaces",
"cannot_retrieve_route_types": "Cannot retrieve route types",
"invalid_metric": "Enter an integer number greater than or equal to 0",
"cannot_update_status_route": "Cannot update route status",
"cannot_delete_port_forward": "Cannot delete port forward",
Expand Down Expand Up @@ -480,7 +480,8 @@
"route_type": "Route type",
"route_choose_type": "Select route type",
"route_mtu": "MTU",
"route_onlink": "On-link\nWhen enabled, gateway is on-link even if the gateway does not match any interface prefix"
"route_onlink": "On-link",
"route_onlink_description": "When enabled, gateway is on-link even if the gateway does not match any interface prefix"
},
"users_and_objects": {
"title": "Users & objects"
Expand Down
59 changes: 35 additions & 24 deletions src/components/standalone/routes/CreateOrEditRouteDrawer.vue
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ watch(
if (selectedRoute.item.interface) form.value.routeInterface = selectedRoute.item.interface
if (selectedRoute.item.type) form.value.routeType = selectedRoute.item.type
if (selectedRoute.item.mtu) form.value.mtu = selectedRoute.item.mtu
if (selectedRoute.item.onlink) form.value.onlink = selectedRoute.item.mtu === '0'
if (selectedRoute.item.onlink) form.value.onlink = selectedRoute.item.onlink === '1'
} else form.value = { ...originalForm }
} else form.value = { ...originalForm }
}
Expand Down Expand Up @@ -163,7 +163,7 @@ async function getFirewallData() {
error = ref({ ...objError })
errorLoadingData = ref({ ...objError })

// Retrive list interfaces && route types
// retrieve list interfaces && route types
try {
let getInterfaces = await ubusCall('ns.routes', 'list-interfaces', {})
if (
Expand All @@ -172,7 +172,10 @@ async function getFirewallData() {
getInterfaces.data.interfaces &&
getInterfaces.data.interfaces.length
) {
routeInterfaces.value = getInterfaces.data.interfaces.map((item: RouteInterface) => ({
let responseData = getInterfaces.data.interfaces
responseData = responseData.filter((item: string) => item !== 'loopback')

routeInterfaces.value = responseData.map((item: RouteInterface) => ({
id: item,
label: item
}))
Expand All @@ -184,7 +187,7 @@ async function getFirewallData() {
}
}
} catch (exception: any) {
errorLoadingData.value.notificationTitle = t('error.cannot_retrive_interfaces')
errorLoadingData.value.notificationTitle = t('error.cannot_retrieve_interfaces')
errorLoadingData.value.notificationDescription = t(getAxiosErrorMessage(exception))
} finally {
try {
Expand All @@ -200,7 +203,7 @@ async function getFirewallData() {
label: item
}))
} catch (exception: any) {
errorLoadingData.value.notificationTitle = t('error.cannot_retrive_route_types')
errorLoadingData.value.notificationTitle = t('error.cannot_retrieve_route_types')
errorLoadingData.value.notificationDescription = t(getAxiosErrorMessage(exception))
} finally {
loading.value = false
Expand Down Expand Up @@ -331,7 +334,6 @@ function validate(): boolean {
function createRoute() {
if (validate()) {
saving.value = true
let isValidCreate = true

// create payload
let payload = {
Expand All @@ -355,28 +357,30 @@ function createRoute() {

ubusCall('ns.routes', methodUpdateStatus, {
id: response.data.id
}).catch((exception: AxiosError) => {
error.value.notificationTitle = t('error.cannot_update_status_route')
error.value.notificationDescription = t(getAxiosErrorMessage(exception))
isValidCreate = false
})
.then(() => {
emit('routeCreated')
})
.catch((exception: AxiosError) => {
error.value.notificationTitle = t('error.cannot_update_status_route')
error.value.notificationDescription = t(getAxiosErrorMessage(exception))
})
.finally(() => {
saving.value = false
})
}
})
.catch((exception: AxiosError) => {
error.value.notificationTitle = t('error.cannot_create_route')
error.value.notificationDescription = t(getAxiosErrorMessage(exception))
isValidCreate = false
saving.value = false
})
.finally(() => (saving.value = false))

if (isValidCreate) emit('routeCreated')
}
}

function editRoute() {
if (validate()) {
saving.value = true
let isValidUpdate = true

// create payload
let payload = {
Expand All @@ -401,21 +405,24 @@ function editRoute() {

ubusCall('ns.routes', methodUpdateStatus, {
id: response.data.id
}).catch((exception: AxiosError) => {
error.value.notificationTitle = t('error.cannot_update_status_route')
error.value.notificationDescription = t(getAxiosErrorMessage(exception))
isValidUpdate = false
})
.then(() => {
emit('routeEdited')
})
.catch((exception: AxiosError) => {
error.value.notificationTitle = t('error.cannot_update_status_route')
error.value.notificationDescription = t(getAxiosErrorMessage(exception))
})
.finally(() => {
saving.value = false
})
}
})
.catch((exception: AxiosError) => {
error.value.notificationTitle = t('error.cannot_edit_route')
error.value.notificationDescription = t(getAxiosErrorMessage(exception))
isValidUpdate = false
saving.value = false
})
.finally(() => (saving.value = false))

if (isValidUpdate) emit('routeEdited')
}
}
</script>
Expand Down Expand Up @@ -514,6 +521,10 @@ function editRoute() {
ref="mtuRef"
/>
<NeToggle v-model="form.onlink" :label="t('standalone.routes.route_onlink')" />
<NeInlineNotification
kind="info"
:description="t('standalone.routes.route_onlink_description')"
/>
</div>
</Transition>
<NeInlineNotification
Expand Down Expand Up @@ -543,7 +554,7 @@ function editRoute() {
:loading="saving"
@click="editRoute()"
>
{{ t('common.edit') }}
{{ t('common.save') }}
</NeButton>
</div>
</div>
Expand Down
49 changes: 30 additions & 19 deletions src/components/standalone/routes/RoutesContent.vue
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,10 @@ import {
NeDropdown,
NeTitle,
NeModal,
NeEmptyState,
NeInlineNotification
} from '@nethserver/vue-tailwind-lib'
import NeTable from '@/components/standalone/NeTable.vue'
import HorizontalCard from '@/components/standalone/HorizontalCard.vue'
import { FontAwesomeIcon } from '@fortawesome/vue-fontawesome'
import {
faCirclePlus,
Expand Down Expand Up @@ -68,6 +68,7 @@ onMounted(async () => {
* get all routes
*/
async function loadRoutes() {
loading.value = true
try {
const res = await ubusCall('ns.routes', 'list-routes', {
protocol: props.protocol
Expand All @@ -84,9 +85,10 @@ async function loadRoutes() {

routes.value = items
} catch (err: any) {
console.error(err)
error.value.notificationTitle = t('error.cannot_load_routes')
error.value.notificationDescription = t(getAxiosErrorMessage(err))
} finally {
loading.value = false
}
}

Expand All @@ -101,7 +103,6 @@ async function loadMainTable() {

if (res.data) table.value = res.data.table
} catch (err: any) {
console.error(err)
error.value.notificationTitle = t('error.cannot_load_routes')
error.value.notificationDescription = t(getAxiosErrorMessage(err))
}
Expand All @@ -116,8 +117,9 @@ function routeCreatedEditedHandler() {
}

function reloadConfig() {
loadRoutes()
uciPendingChangesStore.getChanges()
loadRoutes()
loadMainTable()
}

function openCreateRoute() {
Expand Down Expand Up @@ -159,15 +161,18 @@ function scrollToMainTable() {

<template>
<NeSkeleton v-if="loading" :lines="15" />
<HorizontalCard v-if="!loading && !routes.length" class="space-y-4 text-center">
<p>{{ t('standalone.routes.no_route_found') }}</p>
<NeButton :kind="'primary'" @click="openCreateRoute()">
<NeEmptyState
v-if="!loading && !error.notificationTitle && !routes.length"
:title="t('standalone.routes.no_route_found')"
:icon="['fas', 'circle-info']"
>
<NeButton kind="primary" size="lg" @click="openCreateRoute()">
<template #prefix>
<FontAwesomeIcon :icon="faCirclePlus" />
<FontAwesomeIcon :icon="['fas', 'circle-plus']" aria-hidden="true" />
</template>
{{ t('standalone.routes.create_route') }}
</NeButton>
</HorizontalCard>
{{ t('standalone.routes.create_route') }}</NeButton
>
</NeEmptyState>
<div v-if="!loading && routes.length">
<div class="space-y-8">
<div class="flex">
Expand Down Expand Up @@ -199,7 +204,13 @@ function scrollToMainTable() {
/>
<div v-if="!loading && routes.length">
<div class="my-4">
<NeButton kind="tertiary" size="sm" class="-ml-2" @click="scrollToMainTable()">
<NeButton
v-if="routes && routes.length && routes.length > 10"
kind="tertiary"
size="sm"
class="-ml-2"
@click="scrollToMainTable()"
>
{{ t('standalone.routes.main_table') }}
</NeButton>
</div>
Expand Down Expand Up @@ -242,12 +253,12 @@ function scrollToMainTable() {
<template #tbody>
<tbody>
<template v-for="item in routes" :key="item.id">
<tr :class="{ 'opacity-30': item.disabled !== '0' }">
<td>
<tr>
<td :class="{ 'opacity-30': item.disabled !== '0' }">
<span v-if="item.ns_description">{{ item.ns_description }}</span>
<span v-else>-</span>
</td>
<td>
<td :class="{ 'opacity-30': item.disabled !== '0' }">
<span>
<FontAwesomeIcon v-if="!item.interface" :icon="faEmptySet" />
<FontAwesomeIcon
Expand All @@ -268,16 +279,16 @@ function scrollToMainTable() {
}}
</span>
</td>
<td>
<td :class="{ 'opacity-30': item.disabled !== '0' }">
{{ item.target }}
</td>
<td>
<td :class="{ 'opacity-30': item.disabled !== '0' }">
{{ item.gateway }}
</td>
<td>
<td :class="{ 'opacity-30': item.disabled !== '0' }">
{{ item.metric }}
</td>
<td>
<td :class="{ 'opacity-30': item.disabled !== '0' }">
<span v-if="item.disabled === '0'">
<FontAwesomeIcon :icon="faCircleCheck" />
{{ t('standalone.routes.route_status_enabled') }}
Expand Down